diff --git a/AUTHORS b/AUTHORS index 715650ec..681d467 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -1024,6 +1024,7 @@ Thomas Butter <tbutter@gmail.com> Thomas Conti <tomc@amazon.com> Thomas Nguyen <haitung.nguyen@avast.com> +Thomas Phillips <tphillips@snapchat.com> Thomas White <im.toms.inbox@gmail.com> Tiago Vignatti <tiago.vignatti@intel.com> Tibor Dusnoki <tibor.dusnoki.91@gmail.com>
diff --git a/DEPS b/DEPS index 0210978..dc4bc41 100644 --- a/DEPS +++ b/DEPS
@@ -201,7 +201,7 @@ # 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': '6e7e3279365378aaff6dda33a677477a053a5ffe', + 'v8_revision': '458ab69acb38af95d9d4eb5a7e0f692f3cfe81d0', # 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. @@ -209,11 +209,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '738092aeadaf2faad0fdc7373d43f8aff08bb276', + 'angle_revision': '8b76d37f9f9af22be8f1a31056b8a28992990662', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '259ce70939a8a6eaf3c3dcc88bf3eea903ab09c8', + 'swiftshader_revision': '060020166679a265a2bc8250f4d78a7a8c29de89', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -272,7 +272,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '5c2ea4d80c2bfc8b7a629067c51e6d506198ef94', + 'devtools_frontend_revision': 'ad797e9664801c0444fce13d09d2726ba39edeec', # 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. @@ -907,7 +907,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '484196b739168386485a281071fb3c7cd0cafa5f', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '5589652282f5255cdfb36e86ea098c781557c580', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -915,6 +915,10 @@ 'src/third_party/dom_distiller_js/dist': Var('chromium_git') + '/chromium/dom-distiller/dist.git' + '@' + 'f339eb9463714c3d31657c8ee1bd53d1c7e5c555', + 'src/third_party/eigen3/src': + Var('chromium_git') + '/external/gitlab.com/libeigen/eigen.git' + '@' + '2ce2f5198929caab4b41a6ad1b9c93f67d8b9a69', + + 'src/third_party/espresso': { 'packages': [ { @@ -926,6 +930,9 @@ 'dep_type': 'cipd', }, + 'src/third_party/farmhash/src': + Var('chromium_git') + '/external/github.com/google/farmhash.git' + '@' + '816a4ae622e964763ca0862d9dbd19324a1eaf45', + 'src/third_party/ffmpeg': Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '6d9096c9e3f7f5d4e6528104ed77987ec9327315', @@ -941,8 +948,14 @@ 'condition': 'checkout_linux', }, + 'src/third_party/fp16/src': + Var('chromium_git') + '/external/github.com/Maratyszcza/FP16.git' + '@' + 'febbb1c163726b5db24bed55cc9dc42529068997', + + 'src/third_party/gemmlowp/src': + Var('chromium_git') + '/external/github.com/google/gemmlowp.git' + '@' + 'fda83bdc38b118cc6b56753bd540caa49e570745', + 'src/third_party/grpc/src': { - 'url': Var('chromium_git') + '/external/github.com/grpc/grpc.git' + '@' + '74b981a6a3d9ba17f3acae1d72b9109325ef656d', + 'url': Var('chromium_git') + '/external/github.com/grpc/grpc.git' + '@' + '4ac9c6f755463a2321f84b0cb2d631e1828faedb', }, 'src/third_party/freetype/src': @@ -1221,6 +1234,9 @@ '19f3fad68da99277b2882939d3b2fa4c4b8d51d9' }, + 'src/third_party/neon_2_sse/src': + Var('chromium_git') + '/external/github.com/intel/ARM_NEON_2_x86_SSE.git' + '@' + '42b2bebacee25452e150095ef4480b3fa26e30f5', + 'src/third_party/netty-tcnative/src': { 'url': Var('chromium_git') + '/external/netty-tcnative.git' + '@' + '5b46a8ef4a39c39c576fcdaaf718b585d75df463', 'condition': 'checkout_android', @@ -1263,7 +1279,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '2d31db0b3751edccd984896321db1014b8bd26d5', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '3a578ae352335947ee862d0a9ebc0a70e71902b0', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1400,6 +1416,9 @@ 'dep_type': 'cipd', }, + 'src/third_party/ruy/src': + Var('chromium_git') + '/external/github.com/google/ruy.git' + '@' + '34ea9f4993955fa1ff4eb58e504421806b7f2e8f', + 'src/third_party/shaka-player/dist': { 'packages': [ { @@ -1440,7 +1459,10 @@ 'url': Var('chromium_git') + '/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git' + '@' + 'b2df6bf7b4dc1665989306a8119eb041f013f567', 'condition': 'checkout_ios', }, - + + 'src/third_party/tflite/src': + Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + 'fcc4b966f1265f466e82617020af93670141b009', + 'src/third_party/turbine': { 'packages': [ { @@ -1578,7 +1600,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1ba982f47a9f0e8104378959fc3862b3e012a8aa', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@efe28dbf48ad134d3d13695acb599991fdc185f6', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_browser_process.cc b/android_webview/browser/aw_browser_process.cc index 4c72e05..4ca152e3 100644 --- a/android_webview/browser/aw_browser_process.cc +++ b/android_webview/browser/aw_browser_process.cc
@@ -29,6 +29,7 @@ "auth.android_negotiate_account_type"; // Allowlist containing servers for which Integrated Authentication is enabled. +// This pref should match |prefs::kAuthServerAllowlist|. const char kAuthServerAllowlist[] = "auth.server_allowlist"; } // namespace prefs
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java index c4426e3..84a2fc98 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
@@ -594,12 +594,9 @@ } @Test - /** - * @SmallTest - * @Feature({"AndroidWebView"}) - * BUG=813837 - */ - @DisabledTest + @SmallTest + @Feature({"AndroidWebView"}) + @DisabledTest(message = "https://crbug.com/813837") public void testFlingScrollOnPopup() throws Throwable { final TestAwContentsClient parentContentsClient = new TestAwContentsClient(); final ScrollTestContainerView parentContainerView =
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutocompleteTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutocompleteTest.java index 14e0ceb..ae5d082 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutocompleteTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutocompleteTest.java
@@ -27,7 +27,7 @@ /** * AwAutocompleteTest only runs below Android O. */ -@DisabledTest +@DisabledTest(message = "https://crbug.com/944504") public class AwAutocompleteTest { public static final String FILE = "/login.html"; public static final String TITLE = "DONE";
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnUnhandledKeyEventTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnUnhandledKeyEventTest.java index 8f5c71a7..d7b67ac 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnUnhandledKeyEventTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnUnhandledKeyEventTest.java
@@ -82,7 +82,7 @@ * work. */ @Test - @DisabledTest + @DisabledTest(message = "https://crbug.com/538377") public void testTextboxConsumesKeyEvents() throws Throwable { AwActivityTestRule.enableJavaScriptOnUiThread(mTestContainerView.getAwContents()); final String data = "<html><head></head><body><textarea id='textarea0'></textarea></body>"
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwImeTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwImeTest.java index cb255ae..4cfbc5e 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwImeTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwImeTest.java
@@ -177,10 +177,9 @@ * keydown event. */ // https://crbug.com/787651 - // Flaky! - https://crbug.com/795423 @Test - // @SmallTest - @DisabledTest + @SmallTest + @DisabledTest(message = "https://crbug.com/795423") public void testImeDpadMovesFocusOutOfWebView() throws Throwable { loadContentEditableBody(); focusOnEditTextAndShowKeyboard(); @@ -243,10 +242,9 @@ } // https://crbug.com/920061 - // Flaky! - https://crbug.com/1061218 @Test - // @SmallTest - @DisabledTest + @SmallTest + @DisabledTest(message = "https://crbug.com/1061218") public void testFocusAndViewSizeChangeCausesScroll() throws Throwable { loadBottomInputHtml(); Rect currentRect = new Rect();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/KeySystemTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/KeySystemTest.java index b97cae2..05a57d6 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/KeySystemTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/KeySystemTest.java
@@ -111,8 +111,8 @@ @Test @Feature({"AndroidWebView"}) - @DisabledTest - // crbug/701916 + @SmallTest + @DisabledTest(message = "https://crbug.com/701916") public void testSupportWidevineKeySystem() throws Throwable { Assert.assertEquals( getPlatformKeySystemExpectations(), isKeySystemSupported("com.widevine.alpha")); @@ -127,8 +127,8 @@ @Test @Feature({"AndroidWebView"}) - @DisabledTest - // crbug/701916 + @SmallTest + @DisabledTest(message = "https://crbug.com/701916") public void testSupportPlatformKeySystem() throws Throwable { Assert.assertEquals(getPlatformKeySystemExpectations(), isKeySystemSupported("x-com.oem.test-keysystem"));
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 0583cb0c..9e88880 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -319,6 +319,8 @@ "clipboard/clipboard_nudge_constants.h", "clipboard/clipboard_nudge_controller.cc", "clipboard/clipboard_nudge_controller.h", + "clipboard/scoped_clipboard_history_pause_impl.cc", + "clipboard/scoped_clipboard_history_pause_impl.h", "clipboard/views/clipboard_history_bitmap_item_view.cc", "clipboard/views/clipboard_history_bitmap_item_view.h", "clipboard/views/clipboard_history_item_view.cc",
diff --git a/ash/ambient/ambient_controller.cc b/ash/ambient/ambient_controller.cc index a890a966..0c5bf62 100644 --- a/ash/ambient/ambient_controller.cc +++ b/ash/ambient/ambient_controller.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include "ash/ambient/model/ambient_backend_model_observer.h" #include "ash/ambient/ui/ambient_container_view.h" @@ -22,6 +23,7 @@ #include "ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h" #include "ash/public/cpp/assistant/controller/assistant_ui_controller.h" #include "ash/public/cpp/shell_window_ids.h" +#include "ash/root_window_controller.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/system/power/power_status.h" @@ -44,7 +46,6 @@ #include "ui/aura/client/aura_constants.h" #include "ui/base/ui_base_types.h" #include "ui/base/user_activity/user_activity_detector.h" -#include "ui/events/types/event_type.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" #include "ui/wm/core/cursor_manager.h" @@ -76,11 +77,6 @@ #endif // BUILDFLAG(ENABLE_CROS_AMBIENT_MODE_BACKEND) } -aura::Window* GetWidgetContainer() { - return Shell::GetContainer(Shell::GetPrimaryRootWindow(), - kShellWindowId_AmbientModeContainer); -} - // Returns the name of the ambient widget. std::string GetWidgetName() { if (ambient::util::IsShowing(LockScreen::ScreenType::kLock)) @@ -191,8 +187,7 @@ } AmbientController::~AmbientController() { - if (container_view_) - container_view_->GetWidget()->CloseNow(); + CloseAllWidgets(/*immediately=*/true); } void AmbientController::OnAmbientUiVisibilityChanged( @@ -228,7 +223,7 @@ break; case AmbientUiVisibility::kHidden: case AmbientUiVisibility::kClosed: - CloseWidget(/*immediately=*/false); + CloseAllWidgets(/*immediately=*/false); // TODO(wutao): This will clear the image cache currently. It will not // work with `kHidden` if the token has expired and ambient mode is shown @@ -286,7 +281,6 @@ void AmbientController::OnAutoShowTimeOut() { DCHECK(IsUiHidden(ambient_ui_model_.ui_visibility())); - DCHECK(!container_view_); // Show ambient screen after time out. ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kShown); @@ -388,48 +382,6 @@ } } -void AmbientController::ScreenBrightnessChanged( - const power_manager::BacklightBrightnessChange& change) { - DVLOG(1) << "ScreenBrightnessChanged: " - << (change.has_percent() ? change.percent() : -1); - - if (!change.has_percent()) - return; - - constexpr double kMinBrightness = 0.01; - if (change.percent() < kMinBrightness) { - if (is_screen_off_) - return; - - DVLOG(1) << "Screen is off, close ambient mode."; - is_screen_off_ = true; - // If screen is off, turn everything off. This covers: - // 1. Manually turn screen off. - // 2. Clicking tablet power button. - // 3. Close lid. - // Need to specially close the widget immediately here to be able to close - // the UI before device goes to suspend. Otherwise when opening lid after - // lid closed, there may be a flash of the old window before previous - // closing finished. - CloseWidget(/*immediately=*/true); - CloseUi(); - return; - } - - // change.percent() > kMinBrightness - if (!is_screen_off_) - return; - is_screen_off_ = false; - - // Reset image failures to allow retrying ambient mode because screen has - // turned back on. - GetAmbientBackendModel()->ResetImageFailures(); - - // If screen is back on, turn on ambient mode for lock screen. - if (LockScreen::HasInstance()) - ShowHiddenUi(); -} - void AmbientController::ScreenIdleStateChanged( const power_manager::ScreenIdleState& idle_state) { DVLOG(1) << "ScreenIdleStateChanged: dimmed(" << idle_state.dimmed() @@ -438,25 +390,48 @@ if (!IsAmbientModeEnabled()) return; - // "off" state should already be handled by the screen brightness handler. - if (idle_state.off()) - return; + if (idle_state.off()) { + DVLOG(1) << "Screen is off, close ambient mode."; - if (!idle_state.dimmed()) - return; - - // Do not show the UI if lockscreen is active. The inactivity monitor should - // have activated ambient mode. - if (LockScreen::HasInstance()) - return; - - // Do not show UI if loading images was unsuccessful. - if (GetAmbientBackendModel()->ImageLoadingFailed()) { - VLOG(1) << "Skipping ambient mode activation due to prior failure"; + CloseAllWidgets(/*immediately=*/true); + CloseUi(); return; } - ShowUi(); + if (idle_state.dimmed()) { + // Do not show the UI if lockscreen is active. The inactivity monitor should + // have activated ambient mode. + if (LockScreen::HasInstance()) + return; + + // Do not show UI if loading images was unsuccessful. + if (GetAmbientBackendModel()->ImageLoadingFailed()) { + VLOG(1) << "Skipping ambient mode activation due to prior failure"; + return; + } + + ShowUi(); + return; + } + + if (LockScreen::HasInstance() && + ambient_ui_model_.ui_visibility() == AmbientUiVisibility::kClosed) { + // Restart hidden ui if the screen is back on and lockscreen is shown. + ShowHiddenUi(); + } +} + +void AmbientController::SuspendImminent( + power_manager::SuspendImminent::Reason reason) { + // If about to suspend, turn everything off. This covers: + // 1. Clicking power button. + // 2. Close lid. + // Need to specially close the widget immediately here to be able to close + // the UI before device goes to suspend. Otherwise when opening lid after + // lid closed, there may be a flash of the old window before previous + // closing finished. + CloseAllWidgets(/*immediately=*/true); + CloseUi(); } void AmbientController::OnAuthScanDone( @@ -507,6 +482,7 @@ DVLOG(1) << __func__; ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kClosed); + GetAmbientBackendModel()->ResetImageFailures(); } void AmbientController::ToggleInSessionUi() { @@ -517,7 +493,7 @@ } bool AmbientController::IsShown() const { - return container_view_ && container_view_->IsDrawn(); + return ambient_ui_model_.ui_visibility() == AmbientUiVisibility::kShown; } void AmbientController::AcquireWakeLock() { @@ -558,16 +534,11 @@ delayed_lock_timer_.Stop(); } -void AmbientController::CloseWidget(bool immediately) { - if (!container_view_) - return; - - if (immediately) - container_view_->GetWidget()->CloseNow(); - else - container_view_->GetWidget()->Close(); - - container_view_ = nullptr; +void AmbientController::CloseAllWidgets(bool immediately) { + for (auto* root_window_controller : + RootWindowController::root_window_controllers()) { + root_window_controller->CloseAmbientWidget(immediately); + } } void AmbientController::OnLockScreenInactivityTimeoutPrefChanged() { @@ -631,7 +602,7 @@ } void AmbientController::OnImagesReady() { - CreateAndShowWidget(); + CreateAndShowWidgets(); } void AmbientController::OnImagesFailed() { @@ -639,27 +610,24 @@ CloseUi(); } -std::unique_ptr<AmbientContainerView> AmbientController::CreateContainerView() { - DCHECK(!container_view_); - - auto container = std::make_unique<AmbientContainerView>(&delegate_); - container_view_ = container.get(); - return container; -} - -void AmbientController::CreateAndShowWidget() { - DCHECK(!container_view_); +std::unique_ptr<views::Widget> AmbientController::CreateWidget( + aura::Window* container) { + auto container_view = std::make_unique<AmbientContainerView>(&delegate_); + auto* widget_delegate = new AmbientWidgetDelegate(); + widget_delegate->SetInitiallyFocusedView(container_view.get()); views::Widget::InitParams params; params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; params.name = GetWidgetName(); params.show_state = ui::SHOW_STATE_FULLSCREEN; - params.parent = GetWidgetContainer(); - params.delegate = new AmbientWidgetDelegate(); + params.parent = container; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.delegate = widget_delegate; + params.visible_on_all_workspaces = true; - views::Widget* widget = new views::Widget; + auto widget = std::make_unique<views::Widget>(); widget->Init(std::move(params)); - widget->SetContentsView(CreateContainerView()); + widget->SetContentsView(std::move(container_view)); widget->SetVisibilityAnimationTransition( views::Widget::VisibilityTransition::ANIMATE_BOTH); @@ -669,11 +637,16 @@ widget->Show(); + return widget; +} + +void AmbientController::CreateAndShowWidgets() { // Hide cursor. Shell::Get()->cursor_manager()->HideCursor(); - - // Requests keyboard focus for |container_view_| to receive keyboard events. - container_view_->RequestFocus(); + for (auto* root_window_controller : + RootWindowController::root_window_controllers()) { + root_window_controller->CreateAmbientWidget(); + } } void AmbientController::StartRefreshingImages() {
diff --git a/ash/ambient/ambient_controller.h b/ash/ambient/ambient_controller.h index be8a74c..c28fb8a 100644 --- a/ash/ambient/ambient_controller.h +++ b/ash/ambient/ambient_controller.h
@@ -6,6 +6,7 @@ #define ASH_AMBIENT_AMBIENT_CONTROLLER_H_ #include <memory> +#include <vector> #include "ash/ambient/ambient_access_token_controller.h" #include "ash/ambient/ambient_photo_controller.h" @@ -70,10 +71,9 @@ void OnPowerStatusChanged() override; // chromeos::PowerManagerClient::Observer: - void ScreenBrightnessChanged( - const power_manager::BacklightBrightnessChange& change) override; void ScreenIdleStateChanged( const power_manager::ScreenIdleState& idle_state) override; + void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; // fingerprint::mojom::FingerprintObserver: void OnAuthScanDone( @@ -100,13 +100,17 @@ void ToggleInSessionUi(); - // Returns true if the |container_view_| is currently visible. + // Returns true if ambient mode containers are visible or are being + // constructed. bool IsShown() const; void RequestAccessToken( AmbientAccessTokenController::AccessTokenCallback callback, bool may_refresh_token_on_lock = false); + // Creates a widget and |AmbientContainerView| for the container. + std::unique_ptr<views::Widget> CreateWidget(aura::Window* container); + AmbientBackendModel* GetAmbientBackendModel(); AmbientBackendController* ambient_backend_controller() { @@ -129,14 +133,9 @@ void OnImagesReady() override; void OnImagesFailed() override; - // Initializes the |container_view_|. Called in |CreateWidget()| to create the - // contents view. - std::unique_ptr<AmbientContainerView> CreateContainerView(); - - // TODO(meilinw): reuses the lock-screen widget: b/156531168, b/157175030. - // Creates and shows a full-screen widget responsible for showing - // the ambient UI. - void CreateAndShowWidget(); + // Creates and shows a full-screen widget for each root window to show the + // ambient UI. + void CreateAndShowWidgets(); void StartRefreshingImages(); void StopRefreshingImages(); @@ -155,24 +154,17 @@ // Release |wake_lock_|. Unbalanced release call will have no effect. void ReleaseWakeLock(); - void CloseWidget(bool immediately); + void CloseAllWidgets(bool immediately); // Invoked when the Ambient mode prefs state changes. void OnLockScreenInactivityTimeoutPrefChanged(); void OnLockScreenBackgroundTimeoutPrefChanged(); void OnPhotoRefreshIntervalPrefChanged(); - AmbientContainerView* get_container_view_for_testing() { - return container_view_; - } - AmbientAccessTokenController* access_token_controller_for_testing() { return &access_token_controller_; } - // Owned by |RootView| of its parent widget. - AmbientContainerView* container_view_ = nullptr; - AmbientViewDelegateImpl delegate_{this}; AmbientUiModel ambient_ui_model_; @@ -200,8 +192,6 @@ ScopedObserver<ui::UserActivityDetector, ui::UserActivityObserver> user_activity_observer_{this}; - bool is_screen_off_ = false; - // Observes user profile prefs for ambient. std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
diff --git a/ash/ambient/ambient_controller_unittest.cc b/ash/ambient/ambient_controller_unittest.cc index f53983a8..2f9bfd3 100644 --- a/ash/ambient/ambient_controller_unittest.cc +++ b/ash/ambient/ambient_controller_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/ambient/test/ambient_ash_test_base.h" #include "ash/ambient/ui/ambient_container_view.h" #include "ash/public/cpp/ambient/ambient_ui_model.h" +#include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/system/power/power_status.h" #include "base/run_loop.h" @@ -39,6 +40,14 @@ AmbientAshTestBase::SetUp(); GetSessionControllerClient()->set_show_lock_screen_views(true); } + + bool WidgetsVisible() { + const auto& views = GetContainerViews(); + return views.size() > 0 && + std::all_of(views.cbegin(), views.cend(), [](const auto* view) { + return view->GetWidget()->IsVisible(); + }); + } }; TEST_F(AmbientControllerTest, ShowAmbientScreenUponLock) { @@ -51,7 +60,7 @@ FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_TRUE(container_view()); + EXPECT_FALSE(GetContainerViews().empty()); EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), AmbientUiVisibility::kShown); EXPECT_TRUE(ambient_controller()->IsShown()); @@ -73,7 +82,7 @@ FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_FALSE(container_view()); + EXPECT_TRUE(GetContainerViews().empty()); EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), AmbientUiVisibility::kClosed); EXPECT_FALSE(ambient_controller()->IsShown()); @@ -88,14 +97,15 @@ FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_TRUE(container_view()); + EXPECT_FALSE(GetContainerViews().empty()); EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), AmbientUiVisibility::kShown); EXPECT_TRUE(ambient_controller()->IsShown()); HideAmbientScreen(); - EXPECT_FALSE(container_view()); + FastForwardTiny(); + EXPECT_TRUE(GetContainerViews().empty()); EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), AmbientUiVisibility::kHidden); @@ -109,7 +119,7 @@ FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_TRUE(container_view()); + EXPECT_FALSE(GetContainerViews().empty()); EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), AmbientUiVisibility::kShown); EXPECT_TRUE(ambient_controller()->IsShown()); @@ -120,7 +130,8 @@ AmbientUiVisibility::kClosed); EXPECT_FALSE(ambient_controller()->IsShown()); // The view should be destroyed along the widget. - EXPECT_FALSE(container_view()); + FastForwardTiny(); + EXPECT_TRUE(GetContainerViews().empty()); } TEST_F(AmbientControllerTest, CloseAmbientScreenUponUnlockSecondaryUser) { @@ -133,7 +144,7 @@ FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_TRUE(container_view()); + EXPECT_FALSE(GetContainerViews().empty()); EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), AmbientUiVisibility::kShown); EXPECT_TRUE(ambient_controller()->IsShown()); @@ -143,7 +154,8 @@ AmbientUiVisibility::kClosed); EXPECT_FALSE(ambient_controller()->IsShown()); // The view should be destroyed along the widget. - EXPECT_FALSE(container_view()); + FastForwardTiny(); + EXPECT_TRUE(GetContainerViews().empty()); FastForwardToLockScreenTimeout(); FastForwardTiny(); @@ -151,7 +163,8 @@ AmbientUiVisibility::kClosed); EXPECT_FALSE(ambient_controller()->IsShown()); // The view should be destroyed along the widget. - EXPECT_FALSE(container_view()); + FastForwardTiny(); + EXPECT_TRUE(GetContainerViews().empty()); } TEST_F(AmbientControllerTest, NotShowAmbientWhenLockSecondaryUser) { @@ -164,7 +177,7 @@ FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_TRUE(container_view()); + EXPECT_FALSE(GetContainerViews().empty()); EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), AmbientUiVisibility::kShown); EXPECT_TRUE(ambient_controller()->IsShown()); @@ -178,7 +191,8 @@ AmbientUiVisibility::kClosed); EXPECT_FALSE(ambient_controller()->IsShown()); // The view should be destroyed along the widget. - EXPECT_FALSE(container_view()); + FastForwardTiny(); + EXPECT_TRUE(GetContainerViews().empty()); LockScreen(); FastForwardToLockScreenTimeout(); @@ -188,7 +202,7 @@ AmbientUiVisibility::kClosed); EXPECT_FALSE(ambient_controller()->IsShown()); // The view should be destroyed along the widget. - EXPECT_FALSE(container_view()); + EXPECT_TRUE(GetContainerViews().empty()); } TEST_F(AmbientControllerTest, ShouldRequestAccessTokenWhenLockingScreen) { @@ -472,11 +486,12 @@ for (const auto& event : events) { ShowAmbientScreen(); FastForwardTiny(); - EXPECT_TRUE(container_view()->GetWidget()->IsVisible()); + EXPECT_TRUE(WidgetsVisible()); ambient_controller()->OnUserActivity(event.get()); - EXPECT_FALSE(container_view()); + FastForwardTiny(); + EXPECT_TRUE(GetContainerViews().empty()); // Clean up. CloseAmbientScreen(); @@ -487,16 +502,17 @@ LockScreen(); FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_TRUE(container_view()->GetWidget()->IsVisible()); + EXPECT_TRUE(WidgetsVisible()); ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::KeyboardCode::VKEY_1, ui::EF_NONE); ambient_controller()->OnUserActivity(&key_event); - EXPECT_FALSE(container_view()); + FastForwardTiny(); + EXPECT_TRUE(GetContainerViews().empty()); FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_TRUE(container_view()->GetWidget()->IsVisible()); + EXPECT_TRUE(WidgetsVisible()); } TEST_F(AmbientControllerTest, @@ -508,9 +524,6 @@ // Should enter ambient mode when the screen is dimmed. SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); EXPECT_FALSE(IsLocked()); - EXPECT_FALSE(ambient_controller()->IsShown()); - - FastForwardTiny(); EXPECT_TRUE(ambient_controller()->IsShown()); FastForwardToLockScreen(); @@ -532,7 +545,6 @@ // Should enter ambient mode when the screen is dimmed. SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); EXPECT_FALSE(IsLocked()); - EXPECT_FALSE(ambient_controller()->IsShown()); FastForwardTiny(); EXPECT_TRUE(ambient_controller()->IsShown()); @@ -561,11 +573,11 @@ SetPowerStateDischarging(); EXPECT_FALSE(ambient_controller()->IsShown()); - // Should not lock the device and enter ambient mode when the screen is + // Should not lock the device but still enter ambient mode when the screen is // dimmed. SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); EXPECT_FALSE(IsLocked()); - EXPECT_FALSE(ambient_controller()->IsShown()); + EXPECT_TRUE(ambient_controller()->IsShown()); FastForwardToLockScreenTimeout(); FastForwardTiny(); @@ -604,7 +616,6 @@ // Should not lock the device and enter ambient mode when the screen is // dimmed. - SetScreenBrightnessAndWait(/*percent=*/50); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); EXPECT_FALSE(IsLocked()); @@ -612,13 +623,11 @@ EXPECT_TRUE(ambient_controller()->IsShown()); // Should dismiss ambient mode screen. - SetScreenBrightnessAndWait(/*percent=*/0); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/true); FastForwardTiny(); EXPECT_FALSE(ambient_controller()->IsShown()); // Screen back on again, should not have ambient screen. - SetScreenBrightnessAndWait(/*percent=*/50); SetScreenIdleStateAndWait(/*dimmed=*/false, /*off=*/false); FastForwardTiny(); EXPECT_FALSE(ambient_controller()->IsShown()); @@ -632,7 +641,6 @@ // Should not lock the device and enter ambient mode when the screen is // dimmed. - SetScreenBrightnessAndWait(/*percent=*/50); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); EXPECT_FALSE(IsLocked()); @@ -644,7 +652,6 @@ EXPECT_TRUE(IsLocked()); // Should dismiss ambient mode screen. - SetScreenBrightnessAndWait(/*percent=*/0); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/true); FastForwardToLockScreenTimeout(); FastForwardTiny(); @@ -652,7 +659,6 @@ // Screen back on again, should not have ambient screen, but still has lock // screen. - SetScreenBrightnessAndWait(/*percent=*/50); SetScreenIdleStateAndWait(/*dimmed=*/false, /*off=*/false); EXPECT_TRUE(IsLocked()); EXPECT_FALSE(ambient_controller()->IsShown()); @@ -672,7 +678,7 @@ FastForwardToLockScreenTimeout(); FastForwardTiny(); - EXPECT_TRUE(container_view()); + EXPECT_FALSE(GetContainerViews().empty()); EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), AmbientUiVisibility::kShown); EXPECT_TRUE(ambient_controller()->IsShown()); @@ -683,4 +689,76 @@ EXPECT_FALSE(ambient_controller()->IsShown()); } +TEST_F(AmbientControllerTest, ShowsOnMultipleDisplays) { + UpdateDisplay("800x600,800x600"); + FastForwardTiny(); + + ShowAmbientScreen(); + FastForwardToNextImage(); + + auto* screen = display::Screen::GetScreen(); + EXPECT_EQ(screen->GetNumDisplays(), 2); + EXPECT_EQ(GetContainerViews().size(), 2u); + // Check that each root controller has an ambient widget. + for (auto* ctrl : RootWindowController::root_window_controllers()) + EXPECT_TRUE(ctrl->ambient_widget_for_testing() && + ctrl->ambient_widget_for_testing()->IsVisible()); +} + +TEST_F(AmbientControllerTest, RespondsToDisplayAdded) { + UpdateDisplay("800x600"); + ShowAmbientScreen(); + FastForwardToNextImage(); + + auto* screen = display::Screen::GetScreen(); + EXPECT_EQ(screen->GetNumDisplays(), 1); + EXPECT_EQ(GetContainerViews().size(), 1u); + + UpdateDisplay("800x600,800x600"); + FastForwardTiny(); + + EXPECT_TRUE(WidgetsVisible()); + EXPECT_EQ(screen->GetNumDisplays(), 2); + EXPECT_EQ(GetContainerViews().size(), 2u); + for (auto* ctrl : RootWindowController::root_window_controllers()) + EXPECT_TRUE(ctrl->ambient_widget_for_testing() && + ctrl->ambient_widget_for_testing()->IsVisible()); +} + +TEST_F(AmbientControllerTest, HandlesDisplayRemoved) { + UpdateDisplay("800x600,800x600"); + FastForwardTiny(); + + ShowAmbientScreen(); + FastForwardToNextImage(); + + auto* screen = display::Screen::GetScreen(); + EXPECT_EQ(screen->GetNumDisplays(), 2); + EXPECT_EQ(GetContainerViews().size(), 2u); + EXPECT_TRUE(WidgetsVisible()); + + // Changing to one screen will destroy the widget on the non-primary screen. + UpdateDisplay("800x600"); + FastForwardTiny(); + + EXPECT_EQ(screen->GetNumDisplays(), 1); + EXPECT_EQ(GetContainerViews().size(), 1u); + EXPECT_TRUE(WidgetsVisible()); +} + +TEST_F(AmbientControllerTest, ClosesAmbientBeforeSuspend) { + LockScreen(); + FastForwardToLockScreenTimeout(); + + EXPECT_TRUE(ambient_controller()->IsShown()); + SimulateSystemSuspendAndWait(power_manager::SuspendImminent::Reason:: + SuspendImminent_Reason_LID_CLOSED); + + EXPECT_FALSE(ambient_controller()->IsShown()); + + FastForwardToLockScreenTimeout(); + // Ambient mode should not resume after suspend. + EXPECT_FALSE(ambient_controller()->IsShown()); +} + } // namespace ash
diff --git a/ash/ambient/test/ambient_ash_test_base.cc b/ash/ambient/test/ambient_ash_test_base.cc index 5070fa9..aed8e828 100644 --- a/ash/ambient/test/ambient_ash_test_base.cc +++ b/ash/ambient/test/ambient_ash_test_base.cc
@@ -20,11 +20,13 @@ #include "ash/public/cpp/ambient/ambient_prefs.h" #include "ash/public/cpp/ambient/ambient_ui_model.h" #include "ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h" +#include "ash/root_window_controller.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "base/callback.h" #include "base/files/file_util.h" #include "base/memory/ptr_util.h" +#include "base/notreached.h" #include "base/run_loop.h" #include "base/sequenced_task_runner.h" #include "base/threading/scoped_blocking_call.h" @@ -33,9 +35,11 @@ #include "chromeos/dbus/power/fake_power_manager_client.h" #include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/power_manager/idle.pb.h" +#include "ui/display/screen.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_unittest_util.h" #include "ui/views/controls/label.h" +#include "ui/views/widget/widget.h" namespace ash { namespace { @@ -212,36 +216,46 @@ base::RunLoop().RunUntilIdle(); } -void AmbientAshTestBase::SetScreenBrightnessAndWait(double percent) { - power_manager::BacklightBrightnessChange change; - change.set_percent(percent); - - chromeos::FakePowerManagerClient::Get()->SendScreenBrightnessChanged(change); - base::RunLoop().RunUntilIdle(); +std::vector<views::View*> +AmbientAshTestBase::GetMediaStringViewTextContainers() { + std::vector<views::View*> result; + for (auto* view : GetMediaStringViews()) + result.push_back(view->media_text_container_for_testing()); + return result; } views::View* AmbientAshTestBase::GetMediaStringViewTextContainer() { return GetMediaStringView()->media_text_container_for_testing(); } +std::vector<views::Label*> AmbientAshTestBase::GetMediaStringViewTextLabels() { + std::vector<views::Label*> result; + for (auto* view : GetMediaStringViews()) + result.push_back(view->media_text_label_for_testing()); + return result; +} + views::Label* AmbientAshTestBase::GetMediaStringViewTextLabel() { return GetMediaStringView()->media_text_label_for_testing(); } void AmbientAshTestBase::SimulateMediaMetadataChanged( media_session::MediaMetadata metadata) { - GetMediaStringView()->MediaSessionMetadataChanged(metadata); + for (auto* view : GetMediaStringViews()) + view->MediaSessionMetadataChanged(metadata); } void AmbientAshTestBase::SimulateMediaPlaybackStateChanged( media_session::mojom::MediaPlaybackState state) { - // Creates media session info. - media_session::mojom::MediaSessionInfoPtr session_info( - media_session::mojom::MediaSessionInfo::New()); - session_info->playback_state = state; + for (auto* media_string_view : GetMediaStringViews()) { + // Creates media session info. + media_session::mojom::MediaSessionInfoPtr session_info( + media_session::mojom::MediaSessionInfo::New()); + session_info->playback_state = state; - // Simulate media session info changed. - GetMediaStringView()->MediaSessionInfoChanged(std::move(session_info)); + // Simulate media session info changed. + media_string_view->MediaSessionInfoChanged(std::move(session_info)); + } } void AmbientAshTestBase::SetPhotoViewImageSize(int width, int height) { @@ -251,17 +265,36 @@ image_decoder->SetImageSize(width, height); } +std::vector<AmbientBackgroundImageView*> +AmbientAshTestBase::GetAmbientBackgroundImageViews() { + std::vector<AmbientBackgroundImageView*> result; + for (auto* view : GetContainerViews()) { + auto* background_image_view = + view->GetViewByID(AmbientViewID::kAmbientBackgroundImageView); + result.push_back( + static_cast<AmbientBackgroundImageView*>(background_image_view)); + } + return result; +} + AmbientBackgroundImageView* AmbientAshTestBase::GetAmbientBackgroundImageView() { - DCHECK(container_view()); - return static_cast<AmbientBackgroundImageView*>(container_view()->GetViewByID( - AmbientViewID::kAmbientBackgroundImageView)); + return static_cast<AmbientBackgroundImageView*>( + GetContainerView()->GetViewByID(kAmbientBackgroundImageView)); +} + +std::vector<MediaStringView*> AmbientAshTestBase::GetMediaStringViews() { + std::vector<MediaStringView*> result; + for (auto* view : GetContainerViews()) { + auto* media_string_view = view->GetViewByID(kAmbientMediaStringView); + result.push_back(static_cast<MediaStringView*>(media_string_view)); + } + return result; } MediaStringView* AmbientAshTestBase::GetMediaStringView() { - DCHECK(container_view()); return static_cast<MediaStringView*>( - container_view()->GetViewByID(AmbientViewID::kAmbientMediaStringView)); + GetContainerView()->GetViewByID(kAmbientMediaStringView)); } void AmbientAshTestBase::FastForwardToLockScreenTimeout() { @@ -367,8 +400,30 @@ return ambient_controller()->ambient_photo_controller(); } -AmbientContainerView* AmbientAshTestBase::container_view() { - return ambient_controller()->get_container_view_for_testing(); +std::vector<AmbientContainerView*> AmbientAshTestBase::GetContainerViews() { + std::vector<AmbientContainerView*> result; + for (auto* ctrl : RootWindowController::root_window_controllers()) { + auto* widget = ctrl->ambient_widget_for_testing(); + if (widget) { + auto* view = widget->GetContentsView(); + DCHECK(view && view->GetID() == kAmbientContainerView); + result.push_back(static_cast<AmbientContainerView*>(view)); + } + } + return result; +} + +AmbientContainerView* AmbientAshTestBase::GetContainerView() { + auto* widget = + Shell::GetPrimaryRootWindowController()->ambient_widget_for_testing(); + + if (widget) { + auto* container_view = widget->GetContentsView(); + DCHECK(container_view && container_view->GetID() == kAmbientContainerView); + return static_cast<AmbientContainerView*>(container_view); + } + + return nullptr; } AmbientAccessTokenController* AmbientAshTestBase::token_controller() {
diff --git a/ash/ambient/test/ambient_ash_test_base.h b/ash/ambient/test/ambient_ash_test_base.h index 8fe31122..9b46590 100644 --- a/ash/ambient/test/ambient_ash_test_base.h +++ b/ash/ambient/test/ambient_ash_test_base.h
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include <vector> #include "ash/ambient/ambient_access_token_controller.h" #include "ash/ambient/ambient_controller.h" @@ -14,6 +15,7 @@ #include "ash/ambient/ui/ambient_background_image_view.h" #include "ash/test/ash_test_base.h" #include "services/media_session/public/mojom/media_session.mojom.h" +#include "ui/views/view.h" #include "ui/views/widget/widget.h" namespace views { @@ -64,8 +66,16 @@ void SimulateSystemSuspendAndWait( power_manager::SuspendImminent::Reason reason); + // Return all media string view text containers. There is one per display. + std::vector<views::View*> GetMediaStringViewTextContainers(); + // Return the media string view text container for the ambient mode container + // on the default display. views::View* GetMediaStringViewTextContainer(); + // Return all media string view text labels. There is one per display. + std::vector<views::Label*> GetMediaStringViewTextLabels(); + // Return the media string view text label for the ambient mode container on + // the default display. views::Label* GetMediaStringViewTextLabel(); // Simulates the system starting to resume. @@ -76,9 +86,6 @@ // Wait until the event has been processed. void SetScreenIdleStateAndWait(bool is_screen_dimmed, bool is_off); - // Simulates a screen brightness changed event. - void SetScreenBrightnessAndWait(double percent); - void SimulateMediaMetadataChanged(media_session::MediaMetadata metadata); void SimulateMediaPlaybackStateChanged( @@ -120,17 +127,24 @@ base::TimeDelta GetRefreshTokenDelay(); + // Returns the ambient image view for each display. + std::vector<AmbientBackgroundImageView*> GetAmbientBackgroundImageViews(); + // Returns the AmbientBackgroundImageView for the default display. AmbientBackgroundImageView* GetAmbientBackgroundImageView(); - // Returns the media string view for displaying ongoing media info. + // Returns the media string views for displaying ongoing media info. + std::vector<MediaStringView*> GetMediaStringViews(); + // Returns the media string view for the default display. MediaStringView* GetMediaStringView(); AmbientController* ambient_controller(); AmbientPhotoController* photo_controller(); - // Returns the top-level view which contains all the ambient components. - AmbientContainerView* container_view(); + // Returns the top-level views which contains all the ambient components. + std::vector<AmbientContainerView*> GetContainerViews(); + // Returns the top level ambient container view for the primary root window. + AmbientContainerView* GetContainerView(); AmbientAccessTokenController* token_controller();
diff --git a/ash/ambient/ui/ambient_container_view_unittest.cc b/ash/ambient/ui/ambient_container_view_unittest.cc index 0b92549..f0118e70 100644 --- a/ash/ambient/ui/ambient_container_view_unittest.cc +++ b/ash/ambient/ui/ambient_container_view_unittest.cc
@@ -18,15 +18,18 @@ // Tests that AmbientContainerView window should be fullscreen. TEST_F(AmbientContainerViewTest, WindowFullscreenSize) { ShowAmbientScreen(); - views::Widget* widget = container_view()->GetWidget(); + for (const auto* container : GetContainerViews()) { + const views::Widget* widget = container->GetWidget(); - gfx::Rect root_window_bounds = - display::Screen::GetScreen() - ->GetDisplayNearestWindow(widget->GetNativeWindow()->GetRootWindow()) - .bounds(); - gfx::Rect container_window_bounds = - widget->GetNativeWindow()->GetBoundsInScreen(); - EXPECT_EQ(root_window_bounds, container_window_bounds); + gfx::Rect root_window_bounds = + display::Screen::GetScreen() + ->GetDisplayNearestWindow( + widget->GetNativeWindow()->GetRootWindow()) + .bounds(); + gfx::Rect container_window_bounds = + widget->GetNativeWindow()->GetBoundsInScreen(); + EXPECT_EQ(root_window_bounds, container_window_bounds); + } // Clean up. CloseAmbientScreen();
diff --git a/ash/ambient/ui/glanceable_info_view.cc b/ash/ambient/ui/glanceable_info_view.cc index fe7ee920..bb4ed881 100644 --- a/ash/ambient/ui/glanceable_info_view.cc +++ b/ash/ambient/ui/glanceable_info_view.cc
@@ -74,7 +74,7 @@ DCHECK(delegate); SetID(AmbientViewID::kAmbientGlanceableInfoView); auto* backend_model = delegate_->GetAmbientBackendModel(); - backend_model->AddObserver(this); + scoped_backend_model_observer_.Observe(backend_model); InitLayout(); @@ -84,9 +84,7 @@ } } -GlanceableInfoView::~GlanceableInfoView() { - delegate_->GetAmbientBackendModel()->RemoveObserver(this); -} +GlanceableInfoView::~GlanceableInfoView() = default; const char* GlanceableInfoView::GetClassName() const { return "GlanceableInfoView";
diff --git a/ash/ambient/ui/glanceable_info_view.h b/ash/ambient/ui/glanceable_info_view.h index 31c0bf1..20ccf3d 100644 --- a/ash/ambient/ui/glanceable_info_view.h +++ b/ash/ambient/ui/glanceable_info_view.h
@@ -5,7 +5,9 @@ #ifndef ASH_AMBIENT_UI_GLANCEABLE_INFO_VIEW_H_ #define ASH_AMBIENT_UI_GLANCEABLE_INFO_VIEW_H_ +#include "ash/ambient/model/ambient_backend_model.h" #include "ash/ambient/model/ambient_backend_model_observer.h" +#include "base/scoped_observation.h" #include "ui/views/view.h" namespace views { @@ -53,6 +55,9 @@ // Owned by |AmbientController|. AmbientViewDelegate* const delegate_ = nullptr; + + base::ScopedObservation<AmbientBackendModel, AmbientBackendModelObserver> + scoped_backend_model_observer_{this}; }; } // namespace ash
diff --git a/ash/ambient/ui/media_string_view_unittest.cc b/ash/ambient/ui/media_string_view_unittest.cc index d97ff268..ff9a3b5 100644 --- a/ash/ambient/ui/media_string_view_unittest.cc +++ b/ash/ambient/ui/media_string_view_unittest.cc
@@ -269,7 +269,8 @@ media_session::mojom::MediaPlaybackState::kPlaying); SimulateMediaMetadataChanged(metadata); // Force re-layout. - container_view()->Layout(); + for (auto* view : GetContainerViews()) + view->Layout(); EXPECT_LT(GetMediaStringViewTextLabel()->GetPreferredSize().width(), kMediaStringMaxWidthDip); @@ -288,7 +289,8 @@ media_session::mojom::MediaPlaybackState::kPlaying); SimulateMediaMetadataChanged(metadata); // Force re-layout. - container_view()->Layout(); + for (auto* view : GetContainerViews()) + view->Layout(); EXPECT_GT(GetMediaStringViewTextLabel()->GetPreferredSize().width(), kMediaStringMaxWidthDip); @@ -307,7 +309,8 @@ media_session::mojom::MediaPlaybackState::kPlaying); SimulateMediaMetadataChanged(metadata); // Force re-layout. - container_view()->Layout(); + for (auto* view : GetContainerViews()) + view->Layout(); EXPECT_LT(GetMediaStringViewTextLabel()->GetPreferredSize().width(), kMediaStringMaxWidthDip); @@ -319,7 +322,8 @@ SimulateMediaMetadataChanged(metadata); // Force re-layout. - container_view()->Layout(); + for (auto* view : GetContainerViews()) + view->Layout(); EXPECT_GT(GetMediaStringViewTextLabel()->GetPreferredSize().width(), kMediaStringMaxWidthDip); @@ -331,7 +335,8 @@ SimulateMediaMetadataChanged(metadata); // Force re-layout. - container_view()->Layout(); + for (auto* view : GetContainerViews()) + view->Layout(); EXPECT_LT(GetMediaStringViewTextLabel()->GetPreferredSize().width(), kMediaStringMaxWidthDip);
diff --git a/ash/ambient/ui/photo_view.cc b/ash/ambient/ui/photo_view.cc index 7ec02a7..79e44f6 100644 --- a/ash/ambient/ui/photo_view.cc +++ b/ash/ambient/ui/photo_view.cc
@@ -44,9 +44,7 @@ Init(); } -PhotoView::~PhotoView() { - delegate_->GetAmbientBackendModel()->RemoveObserver(this); -} +PhotoView::~PhotoView() = default; const char* PhotoView::GetClassName() const { return "PhotoView"; @@ -82,7 +80,7 @@ image_views_[1]->layer()->SetOpacity(0.0f); auto* model = delegate_->GetAmbientBackendModel(); - model->AddObserver(this); + scoped_backend_model_observer_.Observe(model); UpdateImage(model->GetCurrentImage()); }
diff --git a/ash/ambient/ui/photo_view.h b/ash/ambient/ui/photo_view.h index 9ecdf88..69d1206c 100644 --- a/ash/ambient/ui/photo_view.h +++ b/ash/ambient/ui/photo_view.h
@@ -7,10 +7,12 @@ #include <memory> +#include "ash/ambient/model/ambient_backend_model.h" #include "ash/ambient/model/ambient_backend_model_observer.h" #include "ash/ambient/ui/ambient_background_image_view.h" #include "ash/ash_export.h" #include "base/macros.h" +#include "base/scoped_observation.h" #include "ui/compositor/layer_animation_observer.h" #include "ui/views/view.h" @@ -66,6 +68,9 @@ // The index of |image_views_| to update the next image. int image_index_ = 0; + + base::ScopedObservation<AmbientBackendModel, AmbientBackendModelObserver> + scoped_backend_model_observer_{this}; }; } // namespace ash
diff --git a/ash/app_list/app_list_color_provider_impl.cc b/ash/app_list/app_list_color_provider_impl.cc index b6660ce1..2af60ef0 100644 --- a/ash/app_list/app_list_color_provider_impl.cc +++ b/ash/app_list/app_list_color_provider_impl.cc
@@ -4,6 +4,7 @@ #include "ash/app_list/app_list_color_provider_impl.h" +#include "ash/public/cpp/ash_features.h" #include "ash/style/ash_color_provider.h" #include "ash/style/default_colors.h" @@ -79,7 +80,10 @@ /*default_color*/ gfx::kGoogleGrey100); } -SkColor AppListColorProviderImpl::GetAppListItemTextColor() const { +SkColor AppListColorProviderImpl::GetAppListItemTextColor( + bool is_in_folder) const { + if (is_in_folder && !features::IsDarkLightModeEnabled()) + return SK_ColorBLACK; return DeprecatedGetContentLayerColor( AshColorProvider::ContentLayerType::kTextColorPrimary, /*default_color*/ SK_ColorWHITE);
diff --git a/ash/app_list/app_list_color_provider_impl.h b/ash/app_list/app_list_color_provider_impl.h index fb32338..c7fa476 100644 --- a/ash/app_list/app_list_color_provider_impl.h +++ b/ash/app_list/app_list_color_provider_impl.h
@@ -26,7 +26,7 @@ SkColor GetSearchBoxTextColor(SkColor default_color) const override; SkColor GetSuggestionChipBackgroundColor() const override; SkColor GetSuggestionChipTextColor() const override; - SkColor GetAppListItemTextColor() const override; + SkColor GetAppListItemTextColor(bool is_in_folder) const override; SkColor GetPageSwitcherButtonColor( bool is_root_app_grid_page_switcher) const override; SkColor GetPageSwitcherInkDropBaseColor(
diff --git a/ash/app_list/test/test_app_list_color_provider.cc b/ash/app_list/test/test_app_list_color_provider.cc index 12cf8da5..f7bf2837 100644 --- a/ash/app_list/test/test_app_list_color_provider.cc +++ b/ash/app_list/test/test_app_list_color_provider.cc
@@ -54,7 +54,8 @@ return gfx::kGoogleGrey200; } -SkColor TestAppListColorProvider::GetAppListItemTextColor() const { +SkColor TestAppListColorProvider::GetAppListItemTextColor( + bool is_in_folder) const { return gfx::kGoogleGrey200; }
diff --git a/ash/app_list/test/test_app_list_color_provider.h b/ash/app_list/test/test_app_list_color_provider.h index 52a4adaf..fac7936 100644 --- a/ash/app_list/test/test_app_list_color_provider.h +++ b/ash/app_list/test/test_app_list_color_provider.h
@@ -26,7 +26,7 @@ SkColor GetSearchBoxSecondaryTextColor(SkColor default_color) const override; SkColor GetSuggestionChipBackgroundColor() const override; SkColor GetSuggestionChipTextColor() const override; - SkColor GetAppListItemTextColor() const override; + SkColor GetAppListItemTextColor(bool is_in_folder) const override; SkColor GetPageSwitcherButtonColor( bool is_root_app_grid_page_switcher) const override; SkColor GetPageSwitcherInkDropBaseColor(
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index 34c91e6..6b9319f 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -312,10 +312,8 @@ title->SetHandlesTooltips(false); title->SetFontList(GetAppListConfig().app_title_font()); title->SetHorizontalAlignment(gfx::ALIGN_CENTER); - title->SetEnabledColor( - apps_grid_view_->is_in_folder() - ? SK_ColorBLACK - : AppListColorProvider::Get()->GetAppListItemTextColor()); + title->SetEnabledColor(AppListColorProvider::Get()->GetAppListItemTextColor( + apps_grid_view_->is_in_folder())); icon_ = AddChildView(std::make_unique<IconImageView>());
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index e85dc2057..87fa10e 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -18,6 +18,7 @@ #include "ash/public/cpp/holding_space/holding_space_controller.h" #include "ash/public/cpp/notification_utils.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/status_area_widget.h" @@ -274,9 +275,14 @@ base::BindRepeating( &CaptureModeController::RecordAndResetScreenshotsTakenInLastWeek, weak_ptr_factory_.GetWeakPtr())); + + Shell::Get()->session_controller()->AddObserver(this); + chromeos::PowerManagerClient::Get()->AddObserver(this); } CaptureModeController::~CaptureModeController() { + chromeos::PowerManagerClient::Get()->RemoveObserver(this); + Shell::Get()->session_controller()->RemoveObserver(this); DCHECK_EQ(g_instance, this); g_instance = nullptr; } @@ -382,12 +388,60 @@ weak_ptr_factory_.GetWeakPtr())); } +void CaptureModeController::OnActiveUserSessionChanged( + const AccountId& account_id) { + EndSessionOrRecording(/*for_suspend=*/false); +} + +void CaptureModeController::OnSessionStateChanged( + session_manager::SessionState state) { + if (Shell::Get()->session_controller()->IsUserSessionBlocked()) + EndSessionOrRecording(/*for_suspend=*/false); +} + +void CaptureModeController::OnChromeTerminating() { + EndSessionOrRecording(/*for_suspend=*/false); +} + +void CaptureModeController::SuspendImminent( + power_manager::SuspendImminent::Reason reason) { + EndSessionOrRecording(/*for_suspend=*/true); +} + void CaptureModeController::StartVideoRecordingImmediatelyForTesting() { DCHECK(IsActive()); DCHECK_EQ(type_, CaptureModeType::kVideo); OnVideoRecordCountDownFinished(); } +void CaptureModeController::EndSessionOrRecording(bool for_suspend) { + if (IsActive()) { + // Suspend or user session changes can happen while the capture mode session + // is active or after the three-second countdown had started but not + // finished yet. + Stop(); + return; + } + + if (!is_recording_in_progress_) + return; + + if (for_suspend) { + // If suspend happens while recording is in progress, we consider this a + // failure, and cut the recording immediately. The recording service may + // have some buffered chunks that will never be received, and as a result, + // the a few seconds at the end of the recording may get lost. + // TODO(afakhry): Think whether this is what we want. We might be able to + // end the recording normally by asking the service to StopRecording(), and + // block the suspend until all chunks have been received, and then we can + // resume it. + OnRecordingEnded(/*success=*/false); + return; + } + + EndVideoRecording(); +} + base::Optional<CaptureModeController::CaptureParams> CaptureModeController::GetCaptureParams() const { DCHECK(IsActive()); @@ -620,6 +674,11 @@ DCHECK(!recording_start_time_.is_null()); RecordCaptureModeRecordTime( (base::TimeTicks::Now() - recording_start_time_).InSeconds()); + + if (features::IsTemporaryHoldingSpaceEnabled()) { + HoldingSpaceController::Get()->client()->AddScreenRecording( + current_video_file_path_); + } } if (!on_file_saved_callback_.is_null())
diff --git a/ash/capture_mode/capture_mode_controller.h b/ash/capture_mode/capture_mode_controller.h index 5ca1eff..37bc4f3 100644 --- a/ash/capture_mode/capture_mode_controller.h +++ b/ash/capture_mode/capture_mode_controller.h
@@ -13,6 +13,7 @@ #include "ash/capture_mode/capture_mode_types.h" #include "ash/capture_mode/video_file_handler.h" #include "ash/public/cpp/capture_mode_delegate.h" +#include "ash/public/cpp/session/session_observer.h" #include "ash/services/recording/public/mojom/recording_service.mojom.h" #include "base/callback_forward.h" #include "base/memory/ref_counted_memory.h" @@ -21,6 +22,7 @@ #include "base/optional.h" #include "base/threading/sequence_bound.h" #include "base/timer/timer.h" +#include "chromeos/dbus/power/power_manager_client.h" #include "mojo/public/cpp/bindings/remote.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/image/image.h" @@ -42,7 +44,9 @@ // Controls starting and ending a Capture Mode session and its behavior. class ASH_EXPORT CaptureModeController - : public recording::mojom::RecordingServiceClient { + : public recording::mojom::RecordingServiceClient, + public SessionObserver, + public chromeos::PowerManagerClient::Observer { public: explicit CaptureModeController(std::unique_ptr<CaptureModeDelegate> delegate); CaptureModeController(const CaptureModeController&) = delete; @@ -93,6 +97,14 @@ void OnMuxerOutput(const std::string& chunk) override; void OnRecordingEnded(bool success) override; + // SessionObserver: + void OnActiveUserSessionChanged(const AccountId& account_id) override; + void OnSessionStateChanged(session_manager::SessionState state) override; + void OnChromeTerminating() override; + + // chromeos::PowerManagerClient::Observer: + void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; + // Skips the 3-second count down, and IsCaptureAllowed() checks, and starts // video recording right away for testing purposes. void StartVideoRecordingImmediatelyForTesting(); @@ -100,6 +112,12 @@ private: friend class CaptureModeTestApi; + // Used by user session change, and suspend events to end the capture mode + // session if it's active, or stop the video recording if one is in progress. + // |for_suspend| is true when this is called from |SuspendImminent()|, which + // leads to ending the video recording immediately as if it's a failure. + void EndSessionOrRecording(bool for_suspend); + // Returns the capture parameters for the capture operation that is about to // be performed (i.e. the window to be captured, and the capture bounds). If // nothing is to be captured (e.g. when there's no window selected in a
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc index 9cd5702..36667258 100644 --- a/ash/capture_mode/capture_mode_unittests.cc +++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -30,6 +30,9 @@ #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "chromeos/dbus/power/fake_power_manager_client.h" +#include "chromeos/dbus/power_manager/suspend.pb.h" +#include "components/account_id/account_id.h" #include "ui/aura/window_tracker.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/events/keycodes/keyboard_codes_posix.h" @@ -271,6 +274,21 @@ base::RunLoop().RunUntilIdle(); } + void SwitchToUser2() { + auto* session_controller = GetSessionControllerClient(); + constexpr char kUserEmail[] = "user2@capture_mode"; + session_controller->AddUserSession(kUserEmail); + session_controller->SwitchActiveUser(AccountId::FromUserEmail(kUserEmail)); + } + + void WaitForSeconds(int seconds) { + base::RunLoop loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::BindLambdaForTesting([&]() { loop.Quit(); }), + base::TimeDelta::FromSeconds(seconds)); + loop.Run(); + } + private: base::test::ScopedFeatureList scoped_feature_list_; }; @@ -1080,7 +1098,7 @@ // Enter tablet mode, the cursor should be hidden. TabletModeControllerTestApi tablet_mode_controller_test_api; - // To void flaky failures due to mouse devices blocking entering tablet mode, + // To avoid flaky failures due to mouse devices blocking entering tablet mode, // we detach all mouse devices. This shouldn't affect testing the cursor // status. tablet_mode_controller_test_api.DetachAllMice(); @@ -1161,7 +1179,7 @@ // Enter tablet mode, the cursor should be hidden. TabletModeControllerTestApi tablet_mode_controller_test_api; - // To void flaky failures due to mouse devices blocking entering tablet mode, + // To avoid flaky failures due to mouse devices blocking entering tablet mode, // we detach all mouse devices. This shouldn't affect testing the cursor // status. tablet_mode_controller_test_api.DetachAllMice(); @@ -1233,7 +1251,7 @@ // incoming input events. TEST_F(CaptureModeTest, DoNotHandleEventDuringCountDown) { // We need a non-zero duration to avoid infinite loop on countdown. - ui::ScopedAnimationDurationScaleMode animatin_scale( + ui::ScopedAnimationDurationScaleMode animation_scale( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); // Create 2 windows that overlap with each other. @@ -1390,6 +1408,67 @@ EXPECT_TRUE(stop_recording_button->visible_preferred()); } +TEST_F(CaptureModeTest, SuspendWhileSessionIsActive) { + auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen, + CaptureModeType::kVideo); + EXPECT_TRUE(controller->IsActive()); + power_manager_client()->SendSuspendImminent( + power_manager::SuspendImminent::IDLE); + EXPECT_FALSE(controller->IsActive()); +} + +TEST_F(CaptureModeTest, SuspendAfterCountdownStarts) { + // User NORMAL_DURATION for the countdown animation so we can have predictable + // timings. + ui::ScopedAnimationDurationScaleMode animation_scale( + ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); + auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen, + CaptureModeType::kVideo); + // Hit Enter to begin recording, wait for 1 second, then suspend the device. + auto* event_generator = GetEventGenerator(); + SendKey(ui::VKEY_RETURN, event_generator); + WaitForSeconds(1); + power_manager_client()->SendSuspendImminent( + power_manager::SuspendImminent::IDLE); + EXPECT_FALSE(controller->IsActive()); + EXPECT_FALSE(controller->is_recording_in_progress()); +} + +TEST_F(CaptureModeTest, SuspendAfterRecordingStarts) { + auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen, + CaptureModeType::kVideo); + controller->StartVideoRecordingImmediatelyForTesting(); + EXPECT_TRUE(controller->is_recording_in_progress()); + power_manager_client()->SendSuspendImminent( + power_manager::SuspendImminent::IDLE); + EXPECT_FALSE(controller->is_recording_in_progress()); +} + +TEST_F(CaptureModeTest, SwitchUsersWhileRecording) { + auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen, + CaptureModeType::kVideo); + controller->StartVideoRecordingImmediatelyForTesting(); + EXPECT_TRUE(controller->is_recording_in_progress()); + SwitchToUser2(); + EXPECT_FALSE(controller->is_recording_in_progress()); +} + +TEST_F(CaptureModeTest, SwitchUsersAfterCountdownStarts) { + // User NORMAL_DURATION for the countdown animation so we can have predictable + // timings. + ui::ScopedAnimationDurationScaleMode animation_scale( + ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); + auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen, + CaptureModeType::kVideo); + // Hit Enter to begin recording, wait for 1 second, then switch users. + auto* event_generator = GetEventGenerator(); + SendKey(ui::VKEY_RETURN, event_generator); + WaitForSeconds(1); + SwitchToUser2(); + EXPECT_FALSE(controller->IsActive()); + EXPECT_FALSE(controller->is_recording_in_progress()); +} + TEST_F(CaptureModeTest, ClosingDisplayBeingFullscreenRecorded) { UpdateDisplay("400x400,401+0-400x400"); auto roots = Shell::GetAllRootWindows(); @@ -1533,11 +1612,7 @@ // down is in progress. auto* event_generator = GetEventGenerator(); SendKey(ui::VKEY_RETURN, event_generator); - base::RunLoop loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::BindLambdaForTesting([&]() { loop.Quit(); }), - base::TimeDelta::FromSeconds(1)); - loop.Run(); + WaitForSeconds(1); SendKey(ui::VKEY_ESCAPE, event_generator); }
diff --git a/ash/capture_mode/video_recording_watcher.cc b/ash/capture_mode/video_recording_watcher.cc index 08b1ef01..5c534c2 100644 --- a/ash/capture_mode/video_recording_watcher.cc +++ b/ash/capture_mode/video_recording_watcher.cc
@@ -6,8 +6,6 @@ #include "ash/capture_mode/capture_mode_controller.h" #include "ash/capture_mode/capture_mode_util.h" -#include "ash/session/session_controller_impl.h" -#include "ash/shell.h" #include "base/check.h" #include "base/check_op.h" #include "base/notreached.h" @@ -24,14 +22,12 @@ DCHECK(controller_->is_recording_in_progress()); window_being_recorded_->AddObserver(this); - Shell::Get()->session_controller()->AddObserver(this); } VideoRecordingWatcher::~VideoRecordingWatcher() { DCHECK(window_being_recorded_); window_being_recorded_->RemoveObserver(this); - Shell::Get()->session_controller()->RemoveObserver(this); } void VideoRecordingWatcher::OnWindowDestroying(aura::Window* window) { @@ -68,18 +64,4 @@ capture_mode_util::SetStopRecordingButtonVisibility(new_root, true); } -void VideoRecordingWatcher::OnSessionStateChanged( - session_manager::SessionState state) { - DCHECK(controller_->is_recording_in_progress()); - - if (Shell::Get()->session_controller()->IsUserSessionBlocked()) - controller_->EndVideoRecording(); -} - -void VideoRecordingWatcher::OnChromeTerminating() { - DCHECK(controller_->is_recording_in_progress()); - - controller_->EndVideoRecording(); -} - } // namespace ash
diff --git a/ash/capture_mode/video_recording_watcher.h b/ash/capture_mode/video_recording_watcher.h index 7728d81..0130d6b 100644 --- a/ash/capture_mode/video_recording_watcher.h +++ b/ash/capture_mode/video_recording_watcher.h
@@ -5,7 +5,6 @@ #ifndef ASH_CAPTURE_MODE_VIDEO_RECORDING_WATCHER_H_ #define ASH_CAPTURE_MODE_VIDEO_RECORDING_WATCHER_H_ -#include "ash/public/cpp/session/session_observer.h" #include "ui/aura/window_observer.h" namespace ash { @@ -14,14 +13,11 @@ // An instance of this class is created while video recording is in progress to // watch for events that end video recording, such as a window being recorded -// gets closed, a display being fullscreen-recorded gets disconnected, the user -// session gets blocked, or while shutting down. -// TODO(https://crbug.com/1142994): Decide what to do when switching users in -// multi-profile. +// gets closed or moved between displays, or a display being fullscreen-recorded +// gets disconnected. // TODO(https://crbug.com/1145003): Use this to paint a border around the area // being recorded while recording is in progress. -class VideoRecordingWatcher : public aura::WindowObserver, - public SessionObserver { +class VideoRecordingWatcher : public aura::WindowObserver { public: VideoRecordingWatcher(CaptureModeController* controller, aura::Window* window_being_recorded); @@ -35,10 +31,6 @@ void OnWindowRemovingFromRootWindow(aura::Window* window, aura::Window* new_root) override; - // SessionObserver: - void OnSessionStateChanged(session_manager::SessionState state) override; - void OnChromeTerminating() override; - private: CaptureModeController* const controller_; aura::Window* const window_being_recorded_;
diff --git a/ash/clipboard/clipboard_history.cc b/ash/clipboard/clipboard_history.cc index 23e5ad6..6625ba8 100644 --- a/ash/clipboard/clipboard_history.cc +++ b/ash/clipboard/clipboard_history.cc
@@ -14,15 +14,6 @@ namespace ash { -ClipboardHistory::ScopedPause::ScopedPause(ClipboardHistory* clipboard_history) - : clipboard_history_(clipboard_history) { - clipboard_history_->Pause(); -} - -ClipboardHistory::ScopedPause::~ScopedPause() { - clipboard_history_->Resume(); -} - ClipboardHistory::ClipboardHistory() { ui::ClipboardMonitor::GetInstance()->AddObserver(this); } @@ -106,6 +97,10 @@ commit_data_weak_factory_.GetWeakPtr(), *clipboard_data)); } +base::WeakPtr<ClipboardHistory> ClipboardHistory::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + void ClipboardHistory::MaybeCommitData(ui::ClipboardData data) { if (!ClipboardHistoryUtil::IsSupported(data)) return;
diff --git a/ash/clipboard/clipboard_history.h b/ash/clipboard/clipboard_history.h index bb8bb044..e6ffeb0 100644 --- a/ash/clipboard/clipboard_history.h +++ b/ash/clipboard/clipboard_history.h
@@ -17,6 +17,8 @@ namespace ash { +class ScopedClipboardHistoryPauseImpl; + // Keeps track of the last few things saved in the clipboard. class ASH_EXPORT ClipboardHistory : public ui::ClipboardObserver { public: @@ -32,19 +34,6 @@ virtual void OnClipboardHistoryCleared() {} }; - // Prevents clipboard history from being recorded within its scope. If - // anything is copied within its scope, history will not be recorded. - class ASH_EXPORT ScopedPause { - public: - explicit ScopedPause(ClipboardHistory* clipboard_history); - ScopedPause(const ScopedPause&) = delete; - ScopedPause& operator=(const ScopedPause&) = delete; - ~ScopedPause(); - - private: - ClipboardHistory* const clipboard_history_; - }; - ClipboardHistory(); ClipboardHistory(const ClipboardHistory&) = delete; ClipboardHistory& operator=(const ClipboardHistory&) = delete; @@ -70,7 +59,13 @@ // ClipboardMonitor: void OnClipboardDataChanged() override; + base::WeakPtr<ClipboardHistory> GetWeakPtr(); + private: + // Friended to allow ScopedClipboardHistoryPauseImpl to `Pause()` and + // `Resume()`. + friend class ScopedClipboardHistoryPauseImpl; + // Adds `data` to the `history_list_` if it's supported. If `data` is not // supported by clipboard history, this method no-ops. void MaybeCommitData(ui::ClipboardData data); @@ -91,6 +86,9 @@ // Factory to create WeakPtrs used to debounce calls to CommitData(). base::WeakPtrFactory<ClipboardHistory> commit_data_weak_factory_{this}; + + // Factory to create WeakPtrs for ClipboardHistory. + base::WeakPtrFactory<ClipboardHistory> weak_factory_{this}; }; } // namespace ash
diff --git a/ash/clipboard/clipboard_history_controller_impl.cc b/ash/clipboard/clipboard_history_controller_impl.cc index c01fefc..e49afc3 100644 --- a/ash/clipboard/clipboard_history_controller_impl.cc +++ b/ash/clipboard/clipboard_history_controller_impl.cc
@@ -11,6 +11,8 @@ #include "ash/clipboard/clipboard_history_resource_manager.h" #include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/clipboard_nudge_controller.h" +#include "ash/clipboard/scoped_clipboard_history_pause_impl.h" +#include "ash/public/cpp/clipboard_image_model_factory.h" #include "ash/public/cpp/window_tree_host_lookup.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" @@ -261,6 +263,12 @@ ClipboardHistoryUtil::IsEnabledInCurrentMode(); } +std::unique_ptr<ScopedClipboardHistoryPause> +ClipboardHistoryControllerImpl::CreateScopedPause() { + return std::make_unique<ScopedClipboardHistoryPauseImpl>( + clipboard_history_.get()); +} + void ClipboardHistoryControllerImpl::OnClipboardHistoryCleared() { // Prevent clipboard contents getting restored if the Clipboard is cleared // soon after a `PasteMenuItemData()`. @@ -273,6 +281,9 @@ void ClipboardHistoryControllerImpl::ExecuteSelectedMenuItem(int event_flags) { DCHECK(IsMenuShowing()); + // Deactivate ClipboardImageModelFactory prior to pasting to ensure that any + // modifications to the clipboard for HTML rendering purposes are reversed. + ClipboardImageModelFactory::Get()->Deactivate(); auto command = context_menu_->GetSelectedMenuItemCommand(); @@ -342,7 +353,7 @@ } // Pause clipboard history when manipulating the clipboard for a paste. - ClipboardHistory::ScopedPause scoped_pause(clipboard_history_.get()); + ScopedClipboardHistoryPauseImpl scoped_pause(clipboard_history_.get()); original_data = clipboard->WriteClipboardData(std::move(temp_data)); } @@ -367,9 +378,9 @@ // need to pause clipboard history. Failure to do so will result in // the original item being re-recorded when this restoration step // should actually be opaque to the user. - std::unique_ptr<ClipboardHistory::ScopedPause> scoped_pause; + std::unique_ptr<ScopedClipboardHistoryPauseImpl> scoped_pause; if (weak_ptr) { - scoped_pause = std::make_unique<ClipboardHistory::ScopedPause>( + scoped_pause = std::make_unique<ScopedClipboardHistoryPauseImpl>( weak_ptr->clipboard_history_.get()); } GetClipboard()->WriteClipboardData(std::move(original_data));
diff --git a/ash/clipboard/clipboard_history_controller_impl.h b/ash/clipboard/clipboard_history_controller_impl.h index 6336436..f037ad64 100644 --- a/ash/clipboard/clipboard_history_controller_impl.h +++ b/ash/clipboard/clipboard_history_controller_impl.h
@@ -14,6 +14,7 @@ #include "ash/public/cpp/clipboard_history_controller.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/optional.h" namespace views { enum class MenuAnchorPosition; @@ -28,6 +29,7 @@ class ClipboardHistoryMenuModelAdapter; class ClipboardHistoryResourceManager; class ClipboardNudgeController; +class ScopedClipboardHistoryPause; // Shows a menu with the last few things saved in the clipboard when the // keyboard shortcut is pressed. @@ -84,10 +86,11 @@ class MenuDelegate; // ClipboardHistoryController: + bool CanShowMenu() const override; void ShowMenu(const gfx::Rect& anchor_rect, views::MenuAnchorPosition menu_anchor_position, ui::MenuSourceType source_type) override; - bool CanShowMenu() const override; + std::unique_ptr<ScopedClipboardHistoryPause> CreateScopedPause() override; // ClipboardHistory::Observer: void OnClipboardHistoryCleared() override; @@ -112,6 +115,7 @@ // Advances the pseudo focus (backward if `reverse` is true). void AdvancePseudoFocus(bool reverse); + // Calculates the anchor rect for the ClipboardHistory menu. gfx::Rect CalculateAnchorRect() const; // Called when the contextual menu is closed.
diff --git a/ash/clipboard/clipboard_history_unittest.cc b/ash/clipboard/clipboard_history_unittest.cc index 4101805..78686a7 100644 --- a/ash/clipboard/clipboard_history_unittest.cc +++ b/ash/clipboard/clipboard_history_unittest.cc
@@ -10,6 +10,7 @@ #include "ash/clipboard/clipboard_history_controller_impl.h" #include "ash/clipboard/clipboard_history_item.h" #include "ash/clipboard/clipboard_history_util.h" +#include "ash/clipboard/scoped_clipboard_history_pause_impl.h" #include "ash/public/cpp/clipboard_image_model_factory.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" @@ -276,7 +277,7 @@ // Because history is paused, there should be nothing stored. std::vector<base::string16> expected_strings{}; - ClipboardHistory::ScopedPause scoped_pause(clipboard_history()); + ScopedClipboardHistoryPauseImpl scoped_pause(clipboard_history()); WriteAndEnsureTextHistory(input_strings, expected_strings); }
diff --git a/ash/clipboard/scoped_clipboard_history_pause_impl.cc b/ash/clipboard/scoped_clipboard_history_pause_impl.cc new file mode 100644 index 0000000..cd744e5 --- /dev/null +++ b/ash/clipboard/scoped_clipboard_history_pause_impl.cc
@@ -0,0 +1,22 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/clipboard/scoped_clipboard_history_pause_impl.h" + +#include "ash/clipboard/clipboard_history.h" + +namespace ash { + +ScopedClipboardHistoryPauseImpl::ScopedClipboardHistoryPauseImpl( + ClipboardHistory* clipboard_history) + : clipboard_history_(clipboard_history->GetWeakPtr()) { + clipboard_history_->Pause(); +} + +ScopedClipboardHistoryPauseImpl::~ScopedClipboardHistoryPauseImpl() { + if (clipboard_history_) + clipboard_history_->Resume(); +} + +} // namespace ash
diff --git a/ash/clipboard/scoped_clipboard_history_pause_impl.h b/ash/clipboard/scoped_clipboard_history_pause_impl.h new file mode 100644 index 0000000..bb5974f --- /dev/null +++ b/ash/clipboard/scoped_clipboard_history_pause_impl.h
@@ -0,0 +1,33 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_CLIPBOARD_SCOPED_CLIPBOARD_HISTORY_PAUSE_IMPL_H_ +#define ASH_CLIPBOARD_SCOPED_CLIPBOARD_HISTORY_PAUSE_IMPL_H_ + +#include "ash/ash_export.h" +#include "ash/public/cpp/scoped_clipboard_history_pause.h" +#include "base/memory/weak_ptr.h" + +namespace ash { +class ClipboardHistory; + +// Prevents clipboard history from being recorded within its lifetime. If +// anything is copied within its lifetime, history will not be recorded. +class ASH_EXPORT ScopedClipboardHistoryPauseImpl + : public ScopedClipboardHistoryPause { + public: + explicit ScopedClipboardHistoryPauseImpl(ClipboardHistory* clipboard_history); + ScopedClipboardHistoryPauseImpl(const ScopedClipboardHistoryPauseImpl&) = + delete; + ScopedClipboardHistoryPauseImpl& operator=( + const ScopedClipboardHistoryPauseImpl&) = delete; + ~ScopedClipboardHistoryPauseImpl() override; + + private: + base::WeakPtr<ClipboardHistory> const clipboard_history_; +}; + +} // namespace ash + +#endif // ASH_CLIPBOARD_SCOPED_CLIPBOARD_HISTORY_PAUSE_IMPL_H_
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index caaa87c..5f5392a 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -232,6 +232,7 @@ "rounded_image_view.h", "scale_utility.cc", "scale_utility.h", + "scoped_clipboard_history_pause.h", "scoped_guest_button_blocker.h", "scoped_singleton_resetter_for_test.h", "screen_backlight.cc",
diff --git a/ash/public/cpp/app_list/app_list_color_provider.h b/ash/public/cpp/app_list/app_list_color_provider.h index 7b4bf58..ec6bd07b 100644 --- a/ash/public/cpp/app_list/app_list_color_provider.h +++ b/ash/public/cpp/app_list/app_list_color_provider.h
@@ -29,7 +29,7 @@ SkColor default_color) const = 0; virtual SkColor GetSuggestionChipBackgroundColor() const = 0; virtual SkColor GetSuggestionChipTextColor() const = 0; - virtual SkColor GetAppListItemTextColor() const = 0; + virtual SkColor GetAppListItemTextColor(bool is_in_folder) const = 0; virtual SkColor GetPageSwitcherButtonColor( bool is_root_app_grid_page_switcher) const = 0; virtual SkColor GetPageSwitcherInkDropBaseColor(
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index 1e449be4..d18d866 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -45,7 +45,7 @@ "DragToSnapInClamshellMode", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kEnhancedDeskAnimations{"EnhancedDeskAnimations", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kFullRestore{"FullRestore", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/public/cpp/clipboard_history_controller.h b/ash/public/cpp/clipboard_history_controller.h index 2c32704..bf7178b 100644 --- a/ash/public/cpp/clipboard_history_controller.h +++ b/ash/public/cpp/clipboard_history_controller.h
@@ -5,6 +5,8 @@ #ifndef ASH_PUBLIC_CPP_CLIPBOARD_HISTORY_CONTROLLER_H_ #define ASH_PUBLIC_CPP_CLIPBOARD_HISTORY_CONTROLLER_H_ +#include <memory> + #include "ash/public/cpp/ash_public_export.h" #include "ui/base/ui_base_types.h" @@ -18,6 +20,8 @@ namespace ash { +class ScopedClipboardHistoryPause; + // An interface implemented in Ash to enable the Chrome side to show the // clipboard history menu. class ASH_PUBLIC_EXPORT ClipboardHistoryController { @@ -34,6 +38,10 @@ views::MenuAnchorPosition menu_anchor_position, ui::MenuSourceType source_type) = 0; + // Creates a ScopedClipboardHistoryPause, which pauses ClipboardHistory for + // its lifetime. + virtual std::unique_ptr<ScopedClipboardHistoryPause> CreateScopedPause() = 0; + protected: ClipboardHistoryController(); virtual ~ClipboardHistoryController();
diff --git a/ash/public/cpp/holding_space/holding_space_client.h b/ash/public/cpp/holding_space/holding_space_client.h index 1a711fb..b12788e1 100644 --- a/ash/public/cpp/holding_space/holding_space_client.h +++ b/ash/public/cpp/holding_space/holding_space_client.h
@@ -26,6 +26,9 @@ // Adds a screenshot item backed by the provided `file_path`. virtual void AddScreenshot(const base::FilePath& file_path) = 0; + // Adds a screen recording item backed by the provided `file_path`. + virtual void AddScreenRecording(const base::FilePath& file_path) = 0; + // Attempts to copy the contents of the image file backing the specified // holding space `item` to the clipboard. If the backing file is not suspected // to contain image data, this method will abort early. Success is returned
diff --git a/ash/public/cpp/holding_space/holding_space_constants.h b/ash/public/cpp/holding_space/holding_space_constants.h index 9907197..edeb0ca5 100644 --- a/ash/public/cpp/holding_space/holding_space_constants.h +++ b/ash/public/cpp/holding_space/holding_space_constants.h
@@ -21,6 +21,7 @@ constexpr int kHoldingSpaceChipHeight = 40; constexpr int kHoldingSpaceChipIconSize = 24; constexpr int kHoldingSpaceChipWidth = 160; +constexpr int kHoldingSpaceChipLabelMaskGradientWidth = 16; constexpr int kHoldingSpaceChipsPerRow = 2; constexpr int kHoldingSpaceColumnSpacing = 8; constexpr int kHoldingSpaceColumnWidth = 160;
diff --git a/ash/public/cpp/scoped_clipboard_history_pause.h b/ash/public/cpp/scoped_clipboard_history_pause.h new file mode 100644 index 0000000..ab4c1120 --- /dev/null +++ b/ash/public/cpp/scoped_clipboard_history_pause.h
@@ -0,0 +1,21 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_PUBLIC_CPP_SCOPED_CLIPBOARD_HISTORY_PAUSE_H_ +#define ASH_PUBLIC_CPP_SCOPED_CLIPBOARD_HISTORY_PAUSE_H_ + +#include "ash/public/cpp/ash_public_export.h" + +namespace ash { + +// An object implemented in Ash that pauses ClipboardHistory for its lifetime. +class ASH_PUBLIC_EXPORT ScopedClipboardHistoryPause { + public: + ScopedClipboardHistoryPause() = default; + virtual ~ScopedClipboardHistoryPause() = default; +}; + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_SCOPED_CLIPBOARD_HISTORY_PAUSE_H_
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 01ac34f..80d7b16 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -12,6 +12,7 @@ #include "ash/accessibility/accessibility_panel_layout_manager.h" #include "ash/accessibility/touch_exploration_controller.h" #include "ash/accessibility/touch_exploration_manager.h" +#include "ash/ambient/ambient_controller.h" #include "ash/app_menu/app_menu_model_adapter.h" #include "ash/focus_cycler.h" #include "ash/high_contrast/high_contrast_controller.h" @@ -96,6 +97,7 @@ #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/view_model.h" #include "ui/views/view_model_utils.h" +#include "ui/views/widget/widget.h" #include "ui/wm/core/capture_controller.h" #include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/visibility_controller.h" @@ -649,6 +651,7 @@ touch_exploration_manager_.reset(); wallpaper_widget_controller_.reset(); + CloseAmbientWidget(/*immediately=*/true); CloseChildWindows(); aura::Window* root_window = GetRootWindow(); @@ -815,6 +818,27 @@ status_area_widget->UpdateAfterLoginStatusChange(status); } +void RootWindowController::CreateAmbientWidget() { + DCHECK(!ambient_widget_); + + auto* ambient_controller = Shell::Get()->ambient_controller(); + if (ambient_controller && ambient_controller->IsShown()) { + ambient_widget_ = ambient_controller->CreateWidget( + GetRootWindow()->GetChildById(kShellWindowId_AmbientModeContainer)); + } +} + +void RootWindowController::CloseAmbientWidget(bool immediately) { + if (ambient_widget_) { + if (immediately) + ambient_widget_->CloseNow(); + else + ambient_widget_->CloseWithReason(views::Widget::ClosedReason::kLostFocus); + } + + ambient_widget_.reset(); +} + AccessibilityPanelLayoutManager* RootWindowController::GetAccessibilityPanelLayoutManagerForTest() { return GetAccessibilityPanelLayoutManager(); @@ -883,6 +907,8 @@ Shell::Get()->session_controller()->IsUserSessionBlocked()); root_window_layout_manager_->OnWindowResized(); + CreateAmbientWidget(); + // Explicitly update the desks controller before notifying the ShellObservers. // This is to make sure the desks' states are correct before clients are // updated.
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h index c91f3ff0..e2146aed 100644 --- a/ash/root_window_controller.h +++ b/ash/root_window_controller.h
@@ -30,7 +30,8 @@ namespace views { class MenuRunner; -} +class Widget; +} // namespace views namespace wm { class ScopedCaptureClient; @@ -222,6 +223,11 @@ // Called when the login status changes after login (such as lock/unlock). void UpdateAfterLoginStatusChange(LoginStatus status); + void CreateAmbientWidget(); + void CloseAmbientWidget(bool immediately); + + views::Widget* ambient_widget_for_testing() { return ambient_widget_.get(); } + // Returns accessibility panel layout manager for this root window. AccessibilityPanelLayoutManager* GetAccessibilityPanelLayoutManagerForTest(); @@ -305,6 +311,8 @@ std::unique_ptr<LockScreenActionBackgroundController> lock_screen_action_background_controller_; + std::unique_ptr<views::Widget> ambient_widget_; + // Whether child windows have been closed during shutdown. Exists to avoid // calling related cleanup code more than once. bool did_close_child_windows_ = false;
diff --git a/ash/style/ash_color_provider.cc b/ash/style/ash_color_provider.cc index 6705b45..523dbcf 100644 --- a/ash/style/ash_color_provider.cc +++ b/ash/style/ash_color_provider.cc
@@ -223,11 +223,20 @@ case ContentLayerType::kSliderColorInactive: case ContentLayerType::kRadioColorInactive: return is_dark_mode ? gfx::kGoogleGrey200 : gfx::kGoogleGrey700; + case ContentLayerType::kSwitchKnobColorInactive: + return is_dark_mode ? gfx::kGoogleGrey800 : SK_ColorWHITE; + case ContentLayerType::kSwitchTrackColorInactive: + return GetSecondToneColor(is_dark_mode ? gfx::kGoogleGrey200 + : gfx::kGoogleGrey700); case ContentLayerType::kButtonLabelColorBlue: case ContentLayerType::kSliderColorActive: case ContentLayerType::kRadioColorActive: case ContentLayerType::kSwitchAccessInnerStrokeColor: + case ContentLayerType::kSwitchKnobColorActive: return is_dark_mode ? gfx::kGoogleBlue300 : gfx::kGoogleBlue600; + case ContentLayerType::kSwitchTrackColorActive: + return GetSecondToneColor( + GetContentLayerColor(ContentLayerType::kSwitchKnobColorActive)); case ContentLayerType::kButtonLabelColorPrimary: case ContentLayerType::kButtonIconColorPrimary: case ContentLayerType::kBatteryBadgeColor:
diff --git a/ash/style/ash_color_provider.h b/ash/style/ash_color_provider.h index 7ed63ed..89fcdc7 100644 --- a/ash/style/ash_color_provider.h +++ b/ash/style/ash_color_provider.h
@@ -121,6 +121,12 @@ kRadioColorActive, kRadioColorInactive, + // Color for toggle button. + kSwitchKnobColorActive, + kSwitchKnobColorInactive, + kSwitchTrackColorActive, + kSwitchTrackColorInactive, + // Color for current active desk's border. kCurrentDeskColor,
diff --git a/ash/system/dark_mode/dark_mode_detailed_view.cc b/ash/system/dark_mode/dark_mode_detailed_view.cc index 86e6736..a03eec95 100644 --- a/ash/system/dark_mode/dark_mode_detailed_view.cc +++ b/ash/system/dark_mode/dark_mode_detailed_view.cc
@@ -122,6 +122,7 @@ TrayDetailedView::OnThemeChanged(); themed_label_->SetEnabledColor(GetLabelColor()); neutral_label_->SetEnabledColor(GetLabelColor()); + TrayPopupUtils::UpdateToggleButtonColors(toggle_); } void DarkModeDetailedView::UpdateToggleButton(bool dark_mode_enabled) {
diff --git a/ash/system/holding_space/holding_space_item_chip_view.cc b/ash/system/holding_space/holding_space_item_chip_view.cc index 39e5c33..309fb79 100644 --- a/ash/system/holding_space/holding_space_item_chip_view.cc +++ b/ash/system/holding_space/holding_space_item_chip_view.cc
@@ -10,12 +10,65 @@ #include "ash/style/ash_color_provider.h" #include "ash/system/holding_space/holding_space_item_view.h" #include "ash/system/tray/tray_popup_utils.h" +#include "ui/compositor/paint_recorder.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/layout/fill_layout.h" #include "ui/views/metadata/metadata_impl_macros.h" namespace ash { +class HoldingSpaceItemChipView::LabelMaskLayerOwner : public ui::LayerDelegate { + public: + LabelMaskLayerOwner() : layer_(ui::LAYER_TEXTURED) { + layer_.set_delegate(this); + layer_.SetFillsBoundsOpaquely(false); + } + + LabelMaskLayerOwner(const LabelMaskLayerOwner&) = delete; + LabelMaskLayerOwner& operator=(const LabelMaskLayerOwner&) = delete; + + ~LabelMaskLayerOwner() override { layer_.set_delegate(nullptr); } + + ui::Layer* layer() { return &layer_; } + + private: + // ui::LayerDelegate: + void OnPaintLayer(const ui::PaintContext& context) override { + const gfx::Size size = layer()->size(); + + views::PaintInfo paint_info = + views::PaintInfo::CreateRootPaintInfo(context, size); + const auto& paint_recording_size = paint_info.paint_recording_size(); + + // Pass the scale factor when constructing `PaintRecorder` so the mask layer + // size is not incorrectly rounded (see https://crbug.com/921274). + ui::PaintRecorder recorder( + context, paint_info.paint_recording_size(), + static_cast<float>(paint_recording_size.width()) / size.width(), + static_cast<float>(paint_recording_size.height()) / size.height(), + /*cache*/ nullptr); + + cc::PaintFlags flags; + flags.setAntiAlias(false); + + gfx::Point gradient_end(size.width() - kHoldingSpacePinIconSize, 0); + gfx::Point gradient_start( + gradient_end.x() - kHoldingSpaceChipLabelMaskGradientWidth, + gradient_end.y()); + flags.setShader(gfx::CreateGradientShader( + gradient_start, gradient_end, SK_ColorBLACK, SK_ColorTRANSPARENT)); + + recorder.canvas()->DrawRect(gfx::Rect(size), flags); + } + + void OnDeviceScaleFactorChanged(float old_device_scale_factor, + float new_device_scale_factor) override {} + + ui::Layer layer_; +}; + HoldingSpaceItemChipView::HoldingSpaceItemChipView( HoldingSpaceItemViewDelegate* delegate, const HoldingSpaceItem* item) @@ -31,14 +84,27 @@ image_ = AddChildView(std::make_unique<RoundedImageView>( kHoldingSpaceChipIconSize / 2, RoundedImageView::Alignment::kLeading)); - label_ = AddChildView(std::make_unique<views::Label>(item->text())); + label_and_pin_button_container_ = + AddChildView(std::make_unique<views::View>()); + layout->SetFlexForView(label_and_pin_button_container_, 1); + + label_and_pin_button_container_->SetLayoutManager( + std::make_unique<views::FillLayout>()); + + label_ = label_and_pin_button_container_->AddChildView( + std::make_unique<views::Label>(item->text())); label_->SetElideBehavior(gfx::ELIDE_MIDDLE); label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); label_->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( AshColorProvider::ContentLayerType::kTextColorPrimary)); TrayPopupUtils::SetLabelFontList( label_, TrayPopupUtils::FontStyle::kDetailedViewLabel); - layout->SetFlexForView(label_, 1); + + label_mask_layer_owner_ = std::make_unique<LabelMaskLayerOwner>(); + + label_->SetPaintToLayer(); + label_->layer()->SetFillsBoundsOpaquely(false); + label_->layer()->SetMaskLayer(label_mask_layer_owner_->layer()); // Subscribe to be notified of changes to `item_`'s image. image_subscription_ = @@ -47,11 +113,34 @@ UpdateImage(); - AddPin(/*parent=*/this); + views::View* pin_button_container = + label_and_pin_button_container_->AddChildView( + std::make_unique<views::View>()); + + auto* pin_layout = + pin_button_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); + pin_layout->set_main_axis_alignment( + views::BoxLayout::MainAxisAlignment::kEnd); + pin_layout->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kCenter); + + AddPin(/*parent=*/pin_button_container); } HoldingSpaceItemChipView::~HoldingSpaceItemChipView() = default; +void HoldingSpaceItemChipView::OnPinVisiblityChanged(bool pin_visible) { + if (label_mask_layer_owner_->layer()->bounds() != + label_and_pin_button_container_->bounds()) { + // Mask layer has the same size as the label container so that the gradient + // ends at the end of the container. + label_mask_layer_owner_->layer()->SetBounds( + label_and_pin_button_container_->bounds()); + } + label_mask_layer_owner_->layer()->SetVisible(pin_visible); +} + void HoldingSpaceItemChipView::UpdateImage() { image_->SetImage( item()->image().image_skia(),
diff --git a/ash/system/holding_space/holding_space_item_chip_view.h b/ash/system/holding_space/holding_space_item_chip_view.h index b5b768a1..858ad6b 100644 --- a/ash/system/holding_space/holding_space_item_chip_view.h +++ b/ash/system/holding_space/holding_space_item_chip_view.h
@@ -35,10 +35,18 @@ ~HoldingSpaceItemChipView() override; private: + class LabelMaskLayerOwner; + + // HoldingSpaceItemView: + void OnPinVisiblityChanged(bool pin_visible) override; + void UpdateImage(); + std::unique_ptr<LabelMaskLayerOwner> label_mask_layer_owner_; + RoundedImageView* image_ = nullptr; views::Label* label_ = nullptr; + views::View* label_and_pin_button_container_ = nullptr; std::unique_ptr<HoldingSpaceImage::Subscription> image_subscription_; };
diff --git a/ash/system/holding_space/holding_space_item_view.cc b/ash/system/holding_space/holding_space_item_view.cc index c2242dc..f4098ca 100644 --- a/ash/system/holding_space/holding_space_item_view.cc +++ b/ash/system/holding_space/holding_space_item_view.cc
@@ -319,6 +319,7 @@ void HoldingSpaceItemView::UpdatePin() { if (!IsMouseHovered()) { pin_->SetVisible(false); + OnPinVisiblityChanged(false); return; } @@ -328,6 +329,7 @@ pin_->SetToggled(!is_item_pinned); pin_->SetVisible(true); + OnPinVisiblityChanged(true); } BEGIN_METADATA(HoldingSpaceItemView, views::InkDropHostView)
diff --git a/ash/system/holding_space/holding_space_item_view.h b/ash/system/holding_space/holding_space_item_view.h index 5ac24d6..edc51ad0 100644 --- a/ash/system/holding_space/holding_space_item_view.h +++ b/ash/system/holding_space/holding_space_item_view.h
@@ -63,6 +63,7 @@ protected: views::ToggleImageButton* AddPin(views::View* parent); + virtual void OnPinVisiblityChanged(bool pin_visible) {} private: void OnPaintFocus(gfx::Canvas* canvas, gfx::Size size);
diff --git a/ash/system/holding_space/holding_space_tray_unittest.cc b/ash/system/holding_space/holding_space_tray_unittest.cc index 0ac097d..4fa67cb 100644 --- a/ash/system/holding_space/holding_space_tray_unittest.cc +++ b/ash/system/holding_space/holding_space_tray_unittest.cc
@@ -1098,6 +1098,224 @@ IsPreviewsFeatureEnabled()); } +// Tests that as screen recording files are added to the model, they show in the +// screen capture container. +TEST_P(HoldingSpaceTrayTest, ScreenCaptureContainerWithScreenRecordingFiles) { + StartSession(); + + test_api()->Show(); + EXPECT_TRUE(test_api()->PinnedFilesContainerShown()); + EXPECT_FALSE(test_api()->RecentFilesContainerShown()); + + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + ASSERT_TRUE(test_api()->GetScreenCaptureViews().empty()); + + // Add a screen recording item and verify recent file container gets shown. + HoldingSpaceItem* item_1 = AddItem(HoldingSpaceItem::Type::kScreenRecording, + base::FilePath("/tmp/fake_1")); + ASSERT_TRUE(item_1->IsFinalized()); + + EXPECT_TRUE(test_api()->PinnedFilesContainerShown()); + EXPECT_TRUE(test_api()->RecentFilesContainerShown()); + + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + EXPECT_TRUE(test_api()->GetDownloadChips().empty()); + ASSERT_EQ(1u, test_api()->GetScreenCaptureViews().size()); + + // Add a screenshot item, and verify it's also shown in the UI in the reverse + // order they were added. + HoldingSpaceItem* item_2 = AddItem(HoldingSpaceItem::Type::kScreenshot, + base::FilePath("/tmp/fake_2")); + + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + EXPECT_TRUE(test_api()->GetDownloadChips().empty()); + std::vector<views::View*> screen_capture_chips = + test_api()->GetScreenCaptureViews(); + ASSERT_EQ(2u, screen_capture_chips.size()); + EXPECT_EQ(item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(item_1->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + + // Remove the first item, and verify the container gets updated. + model()->RemoveItem(item_1->id()); + + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + EXPECT_TRUE(test_api()->GetDownloadChips().empty()); + screen_capture_chips = test_api()->GetScreenCaptureViews(); + ASSERT_EQ(1u, screen_capture_chips.size()); + EXPECT_EQ(item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + + test_api()->Close(); +} + +// Tests that a partially initialized screen recording item shows in the UI in +// the reverse order from added time rather than finalization time. +TEST_P(HoldingSpaceTrayTest, + PartialScreenRecordingItemWithExistingScreenshotItems) { + StartSession(); + test_api()->Show(); + + EXPECT_FALSE(test_api()->RecentFilesContainerShown()); + ASSERT_TRUE(test_api()->GetScreenCaptureViews().empty()); + + // Add partially initialized screen recording item - verify it doesn't get + // shown in the UI yet. + HoldingSpaceItem* screen_recording_item = + AddPartiallyInitializedItem(HoldingSpaceItem::Type::kScreenRecording, + base::FilePath("/tmp/screen_recording")); + EXPECT_FALSE(test_api()->RecentFilesContainerShown()); + EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); + + // Add three screenshot items to fill up the container. + HoldingSpaceItem* screenshot_item_1 = AddItem( + HoldingSpaceItem::Type::kScreenshot, base::FilePath("/tmp/screenshot_1")); + HoldingSpaceItem* screenshot_item_2 = AddItem( + HoldingSpaceItem::Type::kScreenshot, base::FilePath("/tmp/screenshot_2")); + HoldingSpaceItem* screenshot_item_3 = AddItem( + HoldingSpaceItem::Type::kScreenshot, base::FilePath("/tmp/screenshot_3")); + EXPECT_TRUE(test_api()->RecentFilesContainerShown()); + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + EXPECT_TRUE(test_api()->GetDownloadChips().empty()); + std::vector<views::View*> screen_capture_chips = + test_api()->GetScreenCaptureViews(); + ASSERT_EQ(3u, screen_capture_chips.size()); + EXPECT_EQ(screenshot_item_3->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(screenshot_item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + EXPECT_EQ(screenshot_item_1->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[2])->item()->id()); + + // Finalize the screen recording item and verify it is not shown. + model()->FinalizeOrRemoveItem(screen_recording_item->id(), + GURL("filesystem:screen_recording")); + + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + EXPECT_TRUE(test_api()->GetDownloadChips().empty()); + screen_capture_chips = test_api()->GetScreenCaptureViews(); + ASSERT_EQ(3u, screen_capture_chips.size()); + EXPECT_EQ(screenshot_item_3->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(screenshot_item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + EXPECT_EQ(screenshot_item_1->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[2])->item()->id()); + + // Remove one of the fully initialized items, and verify the screen recording + // item that was finalized late is shown. + model()->RemoveItem(screenshot_item_1->id()); + + screen_capture_chips = test_api()->GetScreenCaptureViews(); + ASSERT_EQ(3u, screen_capture_chips.size()); + EXPECT_EQ(screenshot_item_3->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(screenshot_item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + EXPECT_EQ(screen_recording_item->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[2])->item()->id()); + + // Add partially initialized screen recording item - verify it doesn't get + // shown in the UI yet. + HoldingSpaceItem* screen_recording_item_last = + AddPartiallyInitializedItem(HoldingSpaceItem::Type::kScreenRecording, + base::FilePath("/tmp/screen_recording_last")); + screen_capture_chips = test_api()->GetScreenCaptureViews(); + ASSERT_EQ(3u, screen_capture_chips.size()); + EXPECT_EQ(screenshot_item_3->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(screenshot_item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + EXPECT_EQ(screen_recording_item->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[2])->item()->id()); + + // Finalize the screen recording item and verify it is shown first. + model()->FinalizeOrRemoveItem(screen_recording_item_last->id(), + GURL("filesystem:screen_recording")); + + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + EXPECT_TRUE(test_api()->GetDownloadChips().empty()); + screen_capture_chips = test_api()->GetScreenCaptureViews(); + ASSERT_EQ(3u, screen_capture_chips.size()); + EXPECT_EQ(screen_recording_item_last->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(screenshot_item_3->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + EXPECT_EQ(screenshot_item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[2])->item()->id()); + + test_api()->Close(); +} + +// Tests that partially initialized screenshot item shows in the UI in the +// reverse order from added time rather than finalization time. +TEST_P(HoldingSpaceTrayTest, + PartialScreenshotItemWithExistingScreenRecordingItems) { + StartSession(); + test_api()->Show(); + + EXPECT_FALSE(test_api()->RecentFilesContainerShown()); + ASSERT_TRUE(test_api()->GetScreenCaptureViews().empty()); + + // Add partially initialized screenshot item - verify it doesn't get shown + // in the UI yet. + HoldingSpaceItem* screenshot_item = AddPartiallyInitializedItem( + HoldingSpaceItem::Type::kScreenshot, base::FilePath("/tmp/fake_1")); + EXPECT_FALSE(test_api()->RecentFilesContainerShown()); + EXPECT_TRUE(test_api()->GetScreenCaptureViews().empty()); + + // Add three screenshot recording items to fill up the container. + HoldingSpaceItem* screen_recording_item_1 = AddItem( + HoldingSpaceItem::Type::kScreenRecording, base::FilePath("/tmp/fake_2")); + HoldingSpaceItem* screen_recording_item_2 = AddItem( + HoldingSpaceItem::Type::kScreenRecording, base::FilePath("/tmp/fake_3")); + HoldingSpaceItem* screen_recording_item_3 = AddItem( + HoldingSpaceItem::Type::kScreenRecording, base::FilePath("/tmp/fake_4")); + EXPECT_TRUE(test_api()->RecentFilesContainerShown()); + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + EXPECT_TRUE(test_api()->GetDownloadChips().empty()); + std::vector<views::View*> screen_capture_chips = + test_api()->GetScreenCaptureViews(); + ASSERT_EQ(3u, screen_capture_chips.size()); + EXPECT_EQ(screen_recording_item_3->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(screen_recording_item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + EXPECT_EQ(screen_recording_item_1->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[2])->item()->id()); + + // Finalize the screenshot item and verify it is not shown. + model()->FinalizeOrRemoveItem(screenshot_item->id(), + GURL("filesystem:fake_1")); + + EXPECT_TRUE(test_api()->GetPinnedFileChips().empty()); + EXPECT_TRUE(test_api()->GetDownloadChips().empty()); + screen_capture_chips = test_api()->GetScreenCaptureViews(); + ASSERT_EQ(3u, screen_capture_chips.size()); + EXPECT_EQ(screen_recording_item_3->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(screen_recording_item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + EXPECT_EQ(screen_recording_item_1->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[2])->item()->id()); + + // Remove one of the fully initialized items, and verify the partially + // initialized item is not shown. + model()->RemoveItem(screen_recording_item_1->id()); + + screen_capture_chips = test_api()->GetScreenCaptureViews(); + ASSERT_EQ(3u, screen_capture_chips.size()); + EXPECT_EQ(screen_recording_item_3->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[0])->item()->id()); + EXPECT_EQ(screen_recording_item_2->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[1])->item()->id()); + EXPECT_EQ(screenshot_item->id(), + HoldingSpaceItemView::Cast(screen_capture_chips[2])->item()->id()); + + test_api()->Close(); +} + INSTANTIATE_TEST_SUITE_P(All, HoldingSpaceTrayTest, testing::Bool()); } // namespace ash
diff --git a/ash/system/holding_space/recent_files_container.cc b/ash/system/holding_space/recent_files_container.cc index d15237b..417230d 100644 --- a/ash/system/holding_space/recent_files_container.cc +++ b/ash/system/holding_space/recent_files_container.cc
@@ -54,11 +54,20 @@ type == HoldingSpaceItem::Type::kNearbyShare; } +// Returns if an item of the specified `type` belongs in the screen captures +// section. +bool BelongsToScreenCaptureSection(HoldingSpaceItem::Type type) { + return type == HoldingSpaceItem::Type::kScreenshot || + type == HoldingSpaceItem::Type::kScreenRecording; +} + // Returns if items of the specified types belong to the same section. bool BelongToSameSection(HoldingSpaceItem::Type type, HoldingSpaceItem::Type other_type) { - return type == other_type || (BelongsToDownloadsSection(type) && - BelongsToDownloadsSection(other_type)); + return (BelongsToScreenCaptureSection(type) && + BelongsToScreenCaptureSection(other_type)) || + (BelongsToDownloadsSection(type) && + BelongsToDownloadsSection(other_type)); } // DownloadsHeader-------------------------------------------------------------- @@ -165,7 +174,7 @@ bool due_to_finalization) { DCHECK(item->IsFinalized()); - if (item->type() != HoldingSpaceItem::Type::kScreenshot && + if (!BelongsToScreenCaptureSection(item->type()) && !BelongsToDownloadsSection(item->type())) { return; } @@ -185,7 +194,7 @@ } } - if (item->type() == HoldingSpaceItem::Type::kScreenshot) + if (BelongsToScreenCaptureSection(item->type())) AddHoldingSpaceScreenCaptureView(item, index); else if (BelongsToDownloadsSection(item->type())) AddHoldingSpaceDownloadView(item, index); @@ -199,7 +208,7 @@ void RecentFilesContainer::RemoveHoldingSpaceItemView( const HoldingSpaceItem* item) { - if (item->type() == HoldingSpaceItem::Type::kScreenshot) + if (BelongsToScreenCaptureSection(item->type())) RemoveHoldingSpaceScreenCaptureView(item); else if (BelongsToDownloadsSection(item->type())) RemoveHoldingSpaceDownloadView(item); @@ -208,7 +217,7 @@ void RecentFilesContainer::AddHoldingSpaceScreenCaptureView( const HoldingSpaceItem* item, size_t index) { - DCHECK_EQ(item->type(), HoldingSpaceItem::Type::kScreenshot); + DCHECK(BelongsToScreenCaptureSection(item->type())); DCHECK(!base::Contains(views_by_item_id_, item->id())); if (index >= kMaxScreenCaptures) @@ -231,7 +240,7 @@ void RecentFilesContainer::RemoveHoldingSpaceScreenCaptureView( const HoldingSpaceItem* item) { - DCHECK_EQ(item->type(), HoldingSpaceItem::Type::kScreenshot); + DCHECK(BelongsToScreenCaptureSection(item->type())); auto it = views_by_item_id_.find(item->id()); if (it == views_by_item_id_.end()) @@ -250,7 +259,7 @@ for (const auto& candidate : base::Reversed(HoldingSpaceController::Get()->model()->items())) { if (candidate->IsFinalized() && - candidate->type() == HoldingSpaceItem::Type::kScreenshot && + BelongsToScreenCaptureSection(item->type()) && !base::Contains(views_by_item_id_, candidate->id())) { views_by_item_id_[candidate->id()] = screen_captures_container_->AddChildView(
diff --git a/ash/system/tray/tray_popup_utils.cc b/ash/system/tray/tray_popup_utils.cc index 88d8f14..9640a4a 100644 --- a/ash/system/tray/tray_popup_utils.cc +++ b/ash/system/tray/tray_popup_utils.cc
@@ -219,15 +219,6 @@ views::ToggleButton* TrayPopupUtils::CreateToggleButton( views::Button::PressedCallback callback, int accessible_name_id) { - constexpr SkColor kTrackAlpha = 0x66; - auto GetColor = [](bool is_on, SkAlpha alpha = SK_AlphaOPAQUE) { - AshColorProvider::ContentLayerType type = - is_on ? AshColorProvider::ContentLayerType::kIconColorProminent - : AshColorProvider::ContentLayerType::kTextColorPrimary; - - return SkColorSetA(AshColorProvider::Get()->GetContentLayerColor(type), - alpha); - }; views::ToggleButton* toggle = new views::ToggleButton(std::move(callback)); const gfx::Size toggle_size(toggle->GetPreferredSize()); const int vertical_padding = (kMenuButtonSize - toggle_size.height()) / 2; @@ -236,10 +227,7 @@ toggle->SetBorder(views::CreateEmptyBorder( gfx::Insets(vertical_padding, horizontal_padding))); toggle->SetAccessibleName(l10n_util::GetStringUTF16(accessible_name_id)); - toggle->SetThumbOnColor(GetColor(true)); - toggle->SetThumbOffColor(GetColor(false)); - toggle->SetTrackOnColor(GetColor(true, kTrackAlpha)); - toggle->SetTrackOffColor(GetColor(false, kTrackAlpha)); + UpdateToggleButtonColors(toggle); return toggle; } @@ -367,6 +355,18 @@ : HoverHighlightView::AccessibilityState::UNCHECKED_CHECKBOX); } +void TrayPopupUtils::UpdateToggleButtonColors(views::ToggleButton* toggle) { + auto* ash_color_provider = AshColorProvider::Get(); + toggle->SetThumbOnColor(ash_color_provider->GetContentLayerColor( + AshColorProvider::ContentLayerType::kSwitchKnobColorActive)); + toggle->SetThumbOffColor(ash_color_provider->GetContentLayerColor( + AshColorProvider::ContentLayerType::kSwitchKnobColorInactive)); + toggle->SetTrackOnColor(ash_color_provider->GetContentLayerColor( + AshColorProvider::ContentLayerType::kSwitchTrackColorActive)); + toggle->SetTrackOffColor(ash_color_provider->GetContentLayerColor( + AshColorProvider::ContentLayerType::kSwitchTrackColorInactive)); +} + void TrayPopupUtils::SetLabelFontList(views::Label* label, FontStyle style) { label->SetAutoColorReadabilityEnabled(false); const gfx::FontList& base_font_list = views::Label::GetDefaultFontList();
diff --git a/ash/system/tray/tray_popup_utils.h b/ash/system/tray/tray_popup_utils.h index d6326066..8f8d3c79 100644 --- a/ash/system/tray/tray_popup_utils.h +++ b/ash/system/tray/tray_popup_utils.h
@@ -201,6 +201,9 @@ static void UpdateCheckMarkVisibility(HoverHighlightView* container, bool visible); + // Updates the toggle button colors based on the current color mode. + static void UpdateToggleButtonColors(views::ToggleButton* toggle); + // Sets the font list for |label| based on |style|. static void SetLabelFontList(views::Label* label, FontStyle style);
diff --git a/ash/wm/desks/desk_animation_base.cc b/ash/wm/desks/desk_animation_base.cc index f99eb82..b0ba911 100644 --- a/ash/wm/desks/desk_animation_base.cc +++ b/ash/wm/desks/desk_animation_base.cc
@@ -33,10 +33,7 @@ for (auto& observer : controller_->observers_) observer.OnDeskSwitchAnimationLaunching(); - // The throughput tracker measures the animation when the user lifts their - // fingers off the trackpad, which is done in EndSwipeAnimation. - if (!is_continuous_gesture_animation_) - throughput_tracker_.Start(GetReportCallback()); + throughput_tracker_.Start(GetReportCallback()); // This step makes sure that the containers of the target desk are shown at // the beginning of the animation (but not actually visible to the user yet,
diff --git a/ash/wm/desks/desk_animation_impl.cc b/ash/wm/desks/desk_animation_impl.cc index 75d82655a..dc02657 100644 --- a/ash/wm/desks/desk_animation_impl.cc +++ b/ash/wm/desks/desk_animation_impl.cc
@@ -83,11 +83,6 @@ if (source != switch_source_) return false; - // Do not log any EndSwipeAnimation smoothness metrics if the animation has - // been canceled midway by an Replace call. - if (is_continuous_gesture_animation_) - throughput_tracker_.Cancel(); - // If any of the animators are still taking either screenshot, do not replace // the animation. for (const auto& animator : desk_switch_animators_) { @@ -140,6 +135,10 @@ if (!is_continuous_gesture_animation_) return false; + // Do not log any EndSwipeAnimation smoothness metrics if the animation has + // been canceled midway by an UpdateSwipeAnimation call. + throughput_tracker_.Cancel(); + presentation_time_recorder_->RequestNext(); // List of animators that need a screenshot. It should be either empty or
diff --git a/ash/wm/gestures/wm_gesture_handler_unittest.cc b/ash/wm/gestures/wm_gesture_handler_unittest.cc index 826b2073..83a2290 100644 --- a/ash/wm/gestures/wm_gesture_handler_unittest.cc +++ b/ash/wm/gestures/wm_gesture_handler_unittest.cc
@@ -81,8 +81,6 @@ class WmGestureHandlerTest : public AshTestBase { public: WmGestureHandlerTest() = default; - WmGestureHandlerTest(const WmGestureHandlerTest&) = delete; - WmGestureHandlerTest& operator=(const WmGestureHandlerTest&) = delete; ~WmGestureHandlerTest() override = default; void Scroll(float x_offset, float y_offset, int fingers) { @@ -92,16 +90,11 @@ } void ScrollToSwitchDesks(bool scroll_left) { - // Theres no animation when scrolling with enhanced desk animations, so no - // need to wait. - auto waiter = features::IsEnhancedDeskAnimations() - ? nullptr - : std::make_unique<DeskSwitchAnimationWaiter>(); + DeskSwitchAnimationWaiter waiter; const float x_offset = (scroll_left ? -1 : 1) * WmGestureHandler::kHorizontalThresholdDp; Scroll(x_offset, 0, kNumFingersForDesksSwitch); - if (waiter) - waiter->Wait(); + waiter.Wait(); } void MouseWheelScroll(int delta_x, int delta_y, int num_of_times) { @@ -109,6 +102,9 @@ for (int i = 0; i < num_of_times; i++) generator->MoveMouseWheel(delta_x, delta_y); } + + private: + DISALLOW_COPY_AND_ASSIGN(WmGestureHandlerTest); }; // Tests a three fingers upwards scroll gesture to enter and a scroll down to @@ -283,11 +279,6 @@ // Tests that a large scroll only moves to the next desk. TEST_F(DesksGestureHandlerTest, NoDoubleDeskChange) { - // Enhanced desk animations supports switching multiple desks with large - // enough scrolls. - if (features::IsEnhancedDeskAnimations()) - return; - auto* desk_controller = DesksController::Get(); desk_controller->NewDesk(DesksCreationRemovalSource::kButton); desk_controller->NewDesk(DesksCreationRemovalSource::kButton);
diff --git a/base/allocator/OWNERS b/base/allocator/OWNERS index aeb9549..91c97ca9 100644 --- a/base/allocator/OWNERS +++ b/base/allocator/OWNERS
@@ -1,2 +1,3 @@ +lizeb@chromium.org primiano@chromium.org wfh@chromium.org
diff --git a/base/allocator/allocator_shim.h b/base/allocator/allocator_shim.h index 9c819a8..1646ae46 100644 --- a/base/allocator/allocator_shim.h +++ b/base/allocator/allocator_shim.h
@@ -152,6 +152,10 @@ #endif // defined(OS_APPLE) #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) +BASE_EXPORT void EnablePartitionAllocMemoryReclaimer(); +#endif + +#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) BASE_EXPORT void EnablePCScanIfNeeded(); #endif
diff --git a/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc b/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc index 2e37766..a296ab9 100644 --- a/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc +++ b/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc
@@ -5,6 +5,7 @@ #include "base/allocator/allocator_shim_default_dispatch_to_partition_alloc.h" #include "base/allocator/allocator_shim_internals.h" +#include "base/allocator/partition_allocator/memory_reclaimer.h" #include "base/allocator/partition_allocator/partition_alloc.h" #include "base/allocator/partition_allocator/partition_alloc_constants.h" #include "base/allocator/partition_allocator/partition_alloc_features.h" @@ -225,6 +226,17 @@ namespace base { namespace allocator { +void EnablePartitionAllocMemoryReclaimer() { + // Allocator() and AlignedAllocator() do not register their PartitionRoots to + // the memory reclaimer because the memory reclaimer allocates memory. Thus, + // the registration to the memory reclaimer should be done sometime later. + // This function will be called sometime appropriate after PartitionRoots are + // initialized. + PartitionAllocMemoryReclaimer::Instance()->RegisterPartition(Allocator()); + PartitionAllocMemoryReclaimer::Instance()->RegisterPartition( + AlignedAllocator()); +} + void EnablePCScanIfNeeded() { if (!features::IsPartitionAllocPCScanEnabled()) return;
diff --git a/base/allocator/partition_allocator/OWNERS b/base/allocator/partition_allocator/OWNERS index 761f69a..54db26c 100644 --- a/base/allocator/partition_allocator/OWNERS +++ b/base/allocator/partition_allocator/OWNERS
@@ -3,4 +3,3 @@ haraken@chromium.org lizeb@chromium.org palmer@chromium.org -tsepez@chromium.org
diff --git a/base/allocator/partition_allocator/partition_alloc_features.cc b/base/allocator/partition_allocator/partition_alloc_features.cc index 7176685..68a3fd2 100644 --- a/base/allocator/partition_allocator/partition_alloc_features.cc +++ b/base/allocator/partition_allocator/partition_alloc_features.cc
@@ -13,11 +13,11 @@ // If enabled, PartitionAllocator reserves an address space(named, giga cage) // initially and uses a part of the address space for each allocation. const Feature kPartitionAllocGigaCage{"PartitionAllocGigaCage", - FEATURE_DISABLED_BY_DEFAULT}; + FEATURE_ENABLED_BY_DEFAULT}; #else // If enabled, PartitionAllocator remembers allocated address space. const Feature kPartitionAllocGigaCage{"PartitionAllocGigaCage32bit", - FEATURE_DISABLED_BY_DEFAULT}; + FEATURE_ENABLED_BY_DEFAULT}; #endif // If enabled, PCScan is turned on by default for all partitions that don't
diff --git a/base/ios/scoped_critical_action.mm b/base/ios/scoped_critical_action.mm index 51f9639c..fcee68a 100644 --- a/base/ios/scoped_critical_action.mm +++ b/base/ios/scoped_critical_action.mm
@@ -46,12 +46,6 @@ return; } - NSTimeInterval time = application.backgroundTimeRemaining; - if (time != DBL_MAX && time > 0) { - UMA_HISTOGRAM_MEDIUM_TIMES("IOS.CriticalActionBackgroundTimeRemaining", - base::TimeDelta::FromSeconds(time)); - } - AutoLock lock_scope(core->background_task_id_lock_); NSString* task_string = !task_name.empty() ? base::SysUTF8ToNSString(task_name) : nil;
diff --git a/base/scoped_multi_source_observation.h b/base/scoped_multi_source_observation.h index 14e7d1d4..19c7010 100644 --- a/base/scoped_multi_source_observation.h +++ b/base/scoped_multi_source_observation.h
@@ -86,6 +86,7 @@ // Returns true if |source| is being observed. bool IsObservingSource(Source* source) const { + DCHECK(source); return base::Contains(sources_, source); }
diff --git a/base/scoped_observation.h b/base/scoped_observation.h index 5a42193..293fa039 100644 --- a/base/scoped_observation.h +++ b/base/scoped_observation.h
@@ -75,7 +75,10 @@ bool IsObserving() const { return source_ != nullptr; } // Returns true if |source| is being observed. - bool IsObservingSource(Source* source) const { return source_ == source; } + bool IsObservingSource(Source* source) const { + DCHECK(source); + return source_ == source; + } private: Observer* const observer_;
diff --git a/build/android/pylib/local/machine/local_machine_junit_test_run.py b/build/android/pylib/local/machine/local_machine_junit_test_run.py index 4f3b715..422ab8b 100644 --- a/build/android/pylib/local/machine/local_machine_junit_test_run.py +++ b/build/android/pylib/local/machine/local_machine_junit_test_run.py
@@ -48,7 +48,7 @@ # It can actually take longer to run if you shard too much, especially on # smaller suites. Locally media_base_junit_tests takes 4.3 sec with 1 shard, # and 6 sec with 2 or more shards. -_MIN_CLASSES_PER_SHARD = 4 +_MIN_CLASSES_PER_SHARD = 8 class LocalMachineJunitTestRun(test_run.TestRun):
diff --git a/build/android/pylib/local/machine/local_machine_junit_test_run_test.py b/build/android/pylib/local/machine/local_machine_junit_test_run_test.py index de4300d..b193e2e0 100755 --- a/build/android/pylib/local/machine/local_machine_junit_test_run_test.py +++ b/build/android/pylib/local/machine/local_machine_junit_test_run_test.py
@@ -58,7 +58,7 @@ self.assertEquals(local_machine_junit_test_run._MAX_SHARDS, shards) # Tests using min_class per shards. - test_classes = [1] * 10 + test_classes = [1] * 20 test_shards = 8 shards = local_machine_junit_test_run.ChooseNumOfShards( test_classes, test_shards)
diff --git a/build/apple/tweak_info_plist.py b/build/apple/tweak_info_plist.py index 6dde0c482..8bbc46a 100755 --- a/build/apple/tweak_info_plist.py +++ b/build/apple/tweak_info_plist.py
@@ -301,10 +301,14 @@ # Read the plist into its parsed format. Convert the file to 'xml1' as # plistlib only supports that format in Python 2.7. with tempfile.NamedTemporaryFile() as temp_info_plist: - retcode = _ConvertPlist(options.plist_path, temp_info_plist.name, 'xml1') - if retcode != 0: - return retcode - plist = plistlib.readPlist(temp_info_plist.name) + if sys.version_info.major == 2: + retcode = _ConvertPlist(options.plist_path, temp_info_plist.name, 'xml1') + if retcode != 0: + return retcode + plist = plistlib.readPlist(temp_info_plist.name) + else: + with open(options.plist_path, 'rb') as f: + plist = plistlib.load(f) # Convert overrides. overrides = {} @@ -398,7 +402,11 @@ # Now that all keys have been mutated, rewrite the file. with tempfile.NamedTemporaryFile() as temp_info_plist: - plistlib.writePlist(plist, temp_info_plist.name) + if sys.version_info.major == 2: + plistlib.writePlist(plist, temp_info_plist.name) + else: + with open(temp_info_plist.name, 'wb') as f: + plist = plistlib.dump(plist, f) # Convert Info.plist to the format requested by the --format flag. Any # format would work on Mac but iOS requires specific format.
diff --git a/build/config/ios/codesign.py b/build/config/ios/codesign.py index 97772c2..ac2cfdb 100644 --- a/build/config/ios/codesign.py +++ b/build/config/ios/codesign.py
@@ -58,9 +58,13 @@ Returns: The content of the property list file as a python object. """ - return ReadPlistFromString( - subprocess.check_output( - ['xcrun', 'plutil', '-convert', 'xml1', '-o', '-', plist_path])) + if sys.version_info.major == 2: + return plistlib.readPlistFromString( + subprocess.check_output( + ['xcrun', 'plutil', '-convert', 'xml1', '-o', '-', plist_path])) + else: + with open(plist_path) as fp: + return plistlib.load(fp) def CreateSymlink(value, location): @@ -262,7 +266,11 @@ self._data[key] = value def WriteTo(self, target_path): - plistlib.writePlist(self._data, target_path) + with open(target_path, 'wb') as fp: + if sys.version_info.major == 2: + plistlib.writePlist(self._data, fp) + else: + plistlib.dump(self._data, fp) def FindProvisioningProfile(bundle_identifier, required): @@ -317,9 +325,11 @@ def CodeSignBundle(bundle_path, identity, extra_args): - process = subprocess.Popen(['xcrun', 'codesign', '--force', '--sign', - identity, '--timestamp=none'] + list(extra_args) + [bundle_path], - stderr=subprocess.PIPE) + process = subprocess.Popen( + ['xcrun', 'codesign', '--force', '--sign', identity, '--timestamp=none'] + + list(extra_args) + [bundle_path], + stderr=subprocess.PIPE, + universal_newlines=True) _, stderr = process.communicate() if process.returncode: sys.stderr.write(stderr)
diff --git a/build/config/mac/plist_util.py b/build/config/mac/plist_util.py index d89b4188..cf9b449a 100644 --- a/build/config/mac/plist_util.py +++ b/build/config/mac/plist_util.py
@@ -94,13 +94,17 @@ def LoadPList(path): """Loads Plist at |path| and returns it as a dictionary.""" - fd, name = tempfile.mkstemp() - try: - subprocess.check_call(['plutil', '-convert', 'xml1', '-o', name, path]) - with os.fdopen(fd, 'rb') as f: - return plistlib.readPlist(f) - finally: - os.unlink(name) + if sys.version_info.major == 2: + fd, name = tempfile.mkstemp() + try: + subprocess.check_call(['plutil', '-convert', 'xml1', '-o', name, path]) + with os.fdopen(fd, 'rb') as f: + return plistlib.readPlist(f) + finally: + os.unlink(name) + else: + with open(path, 'rb') as f: + return plistlib.load(f) def SavePList(path, format, data): @@ -114,7 +118,10 @@ if os.path.exists(path): os.unlink(path) with os.fdopen(fd, 'wb') as f: - plistlib.writePlist(data, f) + if sys.version_info.major == 2: + plistlib.writePlist(data, f) + else: + plistlib.dump(data, f) subprocess.check_call(['plutil', '-convert', format, '-o', path, name]) finally: os.unlink(name)
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 495d4d0..1f82cdd 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20201118.1.1 +0.20201118.2.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 495d4d0..3a12db5 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20201118.1.1 +0.20201118.3.1
diff --git a/cc/metrics/dropped_frame_counter.cc b/cc/metrics/dropped_frame_counter.cc index 316d9920..f941a57 100644 --- a/cc/metrics/dropped_frame_counter.cc +++ b/cc/metrics/dropped_frame_counter.cc
@@ -4,7 +4,11 @@ #include "cc/metrics/dropped_frame_counter.h" +#include <algorithm> + #include "base/bind.h" +#include "base/metrics/histogram.h" +#include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "cc/metrics/frame_sorter.h" #include "cc/metrics/total_frame_counter.h" @@ -67,11 +71,15 @@ total_counter_->ComputeTotalVisibleFrames(base::TimeTicks::Now()); TRACE_EVENT2("cc,benchmark", "SmoothnessDroppedFrame", "total", total_frames, "smoothness", total_smoothness_dropped_); + UMA_HISTOGRAM_PERCENTAGE( + "Graphics.Smoothness.MaxPercentDroppedFrames_1sWindow", + sliding_window_max_percent_dropped_); if (ukm_smoothness_data_ && total_frames > 0) { UkmSmoothnessData smoothness_data; smoothness_data.avg_smoothness = static_cast<double>(total_smoothness_dropped_) * 100 / total_frames; + smoothness_data.worst_smoothness = sliding_window_max_percent_dropped_; ukm_smoothness_data_->seq_lock.WriteBegin(); device::OneWriterSeqLock::AtomicWriterMemcpy(&ukm_smoothness_data_->data, @@ -91,14 +99,46 @@ total_partial_ = 0; total_dropped_ = 0; total_smoothness_dropped_ = 0; + sliding_window_max_percent_dropped_ = 0; + dropped_frame_count_in_window_ = 0; fcp_received_ = false; + sliding_window_ = {}; ring_buffer_.Clear(); frame_sorter_.Reset(); } +base::TimeDelta DroppedFrameCounter::ComputeCurrentWindowSize() const { + DCHECK_GT(sliding_window_.size(), 0u); + return sliding_window_.back().first.frame_time + + sliding_window_.back().first.interval - + sliding_window_.front().first.frame_time; +} + void DroppedFrameCounter::NotifyFrameResult(const viz::BeginFrameArgs& args, bool is_dropped) { - // TODO(crbug.com/1115141) The implementation of smoothness metrics. + sliding_window_.push({args, is_dropped}); + if (is_dropped) + dropped_frame_count_in_window_++; + + if (ComputeCurrentWindowSize() < kSlidingWindowInterval) + return; + + DCHECK_GE(dropped_frame_count_in_window_, 0u); + DCHECK_GE(sliding_window_.size(), dropped_frame_count_in_window_); + DCHECK_GT(kSlidingWindowInterval, args.interval); + // args.interval being lower than the window interval guarantees that queue + // would not be empty at any point in the loop below. + + double percent_dropped_frame = + (dropped_frame_count_in_window_ * 100.0) / sliding_window_.size(); + sliding_window_max_percent_dropped_ = + fmax(sliding_window_max_percent_dropped_, percent_dropped_frame); + + while (ComputeCurrentWindowSize() >= kSlidingWindowInterval) { + if (sliding_window_.front().second) // If frame is dropped. + dropped_frame_count_in_window_--; + sliding_window_.pop(); + } } void DroppedFrameCounter::OnFcpReceived() {
diff --git a/cc/metrics/dropped_frame_counter.h b/cc/metrics/dropped_frame_counter.h index 17e9386a..1fa5e318 100644 --- a/cc/metrics/dropped_frame_counter.h +++ b/cc/metrics/dropped_frame_counter.h
@@ -6,6 +6,8 @@ #define CC_METRICS_DROPPED_FRAME_COUNTER_H_ #include <stddef.h> +#include <queue> +#include <utility> #include "base/containers/ring_buffer.h" #include "cc/cc_export.h" @@ -64,8 +66,18 @@ total_counter_ = total_counter; } + double sliding_window_max_percent_dropped() const { + return sliding_window_max_percent_dropped_; + } + private: void NotifyFrameResult(const viz::BeginFrameArgs& args, bool is_dropped); + base::TimeDelta ComputeCurrentWindowSize() const; + + const base::TimeDelta kSlidingWindowInterval = + base::TimeDelta::FromSeconds(1); + std::queue<std::pair<const viz::BeginFrameArgs, bool>> sliding_window_; + uint32_t dropped_frame_count_in_window_ = 0; RingBufferType ring_buffer_; size_t total_frames_ = 0; @@ -73,6 +85,7 @@ size_t total_dropped_ = 0; size_t total_smoothness_dropped_ = 0; bool fcp_received_ = false; + double sliding_window_max_percent_dropped_ = 0; UkmSmoothnessDataShared* ukm_smoothness_data_ = nullptr; FrameSorter frame_sorter_;
diff --git a/cc/metrics/dropped_frame_counter_unittest.cc b/cc/metrics/dropped_frame_counter_unittest.cc index 99d5c35..7915531 100644 --- a/cc/metrics/dropped_frame_counter_unittest.cc +++ b/cc/metrics/dropped_frame_counter_unittest.cc
@@ -4,8 +4,11 @@ #include "cc/metrics/dropped_frame_counter.h" +#include <vector> + #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" +#include "base/time/time.h" #include "cc/animation/animation_host.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_picture_layer.h" @@ -247,5 +250,98 @@ // TODO(crbug.com/1115376) Disabled for flakiness. // MULTI_THREAD_TEST_F(DroppedFrameCounterMainDropsSmoothnessTest); +class DroppedFrameCounterTest : public testing::Test { + public: + DroppedFrameCounterTest() { + dropped_frame_counter_.set_total_counter(&total_frame_counter_); + } + ~DroppedFrameCounterTest() override = default; + + // For each boolean in frame_states produces a frame + void SimulateFrameSequence(std::vector<bool> frame_states, int repeat) { + for (int i = 0; i < repeat; i++) { + for (auto is_dropped : frame_states) { + viz::BeginFrameArgs args_ = SimulateBeginFrameArgs(); + dropped_frame_counter_.OnBeginFrame(args_); + dropped_frame_counter_.OnEndFrame(args_, is_dropped); + sequence_number_++; + frame_time_ += interval_; + } + } + } + + void AdvancetimeByIntervals(int interval_count) { + frame_time_ += interval_ * interval_count; + } + + double MaxPercentDroppedFrame() { + return dropped_frame_counter_.sliding_window_max_percent_dropped(); + } + + private: + DroppedFrameCounter dropped_frame_counter_; + TotalFrameCounter total_frame_counter_; + uint64_t sequence_number_ = 1; + uint64_t source_id_ = 1; + const base::TickClock* tick_clock_ = base::DefaultTickClock::GetInstance(); + base::TimeTicks frame_time_ = tick_clock_->NowTicks(); + const base::TimeDelta interval_ = + base::TimeDelta::FromMicroseconds(16667); // 16.667 ms + + viz::BeginFrameArgs SimulateBeginFrameArgs() { + viz::BeginFrameId current_id_(source_id_, sequence_number_); + viz::BeginFrameArgs args = viz::BeginFrameArgs(); + args.frame_id = current_id_; + args.frame_time = frame_time_; + args.interval = interval_; + return args; + } +}; + +TEST_F(DroppedFrameCounterTest, SimplePattern1) { + // 2 out of every 3 frames are dropped (In total 80 frames out of 120). + SimulateFrameSequence({true, true, true, false, true, false}, 20); + EXPECT_EQ(MaxPercentDroppedFrame(), 200.0 / 3); +} + +TEST_F(DroppedFrameCounterTest, SimplePattern2) { + // 1 out of every 5 frames are dropped (In total 24 frames out of 120). + SimulateFrameSequence({false, false, false, false, true}, 24); + EXPECT_EQ(MaxPercentDroppedFrame(), 20.0); +} + +TEST_F(DroppedFrameCounterTest, MaxPercentDroppedChanges) { + // First 60 frames have 20% dropped. + SimulateFrameSequence({false, false, false, false, true}, 12); + EXPECT_EQ(MaxPercentDroppedFrame(), 20.0); + + // 30 new frames are added that have 18 dropped frames. + // and the 30 frame before that had 6 dropped frames. + // So in total in the window has 24 frames dropped out of 60 frames. + SimulateFrameSequence({false, false, true, true, true}, 6); + EXPECT_EQ(MaxPercentDroppedFrame(), 40.0); + + // 30 new frames are added that have 24 dropped frames. + // and the 30 frame before that had 18 dropped frames. + // So in total in the window has 42 frames dropped out of 60 frames. + SimulateFrameSequence({false, true, true, true, true}, 6); + EXPECT_EQ(MaxPercentDroppedFrame(), 70.0); +} + +TEST_F(DroppedFrameCounterTest, MaxPercentDroppedWithIdleFrames) { + // First 20 frames have 4 frames dropped (20%). + SimulateFrameSequence({false, false, false, false, true}, 4); + + // Then no frames are added for 20 intervals. + AdvancetimeByIntervals(20); + + // Then 20 frames have 16 frames dropped (60%). + SimulateFrameSequence({false, false, true, true, true}, 4); + + // So in total, there are 40 frames in the 1 second window with 16 dropped + // frames (40% in total). + EXPECT_EQ(MaxPercentDroppedFrame(), 40.0); +} + } // namespace } // namespace cc
diff --git a/chrome/VERSION b/chrome/VERSION index 209b936..fa2d9b8 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=89 MINOR=0 -BUILD=4330 +BUILD=4331 PATCH=0
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 174acdd..bf1c0f82 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -316,12 +316,9 @@ "java/src/org/chromium/chrome/browser/compositor/layouts/content/TitleBitmapFactory.java", "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/AreaGestureEventFilter.java", "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/BlackHoleEventFilter.java", - "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/EdgeSwipeHandler.java", - "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/EmptyEdgeSwipeHandler.java", "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/GestureEventFilter.java", "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/GestureHandler.java", "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/OverlayPanelEventFilter.java", - "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ScrollDirection.java", "java/src/org/chromium/chrome/browser/compositor/layouts/phone/SimpleAnimationLayout.java", "java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java", "java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java", @@ -413,7 +410,6 @@ "java/src/org/chromium/chrome/browser/contextualsearch/ShortTextRunSuppression.java", "java/src/org/chromium/chrome/browser/contextualsearch/SimpleSearchTermResolver.java", "java/src/org/chromium/chrome/browser/contextualsearch/SmallTextSuppression.java", - "java/src/org/chromium/chrome/browser/contextualsearch/SwipeRecognizer.java", "java/src/org/chromium/chrome/browser/contextualsearch/TapDurationSuppression.java", "java/src/org/chromium/chrome/browser/contextualsearch/TapFarFromPreviousSuppression.java", "java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java", @@ -1216,6 +1212,7 @@ "java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java", "java/src/org/chromium/chrome/browser/query_tiles/TileProviderFactory.java", "java/src/org/chromium/chrome/browser/rappor/RapporServiceBridge.java", + "java/src/org/chromium/chrome/browser/read_later/ReadLaterIPHController.java", "java/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationController.java", "java/src/org/chromium/chrome/browser/resources/ResourceMapper.java", "java/src/org/chromium/chrome/browser/rlz/RevenueStats.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 86b5287..0e233dd 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -483,6 +483,7 @@ "javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionToOmniboxTest.java", "javatests/src/org/chromium/chrome/browser/query_tiles/TileMatchers.java", "javatests/src/org/chromium/chrome/browser/query_tiles/ViewActions.java", + "javatests/src/org/chromium/chrome/browser/read_later/ReadLaterIphTest.java", "javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java", "javatests/src/org/chromium/chrome/browser/search_engines/settings/SearchEngineSettingsTest.java",
diff --git a/chrome/android/expectations/monochrome_public_bundle.arm64.libs_and_assets.expected b/chrome/android/expectations/monochrome_public_bundle.arm64.libs_and_assets.expected index 28ace4d..f54180a 100644 --- a/chrome/android/expectations/monochrome_public_bundle.arm64.libs_and_assets.expected +++ b/chrome/android/expectations/monochrome_public_bundle.arm64.libs_and_assets.expected
@@ -3,6 +3,10 @@ apk_path=lib/armeabi-v7a/libarcore_sdk_c.so, compress=False, alignment=4096 apk_path=lib/armeabi-v7a/libcrashpad_handler_trampoline.so, compress=False, alignment=4096 apk_path=lib/armeabi-v7a/libmonochrome.so, compress=False, alignment=4096 +apk_path=lib/armeabi-v7a/libmonochrome_cablev2_authenticator_partition.so, compress=False, alignment=4096 +apk_path=lib/armeabi-v7a/libmonochrome_stack_unwinder_partition.so, compress=False, alignment=4096 +apk_path=lib/armeabi-v7a/libmonochrome_test_dummy_partition.so, compress=False, alignment=4096 +apk_path=lib/armeabi-v7a/libmonochrome_vr_partition.so, compress=False, alignment=4096 apk_path=assets/chrome_100_percent.pak, compress=False, alignment=4 apk_path=assets/icudtl.dat, compress=False, alignment=4 apk_path=assets/locales/af.pak, compress=False, alignment=4
diff --git a/chrome/android/expectations/trichrome_chrome_bundle.arm64.libs_and_assets.expected b/chrome/android/expectations/trichrome_chrome_bundle.arm64.libs_and_assets.expected index e9c8441..a771646 100644 --- a/chrome/android/expectations/trichrome_chrome_bundle.arm64.libs_and_assets.expected +++ b/chrome/android/expectations/trichrome_chrome_bundle.arm64.libs_and_assets.expected
@@ -1,5 +1,9 @@ apk_path=lib/armeabi-v7a/libarcore_sdk_c.so, compress=False, alignment=4096 apk_path=lib/armeabi-v7a/libchromium_android_linker.so, compress=False, alignment=4096 +apk_path=lib/armeabi-v7a/libmonochrome_cablev2_authenticator_partition.so, compress=False, alignment=4096 +apk_path=lib/armeabi-v7a/libmonochrome_stack_unwinder_partition.so, compress=False, alignment=4096 +apk_path=lib/armeabi-v7a/libmonochrome_test_dummy_partition.so, compress=False, alignment=4096 +apk_path=lib/armeabi-v7a/libmonochrome_vr_partition.so, compress=False, alignment=4096 apk_path=assets/chrome_100_percent.pak, compress=False, alignment=4 apk_path=assets/locales/af.pak, compress=False, alignment=4 apk_path=assets/locales/am.pak, compress=False, alignment=4
diff --git a/chrome/android/java/res/layout/find_in_page.xml b/chrome/android/java/res/layout/find_in_page.xml index dad01d7..d278daa 100644 --- a/chrome/android/java/res/layout/find_in_page.xml +++ b/chrome/android/java/res/layout/find_in_page.xml
@@ -19,6 +19,7 @@ android:layout_height="match_parent" android:layout_gravity="center_vertical" android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" android:background="@null" android:hint="@string/hint_find_in_page" android:imeOptions="actionSearch|flagNoExtractUi" @@ -28,7 +29,6 @@ android:id="@+id/find_status" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="12dp" android:layout_marginEnd="16dp" android:background="@null" android:singleLine="true"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index c8b1a6a..3ff9001 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1656,6 +1656,7 @@ Supplier<TabDelegateFactory> tabDelegateFactorySupplier = () -> { return new TabbedModeTabDelegateFactory(this, getAppBrowserControlsVisibilityDelegate(), getShareDelegateSupplier(), mEphemeralTabCoordinatorSupplier, + ((TabbedRootUiCoordinator) mRootUiCoordinator)::onContextMenuCopyLink, mRootUiCoordinator.getBottomSheetController()); };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java index 882fc59..ebbe03f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java
@@ -34,6 +34,7 @@ private final BrowserControlsVisibilityDelegate mAppBrowserControlsVisibilityDelegate; private final Supplier<ShareDelegate> mShareDelegateSupplier; private final Supplier<EphemeralTabCoordinator> mEphemeralTabCoordinatorSupplier; + private final Runnable mContextMenuCopyLinkObserver; private final BottomSheetController mBottomSheetController; private NativePageFactory mNativePageFactory; @@ -41,11 +42,12 @@ BrowserControlsVisibilityDelegate appBrowserControlsVisibilityDelegate, Supplier<ShareDelegate> shareDelegateSupplier, Supplier<EphemeralTabCoordinator> ephemeralTabCoordinatorSupplier, - BottomSheetController sheetController) { + Runnable contextMenuCopyLinkObserver, BottomSheetController sheetController) { mActivity = activity; mAppBrowserControlsVisibilityDelegate = appBrowserControlsVisibilityDelegate; mShareDelegateSupplier = shareDelegateSupplier; mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier; + mContextMenuCopyLinkObserver = contextMenuCopyLinkObserver; mBottomSheetController = sheetController; } @@ -63,7 +65,8 @@ public ContextMenuPopulatorFactory createContextMenuPopulatorFactory(Tab tab) { return new ChromeContextMenuPopulatorFactory( new TabContextMenuItemDelegate(tab, mActivity.getTabModelSelector(), - mEphemeralTabCoordinatorSupplier, mActivity::getSnackbarManager), + mEphemeralTabCoordinatorSupplier, mContextMenuCopyLinkObserver, + mActivity::getSnackbarManager), mShareDelegateSupplier, ChromeContextMenuPopulator.ContextMenuMode.NORMAL, AppHooks.get().getExternalAuthUtils()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index 0de599b..6690b9a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -62,7 +62,6 @@ import org.chromium.chrome.browser.IntentHandler.IntentHandlerDelegate; import org.chromium.chrome.browser.IntentHandler.TabOpenType; import org.chromium.chrome.browser.PlayServicesVersionInfo; -import org.chromium.chrome.browser.TabbedModeTabDelegateFactory; import org.chromium.chrome.browser.WarmupManager; import org.chromium.chrome.browser.accessibility.FontSizePrefs; import org.chromium.chrome.browser.app.appmenu.AppMenuPropertiesDelegateImpl; @@ -137,7 +136,6 @@ import org.chromium.chrome.browser.sync.SyncController; import org.chromium.chrome.browser.tab.AccessibilityVisibilityHandler; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabDelegateFactory; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -172,7 +170,6 @@ import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; import org.chromium.components.browser_ui.notifications.NotificationManagerProxy; import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; -import org.chromium.components.browser_ui.util.ComposedBrowserControlsVisibilityDelegate; import org.chromium.components.browser_ui.widget.InsetObserverView; import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController; import org.chromium.components.browser_ui.widget.textbubble.TextBubble; @@ -1561,12 +1558,6 @@ return mActivityTabProvider; } - public TabDelegateFactory getTabDelegateFactory() { - return new TabbedModeTabDelegateFactory(this, - new ComposedBrowserControlsVisibilityDelegate(), getShareDelegateSupplier(), null, - mRootUiCoordinator.getBottomSheetController()); - } - /** * Returns the {@link InsetObserverView} that has the current system window * insets information.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java index ad7799f..ebe7c1e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
@@ -23,12 +23,15 @@ import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver; import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType; import org.chromium.chrome.browser.bookmarks.BookmarkRow.Location; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkType; import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableListAdapter; import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter; +import org.chromium.components.feature_engagement.EventConstants; import java.util.ArrayList; import java.util.List; @@ -310,6 +313,11 @@ } else { setBookmarks(mDelegate.getModel().getChildIDs(folder)); } + + if (folder.getType() == BookmarkType.READING_LIST) { + TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile()) + .notifyEvent(EventConstants.READ_LATER_BOOKMARK_FOLDER_OPENED); + } } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java index 7fcab81..773d07474 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
@@ -24,8 +24,10 @@ import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem; import org.chromium.chrome.browser.document.ChromeLauncherActivity; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; @@ -34,6 +36,7 @@ import org.chromium.components.bookmarks.BookmarkType; import org.chromium.components.browser_ui.widget.TintedDrawable; import org.chromium.components.embedder_support.util.UrlConstants; +import org.chromium.components.feature_engagement.EventConstants; import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.PageTransition; @@ -135,6 +138,9 @@ new SnackbarController() {}, Snackbar.TYPE_ACTION, Snackbar.UMA_READING_LIST_BOOKMARK_ADDED); snackbarManager.showSnackbar(snackbar); + + TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile()) + .notifyEvent(EventConstants.READ_LATER_ARTICLE_SAVED); } }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java index b6d61333..789ba7c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
@@ -8,6 +8,7 @@ import android.content.Context; import android.graphics.RectF; import android.os.Handler; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -22,16 +23,16 @@ import org.chromium.chrome.browser.compositor.layouts.Layout; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.chrome.browser.compositor.layouts.eventfilter.GestureHandler; import org.chromium.chrome.browser.compositor.layouts.eventfilter.OverlayPanelEventFilter; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.layouts.EventFilter; import org.chromium.chrome.browser.layouts.SceneOverlay; import org.chromium.chrome.browser.layouts.components.VirtualView; import org.chromium.chrome.browser.layouts.scene_layer.SceneOverlayLayer; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.common.BrowserControlsState; @@ -45,9 +46,9 @@ /** * Controls the Overlay Panel. */ -public class OverlayPanel extends OverlayPanelAnimation implements ActivityStateListener, - EdgeSwipeHandler, GestureHandler, OverlayPanelContentFactory, SceneOverlay { - +public class OverlayPanel extends OverlayPanelAnimation + implements ActivityStateListener, SwipeHandler, GestureHandler, OverlayPanelContentFactory, + SceneOverlay { /** The delay after which the hide progress will be hidden. */ private static final long HIDE_PROGRESS_BAR_DELAY_MS = 1000 / 60 * 4; @@ -785,7 +786,7 @@ } // ============================================================================================ - // GestureHandler and EdgeSwipeHandler implementation. + // GestureHandler and SwipeHandler implementation. // ============================================================================================ @Override @@ -820,10 +821,10 @@ @Override public void onPinch(float x0, float y0, float x1, float y1, boolean firstEvent) {} - // EdgeSwipeHandler implementation. + // SwipeHandler implementation. @Override - public void swipeStarted(@ScrollDirection int direction, float x, float y) { + public void onSwipeStarted(@ScrollDirection int direction, MotionEvent ev) { if (onInterceptBarSwipe()) { mIgnoreSwipeEvents = true; return; @@ -832,13 +833,13 @@ } @Override - public void swipeUpdated(float x, float y, float dx, float dy, float tx, float ty) { + public void onSwipeUpdated(MotionEvent current, float tx, float ty, float dx, float dy) { if (mIgnoreSwipeEvents) return; - handleSwipeMove(ty); + handleSwipeMove(ty * mPxToDp); } @Override - public void swipeFinished() { + public void onSwipeFinished() { if (mIgnoreSwipeEvents) { mIgnoreSwipeEvents = false; return; @@ -847,9 +848,10 @@ } @Override - public void swipeFlingOccurred(float x, float y, float tx, float ty, float vx, float vy) { + public void onFling(@ScrollDirection int direction, MotionEvent current, float tx, float ty, + float vx, float vy) { if (mIgnoreSwipeEvents) return; - handleFling(vy); + handleFling(vy * mPxToDp); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index e0866ca..065745f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.compositor.layouts; import android.content.Context; +import android.view.MotionEvent; import android.view.ViewGroup; import androidx.annotation.Nullable; @@ -22,9 +23,6 @@ import org.chromium.chrome.browser.compositor.TitleCache; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EmptyEdgeSwipeHandler; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelperManager; import org.chromium.chrome.browser.device.DeviceClassManager; @@ -43,6 +41,8 @@ import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.features.start_surface.StartSurface; import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.ui.resources.dynamics.DynamicResourceLoader; @@ -63,7 +63,7 @@ protected Layout mOverviewLayout; // Event Filter Handlers - private final EdgeSwipeHandler mToolbarSwipeHandler; + private final SwipeHandler mToolbarSwipeHandler; // Internal State /** A {@link TitleCache} instance that stores all title/favicon bitmaps as CC resources. */ @@ -150,15 +150,15 @@ } /** - * @return The {@link EdgeSwipeHandler} responsible for processing swipe events for the toolbar. + * @return The {@link SwipeHandler} responsible for processing swipe events for the toolbar. */ @Override - public EdgeSwipeHandler getToolbarSwipeHandler() { + public SwipeHandler getToolbarSwipeHandler() { return mToolbarSwipeHandler; } @Override - public EdgeSwipeHandler createToolbarSwipeHandler(boolean supportSwipeDown) { + public SwipeHandler createToolbarSwipeHandler(boolean supportSwipeDown) { return new ToolbarSwipeHandler(supportSwipeDown); } @@ -475,9 +475,9 @@ } /** - * A {@link EdgeSwipeHandler} meant to respond to edge events for the toolbar. + * A {@link SwipeHandler} meant to respond to edge events for the toolbar. */ - protected class ToolbarSwipeHandler extends EmptyEdgeSwipeHandler { + protected class ToolbarSwipeHandler implements SwipeHandler { /** The scroll direction of the current gesture. */ private @ScrollDirection int mScrollDirection; @@ -494,14 +494,21 @@ } @Override - public void swipeStarted(@ScrollDirection int direction, float x, float y) { + public void onSwipeStarted(@ScrollDirection int direction, MotionEvent ev) { mScrollDirection = ScrollDirection.UNKNOWN; } @Override - public void swipeUpdated(float x, float y, float dx, float dy, float tx, float ty) { + public void onSwipeUpdated(MotionEvent current, float tx, float ty, float dx, float dy) { if (mToolbarSwipeLayout == null) return; + float x = current.getRawX() * mPxToDp; + float y = current.getRawY() * mPxToDp; + dx *= mPxToDp; + dy *= mPxToDp; + tx *= mPxToDp; + ty *= mPxToDp; + // If scroll direction has been computed, send the event to super. if (mScrollDirection != ScrollDirection.UNKNOWN) { mToolbarSwipeLayout.swipeUpdated(time(), x, y, dx, dy, tx, ty); @@ -524,14 +531,21 @@ } @Override - public void swipeFinished() { + public void onSwipeFinished() { if (mToolbarSwipeLayout == null || !mToolbarSwipeLayout.isActive()) return; mToolbarSwipeLayout.swipeFinished(time()); } @Override - public void swipeFlingOccurred(float x, float y, float tx, float ty, float vx, float vy) { + public void onFling(@ScrollDirection int direction, MotionEvent current, float tx, float ty, + float vx, float vy) { if (mToolbarSwipeLayout == null || !mToolbarSwipeLayout.isActive()) return; + float x = current.getRawX() * mPxToDp; + float y = current.getRawX() * mPxToDp; + tx *= mPxToDp; + ty *= mPxToDp; + vx *= mPxToDp; + vy *= mPxToDp; mToolbarSwipeLayout.swipeFlingOccurred(time(), x, y, tx, ty, vx, vy); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java index 7108504..2bfab6c6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
@@ -31,7 +31,6 @@ import org.chromium.chrome.browser.compositor.layouts.Layout.Orientation; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelperManager; import org.chromium.chrome.browser.compositor.overlays.toolbar.TopToolbarOverlayCoordinator; import org.chromium.chrome.browser.compositor.scene_layer.ScrollingBottomViewSceneLayer; @@ -66,6 +65,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.browser.toolbar.ControlContainer; import org.chromium.chrome.browser.toolbar.ToolbarColors; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.base.SPenSupport; @@ -1024,19 +1024,19 @@ } /** - * @return The {@link EdgeSwipeHandler} responsible for processing swipe events for the normal + * @return The {@link SwipeHandler} responsible for processing swipe events for the normal * toolbar. By default this returns null. */ - public EdgeSwipeHandler getToolbarSwipeHandler() { + public SwipeHandler getToolbarSwipeHandler() { return null; } /** - * Creates a {@link EdgeSwipeHandler} instance. + * Creates a {@link SwipeHandler} instance. * @param supportSwipeDown Whether or not to the handler should support swipe down gesture. - * @return The {@link EdgeSwipeHandler} cerated. + * @return The {@link SwipeHandler} cerated. */ - public EdgeSwipeHandler createToolbarSwipeHandler(boolean supportSwipeDown) { + public SwipeHandler createToolbarSwipeHandler(boolean supportSwipeDown) { return null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java index 82f015d..3f9ba2a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java
@@ -16,7 +16,6 @@ import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.compositor.layouts.eventfilter.BlackHoleEventFilter; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.compositor.scene_layer.TabListSceneLayer; import org.chromium.chrome.browser.layouts.EventFilter; import org.chromium.chrome.browser.layouts.LayoutType; @@ -26,6 +25,7 @@ import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.components.browser_ui.widget.animation.Interpolators; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.resources.ResourceManager;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/EdgeSwipeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/EdgeSwipeHandler.java deleted file mode 100644 index da343004..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/EdgeSwipeHandler.java +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 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. - -package org.chromium.chrome.browser.compositor.layouts.eventfilter; - -/** - * Interface to implement to handle swipe from edge of the screen. - */ -public interface EdgeSwipeHandler { - /** - * Called when the swipe animation get initiated. It gives a chance to initialize everything. - * @param direction The direction the swipe is in. - * @param x The horizontal coordinate the swipe started at in dp. - * @param y The vertical coordinate the swipe started at in dp. - */ - public void swipeStarted(@ScrollDirection int direction, float x, float y); - - /** - * Called each time the swipe gets a new event updating the swipe position. - * @param x The horizontal coordinate the swipe is currently at in dp. - * @param y The vertical coordinate the swipe is currently at in dp. - * @param dx The horizontal delta since the last update in dp. - * @param dy The vertical delta since the last update in dp. - * @param tx The horizontal difference between the start and the current position in dp. - * @param ty The vertical difference between the start and the current position in dp. - */ - public void swipeUpdated(float x, float y, float dx, float dy, float tx, float ty); - - /** - * Called when the swipe ends; most likely on finger up event. It gives a chance to start - * an ending animation to exit the mode gracefully. - */ - public void swipeFinished(); - - /** - * Called when a fling happens while in a swipe. - * @param x The horizontal coordinate the swipe is currently at in dp. - * @param y The vertical coordinate the swipe is currently at in dp. - * @param tx The horizontal difference between the start and the current position in dp. - * @param ty The vertical difference between the start and the current position in dp. - * @param vx The horizontal velocity of the fling. - * @param vy The vertical velocity of the fling. - */ - public void swipeFlingOccurred(float x, float y, float tx, float ty, float vx, float vy); - - /** - * Gives the handler a chance to determine whether or not this type of swipe is currently - * allowed. - * @param direction The direction of the swipe. - * @return Whether or not the swipe is allowed. - */ - public boolean isSwipeEnabled(@ScrollDirection int direction); -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/EmptyEdgeSwipeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/EmptyEdgeSwipeHandler.java deleted file mode 100644 index 5e80e64..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/EmptyEdgeSwipeHandler.java +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.compositor.layouts.eventfilter; - -/** - * An empty implementation of a {@link EdgeSwipeHandler}. - */ -public class EmptyEdgeSwipeHandler implements EdgeSwipeHandler { - @Override - public void swipeStarted(@ScrollDirection int direction, float x, float y) {} - - @Override - public void swipeUpdated(float x, float y, float dx, float dy, float tx, float ty) { - } - - @Override - public void swipeFinished() { - } - - @Override - public void swipeFlingOccurred(float x, float y, float tx, float ty, float vx, float vy) { - } - - @Override - public boolean isSwipeEnabled(@ScrollDirection int direction) { - return true; - } - -} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/OverlayPanelEventFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/OverlayPanelEventFilter.java index 00632baa..57320bc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/OverlayPanelEventFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/OverlayPanelEventFilter.java
@@ -16,7 +16,7 @@ import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; -import org.chromium.chrome.browser.contextualsearch.SwipeRecognizer; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener; import org.chromium.content_public.browser.WebContents; import java.lang.annotation.Retention; @@ -63,8 +63,8 @@ /** The {@link GestureDetector} used to distinguish tap and scroll gestures. */ private final GestureDetector mGestureDetector; - /** The @{link SwipeRecognizer} that recognizes directional swipe gestures. */ - private final SwipeRecognizer mSwipeRecognizer; + /** The @{link SwipeGestureListener} that recognizes directional swipe gestures. */ + private final SwipeGestureListener mSwipeGestureListener; /** * The square of ViewConfiguration.getScaledTouchSlop() in pixels used to calculate whether @@ -121,10 +121,9 @@ /** Whether or not the superclass has seen a down event. */ private boolean mFilterHadDownEvent; - private class SwipeRecognizerImpl extends SwipeRecognizer { - public SwipeRecognizerImpl(Context context) { - super(context); - setSwipeHandler(mPanel); + private class SwipeGestureListenerImpl extends SwipeGestureListener { + public SwipeGestureListenerImpl(Context context) { + super(context, mPanel); } @Override @@ -145,7 +144,7 @@ mGestureDetector = new GestureDetector(context, new InternalGestureDetector()); mPanel = panel; - mSwipeRecognizer = new SwipeRecognizerImpl(context); + mSwipeGestureListener = new SwipeGestureListenerImpl(context); // Store the square of the platform touch slop in pixels to use in the scroll detection. // See {@link OverlayPanelEventFilter#isDistanceGreaterThanTouchSlop}. @@ -199,7 +198,7 @@ // Content View visibility to true when the side-swipe is detected. mPanel.notifyBarTouched(e.getX() * mPxToDp); } - mSwipeRecognizer.onTouchEvent(e); + mSwipeGestureListener.onTouchEvent(e); mGestureDetector.onTouchEvent(e); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ScrollDirection.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ScrollDirection.java deleted file mode 100644 index c4b451c8..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ScrollDirection.java +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.compositor.layouts.eventfilter; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({ScrollDirection.UNKNOWN, ScrollDirection.LEFT, ScrollDirection.RIGHT, ScrollDirection.DOWN, - ScrollDirection.UP}) -@Retention(RetentionPolicy.SOURCE) -public @interface ScrollDirection { - int UNKNOWN = 0; - int LEFT = 1; - int RIGHT = 2; - int DOWN = 3; - int UP = 4; -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/OverlappingStack.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/OverlappingStack.java index a0905515..cccc5ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/OverlappingStack.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/OverlappingStack.java
@@ -11,7 +11,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.Layout.Orientation; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayoutBase; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackAnimation.OverviewAnimationType; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; @@ -677,40 +676,4 @@ mWarpSize = warp; } - - @Override - public void swipeStarted(long time, @ScrollDirection int direction, float x, float y) { - if (direction != ScrollDirection.DOWN) return; - - // Turn off warping the tabs because we need them to track the user's finger; - setWarpState(false, false); - - super.swipeStarted(time, direction, x, y); - - // Don't let the tabs even out during this scroll. - mEvenOutProgress = 1.f; - } - - @Override - public void swipeFinished(long time) { - if (!mInSwipe) return; - - // Mark the tabs to even themselves out. - mEvenOutProgress = 0.f; - - // Reset the warp state. - setWarpState(true, true); - - super.swipeFinished(time); - } - - @Override - public void swipeCancelled(long time) { - if (!mInSwipe) return; - - mEvenOutProgress = 0.f; - setWarpState(true, true); - - super.swipeCancelled(time); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java index b3f2926b..992c03a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java
@@ -19,7 +19,6 @@ import org.chromium.chrome.browser.compositor.layouts.Layout; import org.chromium.chrome.browser.compositor.layouts.Layout.Orientation; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayoutBase; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackAnimation.OverviewAnimationType; import org.chromium.chrome.browser.flags.CachedFeatureFlags; @@ -2079,167 +2078,6 @@ mIsDying = false; } - /** - * Called when the swipe animation get initiated. It gives a chance to initialize - * everything. - * @param time The current time of the app in ms. - * @param direction The direction the swipe is in. - * @param x The horizontal coordinate the swipe started at in dp. - * @param y The vertical coordinate the swipe started at in dp. - */ - public void swipeStarted(long time, @ScrollDirection int direction, float x, float y) { - if (direction != ScrollDirection.DOWN) return; - - // Restart the enter stack animation with the new warp values. - startAnimation(time, OverviewAnimationType.ENTER_STACK); - - // Update the scroll offset to put the focused tab at the top. - final int index = mTabList.index(); - - if (mCurrentMode == Orientation.PORTRAIT - || ChromeFeatureList.isEnabled(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID)) { - mScrollOffset = -index * mSpacing; - } else { - mScrollOffset = -index * mSpacing + x - LANDSCAPE_SWIPE_DRAG_TAB_OFFSET_DP; - mScrollOffset = - MathUtils.clamp(mScrollOffset, getMinScroll(false), getMaxScroll(false)); - } - setScrollTarget(mScrollOffset, true); - - // Set up the tracking scroll parameters. - mSwipeUnboundScrollOffset = mScrollOffset; - mSwipeBoundedScrollOffset = mScrollOffset; - - // Reset other state. - mSwipeIsCancelable = false; - mSwipeCanScroll = false; - mInSwipe = true; - } - - /** - * Updates a swipe gesture. - * @param time The current time of the app in ms. - * @param x The horizontal coordinate the swipe is currently at in dp. - * @param y The vertical coordinate the swipe is currently at in dp. - * @param dx The horizontal delta since the last update in dp. - * @param dy The vertical delta since the last update in dp. - * @param tx The horizontal difference between the start and the current position in dp. - * @param ty The vertical difference between the start and the current position in dp. - */ - public void swipeUpdated(long time, float x, float y, float dx, float dy, float tx, float ty) { - if (!mInSwipe) return; - - final float toolbarSize = mLayout.getTopContentOffsetDp(); - if (ty > toolbarSize) mSwipeCanScroll = true; - if (!mSwipeCanScroll) return; - - final int index = mTabList.index(); - - // Check to make sure the index is still valid. - if (index < 0 || index >= mStackTabs.length) { - assert false : "Tab index out of bounds in Stack#swipeUpdated()"; - return; - } - - final float delta = mCurrentMode == Orientation.PORTRAIT ? dy : dx; - - // Update the unbound scroll offset, tracking delta regardless of constraints. - mSwipeUnboundScrollOffset += delta; - - // Figure out the new constrained position. - final float minScroll = getMinScroll(true); - final float maxScroll = getMaxScroll(true); - float offset = MathUtils.clamp(mSwipeUnboundScrollOffset, minScroll, maxScroll); - - final float constrainedDelta = offset - mSwipeBoundedScrollOffset; - mSwipeBoundedScrollOffset = offset; - - if (constrainedDelta == 0.f) return; - - if (mCurrentMode == Orientation.PORTRAIT) { - dy = constrainedDelta; - } else { - dx = constrainedDelta; - } - - // Propagate the new drag event. - drag(time, x, y, dx, dy); - - // Figure out if the user has scrolled down enough that they can scroll back up and - // exit. - if (mCurrentMode == Orientation.PORTRAIT) { - // The cancelable threshold is determined by the top position of the tab in the - // stack. - final float discardOffset = mStackTabs[index].getScrollOffset(); - final boolean beyondThreshold = -mScrollOffset < discardOffset; - - // Allow the user to cancel in the future if they're beyond the threshold. - mSwipeIsCancelable |= beyondThreshold; - - // If the user can cancel the swipe and they're back behind the threshold, cancel. - if (mSwipeIsCancelable && !beyondThreshold) swipeCancelled(time); - } else { - // The cancelable threshold is determined by the top position of the tab. - final float discardOffset = mStackTabs[index].getLayoutTab().getY(); - - boolean aboveThreshold = discardOffset < getRange(SWIPE_LANDSCAPE_THRESHOLD); - - mSwipeIsCancelable |= !aboveThreshold; - - if (mSwipeIsCancelable && aboveThreshold) swipeCancelled(time); - } - } - - /** - * Called when the swipe ends; most likely on finger up event. It gives a chance to start - * an ending animation to exit the mode gracefully. - * @param time The current time of the app in ms. - */ - public void swipeFinished(long time) { - if (!mInSwipe) return; - - mInSwipe = false; - - onUpOrCancel(time); - } - - /** - * Called when the user has cancelled a swipe; most likely if they have dragged their finger - * back to the starting position. Some handlers will throw swipeFinished() instead. - * @param time The current time of the app in ms. - */ - public void swipeCancelled(long time) { - if (!mInSwipe) return; - - mDiscardingTab = null; - - mInSwipe = false; - - // Select the current tab so we exit the switcher. - Tab tab = TabModelUtils.getCurrentTab(mTabList); - mLayout.uiSelectingTab(time, tab != null ? tab.getId() : Tab.INVALID_TAB_ID); - } - - /** - * Fling from a swipe gesture. - * @param time The current time of the app in ms. - * @param x The horizontal coordinate the swipe is currently at in dp. - * @param y The vertical coordinate the swipe is currently at in dp. - * @param tx The horizontal difference between the start and the current position in dp. - * @param ty The vertical difference between the start and the current position in dp. - * @param vx The horizontal velocity of the fling. - * @param vy The vertical velocity of the fling. - */ - public void swipeFlingOccurred( - long time, float x, float y, float tx, float ty, float vx, float vy) { - if (!mInSwipe) return; - - // Propagate the fling data. - fling(time, x, y, vx, vy); - - onUpOrCancel(time); - } - public static final FloatProperty<Stack> SCROLL_OFFSET = new FloatProperty<Stack>("SCROLL_OFFSET") { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java index c43444a..fdc50666 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
@@ -31,8 +31,6 @@ import java.net.URL; import java.util.HashSet; -import java.util.List; -import java.util.Locale; import java.util.regex.Pattern; /** @@ -442,60 +440,6 @@ ChromePreferenceKeys.CONTEXTUAL_SEARCH_TAP_SINCE_OPEN_COUNT); } - // -------------------------------------------------------------------------------------------- - // Translation support. - // -------------------------------------------------------------------------------------------- - - /** - * Determines whether translation is needed between the given languages. - * @param sourceLanguage The source language code; language we're translating from. - * @param targetLanguages A list of target language codes; languages we might translate to. - * @return Whether translation is needed or not. - */ - boolean needsTranslation(String sourceLanguage, List<String> targetLanguages) { - // For now, we just look for a language match. - for (String targetLanguage : targetLanguages) { - if (TextUtils.equals(sourceLanguage, targetLanguage)) { - return false; - } - } - return true; - } - - /** - * @return The best target language from the ordered list, or the empty string if - * none is available. - */ - String bestTargetLanguage(List<String> targetLanguages) { - return bestTargetLanguage(targetLanguages, Locale.getDefault().getCountry()); - } - - /** - * Determines the best language to convert into, given the ordered list of languages the user - * knows, and the UX language. - * @param targetLanguages The list of languages to consider converting to. - * @param countryOfUx The country of the UX. - * @return the best language or an empty string. - */ - @VisibleForTesting - String bestTargetLanguage(List<String> targetLanguages, String countryOfUx) { - // For now, we just return the first language, unless it's English - // (due to over-usage). - // TODO(donnd): Improve this logic. Determining the right language seems non-trivial. - // E.g. If this language doesn't match the user's server preferences, they might see a page - // in one language and the one box translation in another, which might be confusing. - // Also this logic should only apply on Android, where English setup is overused. - if (targetLanguages.size() > 1 - && TextUtils.equals(targetLanguages.get(0), Locale.ENGLISH.getLanguage()) - && !PREDOMINENTLY_ENGLISH_SPEAKING_COUNTRIES.contains(countryOfUx)) { - return targetLanguages.get(1); - } else if (targetLanguages.size() > 0) { - return targetLanguages.get(0); - } else { - return ""; - } - } - /** * @return The ISO country code for the user's home country, or an empty string if not * available or privacy-enabled.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/SwipeRecognizer.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/SwipeRecognizer.java deleted file mode 100644 index 2fed894..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/SwipeRecognizer.java +++ /dev/null
@@ -1,195 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextualsearch; - -import android.content.Context; -import android.graphics.PointF; -import android.view.GestureDetector; -import android.view.GestureDetector.SimpleOnGestureListener; -import android.view.MotionEvent; - -import org.chromium.base.ThreadUtils; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; - -/** - * Recognizes directional swipe gestures using supplied {@link MotionEvent}s. - * The {@EdgeSwipeHandler} callbacks will notify users when a particular gesture - * has occurred, if the handler supports the particular direction of the swipe. - * - * To use this class: - * <ul> - * <li>Create an instance of the {@code SwipeRecognizer} for your View - * <li>In the View#onTouchEvent(MotionEvent) method ensure you call - * {@link #onTouchEvent(MotionEvent)}. The methods defined in your callback - * will be executed when the gestures occur. - * <li>Before trying to recognize the gesture, the class will call - * {@link #shouldRecognizeSwipe(MotionEvent, MotionEvent)}, which allow - * ignoring swipe recognition based on the MotionEvents. - * <li>Once a swipe gesture is detected, the class will check if the the direction - * is supported by calling {@link EdgeSwipeHandler#isSwipeEnabled(ScrollDirection)}. - * </ul> - - * Internally, this class uses a {@link GestureDetector} to recognize swipe gestures. - * For convenience, this class also extends {@link SimpleOnGestureListener} which - * is passed to the {@GestureDetector}. This means that this class can also be - * used to detect simple gestures defined in {@link GestureDetector}. - */ -public class SwipeRecognizer extends SimpleOnGestureListener { - - /** - * The threshold for a vertical swipe gesture, in dps. - */ - private static final float SWIPE_VERTICAL_DRAG_THRESHOLD_DP = 5.f; - - /** - * The threshold for a horizontal swipe gesture, in dps. - */ - private static final float SWIPE_HORIZONTAL_DRAG_THRESHOLD_DP = 10.f; - - /** - * The {@link EdgeSwipeHandler} that will respond to recognized gestures. - */ - private EdgeSwipeHandler mSwipeHandler; - - /** - * The direction of the swipe gesture. - * TODO(pedrosimonetti): Consider renaming ScrollDirection to SwipeDirection. - * Also consider renaming EdgeSwipeHandler to SwipeHandler or DirectionalSwipeHandler. - * Finally, consider moving the ScrollDirection/SwipeDirection enum to this class. - */ - private @ScrollDirection int mSwipeDirection = ScrollDirection.UNKNOWN; - - /** - * The point that originated the swipe gesture. - */ - private final PointF mMotionStartPoint = new PointF(); - - /** - * The dps per pixel ratio. - */ - private final float mPxToDp; - - /** - * The internal {@GestureDetector} used to recognize swipe gestures. - */ - private final GestureDetector mGestureDetector; - - /** - * @param context The current Android {@link Context}. - */ - public SwipeRecognizer(Context context) { - mPxToDp = 1.f / context.getResources().getDisplayMetrics().density; - mGestureDetector = new GestureDetector(context, this, ThreadUtils.getUiThreadHandler()); - } - - /** - * Sets the {@link EdgeSwipeHandler} that will respond to recognized gestures. - * @param handler The {@link EdgeSwipeHandler}. - */ - public void setSwipeHandler(EdgeSwipeHandler handler) { - mSwipeHandler = handler; - } - - /** - * Analyzes the given motion event by feeding it to a {@GestureDetector}. Depending on the - * results from the onScroll() and onFling() methods, it triggers the appropriate callbacks - * on the {@link EdgeSwipeHandler} supplied. - * - * @param event The {@link MotionEvent}. - * @return Whether the event has been consumed. - */ - public boolean onTouchEvent(MotionEvent event) { - boolean consumed = mGestureDetector.onTouchEvent(event); - - if (mSwipeHandler != null) { - final int action = event.getAction(); - if ((action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) - && mSwipeDirection != ScrollDirection.UNKNOWN) { - mSwipeHandler.swipeFinished(); - mSwipeDirection = ScrollDirection.UNKNOWN; - consumed = true; - } - } - - return consumed; - } - - /** - * Checks whether the swipe gestures should be recognized. If this method returns false, - * then the whole swipe recognition process will be ignored. By default this method returns - * true. If a more complex logic is needed, this method should be overridden. - * - * @param e1 The first {@link MotionEvent}. - * @param e2 The second {@link MotionEvent}. - * @return Whether the swipe gestures should be recognized - */ - public boolean shouldRecognizeSwipe(MotionEvent e1, MotionEvent e2) { - return true; - } - - // ============================================================================================ - // Swipe Recognition Helpers - // ============================================================================================ - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - if (mSwipeHandler == null || e1 == null || e2 == null) return false; - - final float x = e2.getRawX() * mPxToDp; - final float y = e2.getRawY() * mPxToDp; - - if (mSwipeDirection == ScrollDirection.UNKNOWN && shouldRecognizeSwipe(e1, e2)) { - float tx = (e2.getRawX() - e1.getRawX()) * mPxToDp; - float ty = (e2.getRawY() - e1.getRawY()) * mPxToDp; - - @ScrollDirection - int direction = ScrollDirection.UNKNOWN; - - if (Math.abs(tx) > SWIPE_HORIZONTAL_DRAG_THRESHOLD_DP) { - direction = tx > 0.f ? ScrollDirection.RIGHT : ScrollDirection.LEFT; - } else if (Math.abs(ty) > SWIPE_VERTICAL_DRAG_THRESHOLD_DP) { - direction = ty > 0.f ? ScrollDirection.DOWN : ScrollDirection.UP; - } - - if (direction != ScrollDirection.UNKNOWN && mSwipeHandler.isSwipeEnabled(direction)) { - mSwipeDirection = direction; - mSwipeHandler.swipeStarted(direction, x, y); - mMotionStartPoint.set(e2.getRawX(), e2.getRawY()); - } - } - - if (mSwipeDirection != ScrollDirection.UNKNOWN) { - final float tx = (e2.getRawX() - mMotionStartPoint.x) * mPxToDp; - final float ty = (e2.getRawY() - mMotionStartPoint.y) * mPxToDp; - final float dx = -distanceX * mPxToDp; - final float dy = -distanceY * mPxToDp; - - mSwipeHandler.swipeUpdated(x, y, dx, dy, tx, ty); - return true; - } - - return false; - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if (mSwipeHandler == null) return false; - - if (mSwipeDirection != ScrollDirection.UNKNOWN) { - final float x = e2.getRawX() * mPxToDp; - final float y = e2.getRawY() * mPxToDp; - final float tx = (e2.getRawX() - mMotionStartPoint.x) * mPxToDp; - final float ty = (e2.getRawY() - mMotionStartPoint.y) * mPxToDp; - final float vx = velocityX * mPxToDp; - final float vy = velocityY * mPxToDp; - - mSwipeHandler.swipeFlingOccurred(x, y, tx, ty, vx, vy); - return true; - } - - return false; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java index 8649669c..3821ce3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
@@ -477,7 +477,7 @@ new TabContextMenuItemDelegate(tab, tabModelSelector, EphemeralTabCoordinator.isSupported() ? mEphemeralTabCoordinator::get : () -> null, - mActivity == null ? null : mActivity::getSnackbarManager), + () -> {}, mActivity == null ? null : mActivity::getSnackbarManager), shareDelegateSupplier, contextMenuMode, AppHooks.get().getExternalAuthUtils()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 450e5df..8e4905a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -443,7 +443,7 @@ // When we restore tabs, we focus the selected tab so the URL of the page shows. } - /* package */ void performSearchQuery(String query, List<String> searchParams) { + public void performSearchQuery(String query, List<String> searchParams) { if (TextUtils.isEmpty(query)) return; String queryUrl = TemplateUrlServiceFactory.get().getUrlForSearchQuery(query, searchParams);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/read_later/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/read_later/OWNERS new file mode 100644 index 0000000..4f3e2a6 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/read_later/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/reading_list/OWNERS
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadLaterIPHController.java b/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadLaterIPHController.java new file mode 100644 index 0000000..ec2227c --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadLaterIPHController.java
@@ -0,0 +1,87 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.read_later; + +import android.app.Activity; +import android.os.Handler; +import android.os.Looper; +import android.view.View; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler; +import org.chromium.chrome.browser.user_education.IPHCommandBuilder; +import org.chromium.chrome.browser.user_education.UserEducationHelper; +import org.chromium.components.feature_engagement.FeatureConstants; + +/** + * Controller to manage when and how we show read later in-product-help messages to users. + */ +public class ReadLaterIPHController { + private final UserEducationHelper mUserEducationHelper; + private final AppMenuHandler mAppMenuHandler; + private final View mToolbarMenuButton; + + /** + * Constructor. + * @param activity The current activity. + * @param toolbarMenuButton The toolbar menu button to which IPH will be anchored. + * @param appMenuHandler The app menu handler + */ + public ReadLaterIPHController( + Activity activity, View toolbarMenuButton, AppMenuHandler appMenuHandler) { + mToolbarMenuButton = toolbarMenuButton; + mAppMenuHandler = appMenuHandler; + mUserEducationHelper = new UserEducationHelper(activity, + new Handler(Looper.getMainLooper()), TrackerFactory::getTrackerForProfile); + } + + /** + * Attempts to show an IPH text bubble about the read later option in app menu. + */ + public void onCopyContextMenuItemClicked() { + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.READ_LATER)) return; + mUserEducationHelper.requestShowIPH( + new IPHCommandBuilder(mToolbarMenuButton.getContext().getResources(), + FeatureConstants.READ_LATER_APP_MENU_BOOKMARK_THIS_PAGE_FEATURE, + R.string.reading_list_save_pages_for_later, + R.string.reading_list_save_pages_for_later) + .setAnchorView(mToolbarMenuButton) + .setOnShowCallback( + () -> turnOnHighlightForMenuItem(R.id.bookmark_this_page_id)) + .setOnDismissCallback(this::turnOffHighlightForMenuItem) + .build()); + } + + /** + * Attempts to show an IPH text bubble after a cold start. + */ + public void showColdStartIPH() { + showReadLaterAppMenuBookmarksIPH(); + } + + private void showReadLaterAppMenuBookmarksIPH() { + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.READ_LATER)) return; + mUserEducationHelper.requestShowIPH( + new IPHCommandBuilder(mToolbarMenuButton.getContext().getResources(), + FeatureConstants.READ_LATER_APP_MENU_BOOKMARKS_FEATURE, + R.string.reading_list_find_in_bookmarks, + R.string.reading_list_find_in_bookmarks) + .setAnchorView(mToolbarMenuButton) + .setOnShowCallback( + () -> turnOnHighlightForMenuItem(R.id.all_bookmarks_menu_id)) + .setOnDismissCallback(this::turnOffHighlightForMenuItem) + .build()); + } + + private void turnOnHighlightForMenuItem(int highlightMenuItemId) { + mAppMenuHandler.setMenuHighlight(highlightMenuItemId); + } + + private void turnOffHighlightForMenuItem() { + mAppMenuHandler.clearMenuHighlight(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS index 77a2fcbd..2fecf072 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS
@@ -7,6 +7,7 @@ "+chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java", "+chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java", "+chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java", + "+chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java", "+chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java", "+chrome/android/java/src/org/chromium/chrome/browser/media/MediaCaptureNotificationServiceImpl.java", "+chrome/android/java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewTabHelper.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java index bf6f465..aa110a23 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -25,15 +25,18 @@ import org.chromium.chrome.browser.contextmenu.ContextMenuItemDelegate; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.download.ChromeDownloadDelegate; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.state.CriticalPersistedTabData; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlUtilities; +import org.chromium.components.feature_engagement.EventConstants; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.common.Referrer; @@ -52,6 +55,7 @@ private boolean mLoadOriginalImageRequestedForPageLoad; private EmptyTabObserver mDataReductionProxyContextMenuTabObserver; private final Supplier<EphemeralTabCoordinator> mEphemeralTabCoordinatorSupplier; + private final Runnable mContextMenuCopyLinkObserver; private final Supplier<SnackbarManager> mSnackbarManagerSupplier; /** @@ -59,10 +63,12 @@ */ public TabContextMenuItemDelegate(Tab tab, TabModelSelector tabModelSelector, Supplier<EphemeralTabCoordinator> ephemeralTabCoordinatorSupplier, + Runnable contextMenuCopyLinkObserver, Supplier<SnackbarManager> snackbarManagerSupplier) { mTab = (TabImpl) tab; mTabModelSelector = tabModelSelector; mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier; + mContextMenuCopyLinkObserver = contextMenuCopyLinkObserver; mSnackbarManagerSupplier = snackbarManagerSupplier; mDataReductionProxyContextMenuTabObserver = new EmptyTabObserver() { @@ -119,6 +125,10 @@ @Override public void onSaveToClipboard(String text, int clipboardType) { Clipboard.getInstance().setText(text); + if (clipboardType == ClipboardType.LINK_URL) { + // TODO(crbug/1150090): Find a better way of passing event for IPH. + mContextMenuCopyLinkObserver.run(); + } } @Override @@ -262,6 +272,8 @@ public void onReadLater(String url, String title) { BookmarkUtils.addToReadingList( url, title, mSnackbarManagerSupplier.get(), mTab.getContext()); + TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile()) + .notifyEvent(EventConstants.READ_LATER_CONTEXT_MENU_TAPPED); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java index dec6779b..c93b689b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -49,6 +49,7 @@ import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.read_later.ReadLaterIPHController; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.signin.SigninPromoUtil; import org.chromium.chrome.browser.status_indicator.StatusIndicatorCoordinator; @@ -81,6 +82,7 @@ private StatusIndicatorCoordinator.StatusIndicatorObserver mStatusIndicatorObserver; private OfflineIndicatorControllerV2 mOfflineIndicatorController; private OfflineIndicatorInProductHelpController mOfflineIndicatorInProductHelpController; + private ReadLaterIPHController mReadLaterIPHController; private UrlFocusChangeListener mUrlFocusChangeListener; private @Nullable ToolbarButtonInProductHelpController mToolbarButtonInProductHelpController; private AppBannerInProductHelpController mAppBannerInProductHelpController; @@ -326,10 +328,13 @@ } }; mToolbarButtonIphTabSupplier.set(activityTabProvider.get()); + mReadLaterIPHController = new ReadLaterIPHController(mActivity, + getToolbarManager().getMenuButtonView(), mAppMenuCoordinator.getAppMenuHandler()); boolean didTriggerPromo = triggerPromo(intentWithEffect); if (!didTriggerPromo) { mToolbarButtonInProductHelpController.showColdStartIPH(); + mReadLaterIPHController.showColdStartIPH(); } if (ChromeFeatureList.isEnabled(ChromeFeatureList.TOOLBAR_IPH_ANDROID)) { mPromoShownOneshotSupplier.set(didTriggerPromo); @@ -459,6 +464,12 @@ return mNavigationSheet; } + /** Called when a link is copied through context menu. */ + public void onContextMenuCopyLink() { + // TODO(crbug/1150090): Find a better way of passing event for IPH. + mReadLaterIPHController.onCopyContextMenuItemClicked(); + } + /** * Triggers the display of an appropriate promo, if any, returning true if a promo is actually * displayed.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ControlContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ControlContainer.java index 936f117..e2b80f96 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ControlContainer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ControlContainer.java
@@ -6,8 +6,8 @@ import android.view.View; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.components.browser_ui.widget.ClipDrawableProgressBar; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.ui.resources.dynamics.ViewResourceAdapter; /** @@ -38,7 +38,7 @@ /** * @param handler The swipe handler to be notified of swipe events on this container. */ - void setSwipeHandler(EdgeSwipeHandler handler); + void setSwipeHandler(SwipeHandler handler); /** * @return The {@link View} associated with this container.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java index a3df629e..ed05be8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
@@ -16,13 +16,13 @@ import org.chromium.base.TraceEvent; import org.chromium.chrome.R; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.chrome.browser.compositor.resources.ResourceFactory; -import org.chromium.chrome.browser.contextualsearch.SwipeRecognizer; import org.chromium.chrome.browser.toolbar.ControlContainer; import org.chromium.chrome.browser.toolbar.ToolbarProgressBar; import org.chromium.components.browser_ui.widget.ClipDrawableProgressBar.DrawingInfo; import org.chromium.components.browser_ui.widget.ViewResourceFrameLayout; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.base.ViewUtils; import org.chromium.ui.resources.dynamics.ViewResourceAdapter; @@ -37,8 +37,7 @@ private Toolbar mToolbar; private ToolbarViewResourceFrameLayout mToolbarContainer; - private final SwipeRecognizer mSwipeRecognizer; - private EdgeSwipeHandler mSwipeHandler; + private SwipeGestureListener mSwipeGestureListener; /** * Constructs a new control container. @@ -51,7 +50,6 @@ public ToolbarControlContainer(Context context, AttributeSet attrs) { super(context, attrs); mTabStripHeight = context.getResources().getDimension(R.dimen.tab_strip_height); - mSwipeRecognizer = new SwipeRecognizerImpl(context); } @Override @@ -79,9 +77,8 @@ } @Override - public void setSwipeHandler(EdgeSwipeHandler handler) { - mSwipeHandler = handler; - mSwipeRecognizer.setSwipeHandler(handler); + public void setSwipeHandler(SwipeHandler handler) { + mSwipeGestureListener = new SwipeGestureListenerImpl(getContext(), handler); } @Override @@ -263,7 +260,7 @@ @Override public boolean onTouchEvent(MotionEvent event) { // Don't eat the event if we don't have a handler. - if (mSwipeHandler == null) return false; + if (mSwipeGestureListener == null) return false; // Don't react on touch events if the toolbar container is not fully visible. if (!isToolbarContainerFullyVisible()) return true; @@ -277,15 +274,15 @@ return true; } - return mSwipeRecognizer.onTouchEvent(event); + return mSwipeGestureListener.onTouchEvent(event); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (!isToolbarContainerFullyVisible()) return true; - if (mSwipeHandler == null || isOnTabStrip(event)) return false; + if (mSwipeGestureListener == null || isOnTabStrip(event)) return false; - return mSwipeRecognizer.onTouchEvent(event); + return mSwipeGestureListener.onTouchEvent(event); } private boolean isOnTabStrip(MotionEvent e) { @@ -300,9 +297,9 @@ && mToolbarContainer.getVisibility() == VISIBLE; } - private class SwipeRecognizerImpl extends SwipeRecognizer { - public SwipeRecognizerImpl(Context context) { - super(context); + private class SwipeGestureListenerImpl extends SwipeGestureListener { + public SwipeGestureListenerImpl(Context context, SwipeHandler handler) { + super(context, handler); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java index 160a00b..28ec148ca 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java
@@ -4,12 +4,15 @@ package org.chromium.chrome.browser; +import static org.chromium.chrome.test.util.ViewUtils.createMotionEvent; + import android.support.test.InstrumentationRegistry; import android.view.View; import androidx.test.filters.MediumTest; import org.junit.Assert; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,13 +27,13 @@ import org.chromium.base.test.util.UrlUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.ViewEventSink; import org.chromium.content_public.browser.WebContents; @@ -58,6 +61,17 @@ private String mTitle; + private float mDpToPx; + + @Before + public void setUp() throws InterruptedException { + mDpToPx = InstrumentationRegistry.getInstrumentation() + .getContext() + .getResources() + .getDisplayMetrics() + .density; + } + private void addFocusChangedListener(View view) { view.setOnFocusChangeListener((v, hasFocus) -> { synchronized (mFocusChanges) { @@ -115,11 +129,12 @@ // Start the swipe addFocusChangedListener(view); - final EdgeSwipeHandler edgeSwipeHandler = + final SwipeHandler swipeHandler = mActivityTestRule.getActivity().getLayoutManager().getToolbarSwipeHandler(); PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> { - edgeSwipeHandler.swipeStarted(ScrollDirection.RIGHT, 0, 0); - edgeSwipeHandler.swipeUpdated(100, 0, 100, 0, 100, 0); + swipeHandler.onSwipeStarted(ScrollDirection.RIGHT, createMotionEvent(0, 0)); + swipeHandler.onSwipeUpdated( + createMotionEvent(100 * mDpToPx, 0), 100 * mDpToPx, 0, 100 * mDpToPx, 0); }); CriteriaHelper.pollUiThread(() -> { @@ -132,7 +147,7 @@ Assert.assertFalse("Content view didn't lose focus", blockForFocusChanged()); // End the drag - PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> edgeSwipeHandler.swipeFinished()); + PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, swipeHandler::onSwipeFinished); CriteriaHelper.pollUiThread(() -> { LayoutManagerImpl driver = mActivityTestRule.getActivity().getLayoutManager();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 7a05757..1cc638b0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -9,6 +9,7 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId; import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE; +import static org.chromium.chrome.test.util.ViewUtils.createMotionEvent; import android.content.pm.ActivityInfo; import android.graphics.Point; @@ -53,8 +54,6 @@ import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.compositor.layouts.StaticLayout; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; import org.chromium.chrome.browser.compositor.layouts.phone.stack.Stack; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackTab; @@ -79,6 +78,8 @@ import org.chromium.chrome.test.util.MenuUtils; import org.chromium.chrome.test.util.NewTabPageTestUtils; import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.javascript_dialogs.JavascriptTabModalDialog; import org.chromium.content_public.browser.SelectionPopupController; @@ -1573,7 +1574,7 @@ public void testOSKIsNotShownDuringSwipe() throws InterruptedException { final View urlBar = mActivityTestRule.getActivity().findViewById(R.id.url_bar); final LayoutManagerChrome layoutManager = updateTabsViewSize(); - final EdgeSwipeHandler edgeSwipeHandler = layoutManager.getToolbarSwipeHandler(); + final SwipeHandler swipeHandler = layoutManager.getToolbarSwipeHandler(); UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation()); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> urlBar.requestFocus()); @@ -1590,10 +1591,10 @@ mActivityTestRule.getActivity(), urlBar)); PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> { - edgeSwipeHandler.swipeStarted(ScrollDirection.RIGHT, 0, 0); + swipeHandler.onSwipeStarted(ScrollDirection.RIGHT, createMotionEvent(0, 0)); float swipeXChange = mTabsViewWidthDp / 2.f; - edgeSwipeHandler.swipeUpdated( - swipeXChange, 0.f, swipeXChange, 0.f, swipeXChange, 0.f); + swipeHandler.onSwipeUpdated(createMotionEvent(swipeXChange / mPxToDp, 0.f), + swipeXChange / mPxToDp, 0.f, swipeXChange / mPxToDp, 0.f); }); CriteriaHelper.pollUiThread(() -> { @@ -1607,7 +1608,7 @@ Assert.assertFalse("Keyboard should be hidden while swiping", mActivityTestRule.getKeyboardDelegate().isKeyboardShowing( mActivityTestRule.getActivity(), urlBar)); - edgeSwipeHandler.swipeFinished(); + swipeHandler.onSwipeFinished(); }); CriteriaHelper.pollUiThread(() -> {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index f1abe19..02ae4109 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -11,6 +11,7 @@ import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_LOW_END_DEVICE; import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE; import static org.chromium.chrome.browser.tab.TabCreationState.LIVE_IN_BACKGROUND; +import static org.chromium.chrome.test.util.ViewUtils.createMotionEvent; import android.content.Context; import android.graphics.PointF; @@ -52,8 +53,6 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; -import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; import org.chromium.chrome.browser.compositor.layouts.phone.stack.Stack; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackTab; @@ -79,6 +78,8 @@ import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.tabmodel.MockTabModel.MockTabModelDelegate; import org.chromium.chrome.test.util.browser.tabmodel.MockTabModelSelector; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection; +import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiRestriction; @@ -1047,7 +1048,7 @@ direction == ScrollDirection.LEFT || direction == ScrollDirection.RIGHT); final Layout layout = mManager.getActiveLayout(); - final EdgeSwipeHandler eventHandler = mManager.getToolbarSwipeHandler(); + final SwipeHandler eventHandler = mManager.getToolbarSwipeHandler(); Assert.assertNotNull("LayoutManager#getToolbarSwipeHandler() returned null", eventHandler); Assert.assertNotNull("LayoutManager#getActiveLayout() returned null", layout); @@ -1056,11 +1057,12 @@ final boolean scrollLeft = direction == ScrollDirection.LEFT; final float deltaX = MathUtils.flipSignIf(layoutWidth / 2.f, scrollLeft); - eventHandler.swipeStarted(direction, layoutWidth, 0); + eventHandler.onSwipeStarted(direction, createMotionEvent(layoutWidth * mDpToPx, 0)); // Call swipeUpdated twice since the handler computes direction in that method. // TODO(mdjones): Update implementation of EdgeSwipeHandler to work this way by default. - eventHandler.swipeUpdated(deltaX, 0.f, deltaX, 0.f, deltaX, 0.f); - eventHandler.swipeUpdated(deltaX, 0.f, deltaX, 0.f, deltaX, 0.f); + MotionEvent ev = createMotionEvent(deltaX * mDpToPx, 0.f); + eventHandler.onSwipeUpdated(ev, deltaX * mDpToPx, 0.f, deltaX * mDpToPx, 0.f); + eventHandler.onSwipeUpdated(ev, deltaX * mDpToPx, 0.f, deltaX * mDpToPx, 0.f); Assert.assertTrue("LayoutManager#getActiveLayout() should be ToolbarSwipeLayout", mManager.getActiveLayout() instanceof ToolbarSwipeLayout); Assert.assertTrue("LayoutManager took too long to finish the animations", @@ -1068,10 +1070,10 @@ } private void finishToolbarSideSwipe() { - final EdgeSwipeHandler eventHandler = mManager.getToolbarSwipeHandler(); + final SwipeHandler eventHandler = mManager.getToolbarSwipeHandler(); Assert.assertNotNull("LayoutManager#getToolbarSwipeHandler() returned null", eventHandler); - eventHandler.swipeFinished(); + eventHandler.onSwipeFinished(); Assert.assertTrue("LayoutManager took too long to finish the animations", simulateTime(mManager, 1000)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicyTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicyTest.java index 3354f062..00a3f9f6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicyTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicyTest.java
@@ -29,7 +29,6 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.net.URL; -import java.util.ArrayList; /** * Tests for the ContextualSearchPolicy class. @@ -53,55 +52,6 @@ () -> mPolicy = new ContextualSearchPolicy(null, mMockServer)); } - @Test - @SmallTest - @Feature({"ContextualSearch"}) - public void testBestTargetLanguageFromMultiple() { - ArrayList<String> list = new ArrayList<String>(); - list.add("br"); - list.add("de"); - Assert.assertEquals("br", mPolicy.bestTargetLanguage(list)); - } - - @Test - @SmallTest - @Feature({"ContextualSearch"}) - public void testBestTargetLanguageSkipsEnglish() { - String countryOfUx = ""; - ArrayList<String> list = new ArrayList<String>(); - list.add("en"); - list.add("id"); - Assert.assertEquals("id", mPolicy.bestTargetLanguage(list, countryOfUx)); - } - - @Test - @SmallTest - @Feature({"ContextualSearch"}) - public void testBestTargetLanguageReturnsEnglishWhenInUS() { - String countryOfUx = "US"; - ArrayList<String> list = new ArrayList<String>(); - list.add("en"); - list.add("id"); - Assert.assertEquals("en", mPolicy.bestTargetLanguage(list, countryOfUx)); - } - - @Test - @SmallTest - @Feature({"ContextualSearch"}) - public void testBestTargetLanguageUsesEnglishWhenOnlyChoice() { - ArrayList<String> list = new ArrayList<String>(); - list.add("en"); - Assert.assertEquals("en", mPolicy.bestTargetLanguage(list)); - } - - @Test - @SmallTest - @Feature({"ContextualSearch"}) - public void testBestTargetLanguageReturnsEmptyWhenNoChoice() { - ArrayList<String> list = new ArrayList<String>(); - Assert.assertEquals("", mPolicy.bestTargetLanguage(list)); - } - /** Call on the UI thread to set up all the conditions needed for sending the URL. */ private void setupAllConditionsToSendUrl() { mPolicy.overrideDecidedStateForTesting(true);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/OWNERS new file mode 100644 index 0000000..4f3e2a6 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/reading_list/OWNERS
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/ReadLaterIphTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/ReadLaterIphTest.java new file mode 100644 index 0000000..69e1dbf1 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/read_later/ReadLaterIphTest.java
@@ -0,0 +1,137 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.read_later; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isRoot; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import static org.chromium.chrome.browser.toolbar.top.ButtonHighlightMatcher.withHighlight; +import static org.chromium.chrome.test.util.ViewUtils.waitForView; + +import android.os.Looper; +import android.support.test.InstrumentationRegistry; +import android.view.View; + +import androidx.test.espresso.ViewInteraction; +import androidx.test.espresso.matcher.RootMatchers; +import androidx.test.filters.MediumTest; + +import org.hamcrest.Matcher; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import org.chromium.base.Callback; +import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Restriction; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.app.ChromeActivity; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.browser.Features; +import org.chromium.chrome.test.util.browser.contextmenu.RevampedContextMenuUtils; +import org.chromium.components.feature_engagement.EventConstants; +import org.chromium.components.feature_engagement.FeatureConstants; +import org.chromium.components.feature_engagement.Tracker; +import org.chromium.net.test.EmbeddedTestServerRule; +import org.chromium.ui.test.util.UiRestriction; + +/** Integration tests for showing IPH bubbles for read later. */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@Features.EnableFeatures(ChromeFeatureList.READ_LATER) +@Batch(Batch.PER_CLASS) +public class ReadLaterIphTest { + @Rule + public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); + @Rule + public EmbeddedTestServerRule mTestServer = new EmbeddedTestServerRule(); + @Rule + public MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private Tracker mTracker; + + private static final String CONTEXT_MENU_TEST_URL = + "/chrome/test/data/android/contextmenu/context_menu_test.html"; + private static final String CONTEXT_MENU_LINK_DOM_ID = "testLink"; + + @Before + public void setUp() { + Looper.prepare(); + // Pretend the feature engagement feature is already initialized. Otherwise + // UserEducationHelper#requestShowIPH() calls get dropped during test. + doAnswer(invocation -> { + invocation.<Callback<Boolean>>getArgument(0).onResult(true); + return null; + }) + .when(mTracker) + .addOnInitializedCallback(any()); + TrackerFactory.setTrackerForTests(mTracker); + mActivityTestRule.startMainActivityOnBlankPage(); + } + + @After + public void tearDown() throws Exception { + TrackerFactory.setTrackerForTests(null); + } + + @Test + @MediumTest + @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) + public void testShowIPHOnContextMenuLinkCopied() throws Throwable { + when(mTracker.shouldTriggerHelpUI( + FeatureConstants.READ_LATER_APP_MENU_BOOKMARK_THIS_PAGE_FEATURE)) + .thenReturn(true); + mActivityTestRule.loadUrlInNewTab(mTestServer.getServer().getURL(CONTEXT_MENU_TEST_URL)); + + ChromeActivity activity = mActivityTestRule.getActivity(); + Tab tab = activity.getActivityTab(); + RevampedContextMenuUtils.selectContextMenuItem(InstrumentationRegistry.getInstrumentation(), + activity, tab, CONTEXT_MENU_LINK_DOM_ID, R.id.contextmenu_copy_link_address); + + onView(withId(R.id.menu_button_wrapper)).check(matches(withHighlight(true))); + waitForHelpBubble(withText(R.string.reading_list_save_pages_for_later)); + } + + @Test + @MediumTest + @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) + public void testShowBookmarksReadLaterIPH() throws Throwable { + mActivityTestRule.loadUrl(mTestServer.getServer().getURL(CONTEXT_MENU_TEST_URL)); + ChromeActivity activity = mActivityTestRule.getActivity(); + Tab tab = activity.getActivityTab(); + RevampedContextMenuUtils.selectContextMenuItem(InstrumentationRegistry.getInstrumentation(), + activity, tab, CONTEXT_MENU_LINK_DOM_ID, R.id.contextmenu_read_later); + verify(mTracker, times(1)).notifyEvent(EventConstants.READ_LATER_CONTEXT_MENU_TAPPED); + } + + private ViewInteraction waitForHelpBubble(Matcher<View> matcher) { + View mainDecorView = mActivityTestRule.getActivity().getWindow().getDecorView(); + return onView(isRoot()) + .inRoot(RootMatchers.withDecorView(not(is(mainDecorView)))) + .check(waitForView(matcher)); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabUmaTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabUmaTest.java index a145c1a7..3eb2a0f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabUmaTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabUmaTest.java
@@ -72,11 +72,13 @@ private TabbedModeTabDelegateFactory createTabDelegateFactory() { BrowserControlsVisibilityDelegate visibilityDelegate = new BrowserControlsVisibilityDelegate(BrowserControlsState.BOTH) {}; + // clang-format off return new TabbedModeTabDelegateFactory(mActivityTestRule.getActivity(), visibilityDelegate, new ObservableSupplierImpl<ShareDelegate>(), null, - mActivityTestRule.getActivity() + () -> {}, mActivityTestRule.getActivity() .getRootUiCoordinatorForTesting() .getBottomSheetController()); + // clang-format on } private Tab createLazilyLoadedTab(boolean show) throws ExecutionException {
diff --git a/chrome/android/modules/buildflags.gni b/chrome/android/modules/buildflags.gni index b27f073..2cc34bd 100644 --- a/chrome/android/modules/buildflags.gni +++ b/chrome/android/modules/buildflags.gni
@@ -13,7 +13,8 @@ # other DFMs. # TODO(crbug.com/1126301): The binary size tools need to be updated to include # DFM code before this can be enabled on stable. - enable_chrome_module = false + enable_chrome_module = android_channel == "default" || + android_channel == "canary" || android_channel == "dev" # Whether to enable DFMs which depend on the chrome DFM. These will be split # out of the chrome DFM using DexSplitter.
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index ee0d052..2216521 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -760,12 +760,15 @@ </message> <!-- Crostini section. --> - <message name="IDS_OS_SETTINGS_TAG_CROSTINI" desc="Text for search result item which, when clicked, navigates the user to Linux (a.k.a. Crostini) settings. Alternate phrase for: 'Crostini'"> + <message name="IDS_OS_SETTINGS_TAG_CROSTINI" desc="Text for search result item which, when clicked, navigates the user to Linux (a.k.a. Crostini) settings. Alternate phrase for: 'Crostini, Developers'"> Linux </message> - <message name="IDS_OS_SETTINGS_TAG_CROSTINI_ALT1" desc="Text for search result item which, when clicked, navigates the user to Linux (a.k.a. Crostini) settings. Alternate phrase for: 'Linux'"> + <message name="IDS_OS_SETTINGS_TAG_CROSTINI_ALT1" desc="Text for search result item which, when clicked, navigates the user to Linux (a.k.a. Crostini) settings. Alternate phrase for: 'Linux, Developers'"> Crostini </message> + <message name="IDS_OS_SETTINGS_TAG_CROSTINI_ALT2" desc="Text for search result item which, when clicked, navigates the user to Linux (a.k.a. Crostini) settings. Alternate phrase for: 'Linux, Crostini'"> + Developers + </message> <message name="IDS_OS_SETTINGS_TAG_CROSTINI_SHARED_FOLDERS" desc="Text for search result item which, when clicked, navigates the user to Linux (a.k.a. Crostini) settings, with the option to share folders with the Chromebook. Alternate phrase for: 'Linux shared directories', 'Crostini shared folders', 'Crostini shared directories'"> Linux shared folders </message>
diff --git a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_CROSTINI_ALT2.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_CROSTINI_ALT2.png.sha1 new file mode 100644 index 0000000..4dd4daa3 --- /dev/null +++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_CROSTINI_ALT2.png.sha1
@@ -0,0 +1 @@ +479226be7e58aca337d957fd411b0b628b37d76d \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 5325a86..324637be4 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -1207,11 +1207,11 @@ </message> <!-- Crostini --> - <message name="IDS_SETTINGS_CROSTINI_TITLE" desc="The title of Crostini section."> - Linux (Beta) + <message name="IDS_SETTINGS_CROSTINI_TITLE" desc="The title of Crostini section. It is meant to be used by software developers."> + Developers </message> - <message name="IDS_SETTINGS_CROSTINI_LABEL" desc="The text associated with the primary section setting."> - Linux + <message name="IDS_SETTINGS_CROSTINI_LABEL" desc="The text associated with the primary section setting. This contains settings for a Linux container running in a virtual machine for use by software developers."> + Linux development environment </message> <message name="IDS_SETTINGS_CROSTINI_SHARED_PATHS" desc="Label for managing shared folders in Crostini."> Manage shared folders
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_LABEL.png.sha1 new file mode 100644 index 0000000..4dd4daa3 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_LABEL.png.sha1
@@ -0,0 +1 @@ +479226be7e58aca337d957fd411b0b628b37d76d \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_TITLE.png.sha1 new file mode 100644 index 0000000..4dd4daa3 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CROSTINI_TITLE.png.sha1
@@ -0,0 +1 @@ +479226be7e58aca337d957fd411b0b628b37d76d \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index f5cfac5..12336f5c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2812,6 +2812,12 @@ flag_descriptions::kShowBluetoothDebugLogToggleName, flag_descriptions::kShowBluetoothDebugLogToggleDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kShowBluetoothDebugLogToggle)}, + {"enable-bluetooth-verbose-logs-for-googlers", + flag_descriptions::kEnableBluetoothVerboseLogsForGooglersName, + flag_descriptions::kEnableBluetoothVerboseLogsForGooglersDescription, + kOsCrOS, + FEATURE_VALUE_TYPE( + chromeos::features::kEnableBluetoothVerboseLogsForGooglers)}, {"show-bluetooth-device-battery", flag_descriptions::kShowBluetoothDeviceBatteryName, flag_descriptions::kShowBluetoothDeviceBatteryDescription, kOsCrOS, @@ -6729,6 +6735,13 @@ flag_descriptions::kShowPerformanceMetricsHudDescription, kOsAll, FEATURE_VALUE_TYPE(features::kHudDisplayForPerformanceMetrics)}, +#if defined(OS_CHROMEOS) + {"disable-buffer-bw-compression", + flag_descriptions::kDisableBufferBWCompressionName, + flag_descriptions::kDisableBufferBWCompressionDescription, kOsCrOS, + SINGLE_VALUE_TYPE(switches::kDisableBufferBWCompression)}, +#endif // defined(OS_CHROMEOS) + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/apps/app_service/app_service_proxy.cc b/chrome/browser/apps/app_service/app_service_proxy.cc index 42c9e82..8de93d3 100644 --- a/chrome/browser/apps/app_service/app_service_proxy.cc +++ b/chrome/browser/apps/app_service/app_service_proxy.cc
@@ -37,7 +37,6 @@ #include "chrome/browser/chromeos/crosapi/browser_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/supervised_user/grit/supervised_user_unscaled_resources.h" -#include "chromeos/constants/chromeos_features.h" #include "components/user_manager/user.h" #include "extensions/common/constants.h" #endif @@ -183,8 +182,7 @@ // Lacros does not support multi-signin, so only create for the primary // profile. This also avoids creating an instance for the lock screen app // profile and ensures there is only one instance of LacrosApps. - if (chromeos::features::IsLacrosSupportEnabled() && - crosapi::browser_util::IsLacrosAllowed() && + if (crosapi::browser_util::IsLacrosEnabled() && chromeos::ProfileHelper::IsPrimaryProfile(profile_)) { lacros_apps_ = std::make_unique<LacrosApps>(app_service_); }
diff --git a/chrome/browser/apps/app_service/lacros_apps.cc b/chrome/browser/apps/app_service/lacros_apps.cc index 206ccf29..80dd84a 100644 --- a/chrome/browser/apps/app_service/lacros_apps.cc +++ b/chrome/browser/apps/app_service/lacros_apps.cc
@@ -12,9 +12,9 @@ #include "chrome/browser/apps/app_service/app_icon_factory.h" #include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/chromeos/crosapi/browser_manager.h" +#include "chrome/browser/chromeos/crosapi/browser_util.h" #include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/generated_resources.h" -#include "chromeos/constants/chromeos_features.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "extensions/common/constants.h" @@ -22,7 +22,7 @@ LacrosApps::LacrosApps( const mojo::Remote<apps::mojom::AppService>& app_service) { - DCHECK(chromeos::features::IsLacrosSupportEnabled()); + DCHECK(crosapi::browser_util::IsLacrosEnabled()); PublisherBase::Initialize(app_service, apps::mojom::AppType::kLacros); }
diff --git a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc index 87dc70ae..e3830f2 100644 --- a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc +++ b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
@@ -220,30 +220,6 @@ base::Optional<std::string> device_to_select_; }; -class FakeBluetoothScanningPrompt : public content::BluetoothScanningPrompt { - public: - explicit FakeBluetoothScanningPrompt( - const content::BluetoothScanningPrompt::EventHandler& event_handler) - : event_handler_(event_handler) {} - ~FakeBluetoothScanningPrompt() override = default; - - // Move-only class - FakeBluetoothScanningPrompt(const FakeBluetoothScanningPrompt&) = delete; - FakeBluetoothScanningPrompt& operator=(const FakeBluetoothScanningPrompt&) = - delete; - - void RunPromptEventHandler(content::BluetoothScanningPrompt::Event event) { - if (event_handler_.is_null()) { - FAIL() << "event_handler_ is not set"; - return; - } - event_handler_.Run(event); - } - - protected: - content::BluetoothScanningPrompt::EventHandler event_handler_; -}; - class TestBluetoothDelegate : public ChromeBluetoothDelegate { public: TestBluetoothDelegate() = default; @@ -255,18 +231,6 @@ device_to_select_ = device_address; } - // This method waits until ShowBluetoothScanningPrompt() has been called and - // |scanning_prompt_| contains a pointer to the created prompt, so the test - // will timeout if |navigator.bluetooth.requestLEScan()| has not been called - // in JavaScript. - void RunPromptEventHandler(content::BluetoothScanningPrompt::Event event) { - if (!scanning_prompt_) { - scanning_prompt_creation_loop_.emplace(); - scanning_prompt_creation_loop_->Run(); - } - scanning_prompt_->RunPromptEventHandler(event); - } - protected: // content::BluetoothDelegate implementation: std::unique_ptr<content::BluetoothChooser> RunBluetoothChooser( @@ -280,20 +244,12 @@ content::RenderFrameHost* frame, const content::BluetoothScanningPrompt::EventHandler& event_handler) override { - auto scanning_prompt = - std::make_unique<FakeBluetoothScanningPrompt>(event_handler); - scanning_prompt_ = scanning_prompt.get(); - if (scanning_prompt_creation_loop_) - scanning_prompt_creation_loop_->Quit(); - return scanning_prompt; + // Simulate that a prompt was accepted; no actual prompt is needed here. + event_handler.Run(content::BluetoothScanningPrompt::Event::kAllow); + return nullptr; } base::Optional<std::string> device_to_select_; - FakeBluetoothScanningPrompt* scanning_prompt_; - - // This RunLoop is used to ensure that |scanning_prompt_| is not nullptr when - // RunPromptEventHandler() is called. - base::Optional<base::RunLoop> scanning_prompt_creation_loop_; }; class TestContentBrowserClient : public ChromeContentBrowserClient { @@ -393,10 +349,6 @@ browser_client_.bluetooth_delegate()->SetDeviceToSelect(device_address); } - void RunPromptEventHandler(content::BluetoothScanningPrompt::Event event) { - browser_client_.bluetooth_delegate()->RunPromptEventHandler(event); - } - std::unique_ptr<device::BluetoothAdapterFactory::GlobalValuesForTesting> global_values_; scoped_refptr<FakeBluetoothAdapter> adapter_; @@ -596,14 +548,13 @@ IN_PROC_BROWSER_TEST_F(WebBluetoothTestWithNewPermissionsBackendEnabled, PRE_WebBluetoothScanningIdsNotPersistent) { - // Grant permission to scan for Bluetooth devices and store the detected + // The request to scan should be automatically accepted. Store the detected // device's WebBluetoothDeviceId in localStorage to retrieve it after the // browser restarts. ASSERT_TRUE(content::ExecJs(web_contents_, R"( var requestLEScanPromise = navigator.bluetooth.requestLEScan({ acceptAllAdvertisements: true}); )")); - RunPromptEventHandler(content::BluetoothScanningPrompt::Event::kAllow); ASSERT_TRUE(content::ExecJs(web_contents_, "requestLEScanPromise")); ASSERT_TRUE(content::ExecJs(web_contents_, R"( @@ -625,16 +576,14 @@ EXPECT_TRUE(blink::WebBluetoothDeviceId::IsValid(scan_id)); } -// TODO(crbug.com/1147575) Test failure on Mac10.15 IN_PROC_BROWSER_TEST_F(WebBluetoothTestWithNewPermissionsBackendEnabled, - DISABLED_WebBluetoothScanningIdsNotPersistent) { - // Grant permission to scan for Bluetooth devices again, and compare the ID + WebBluetoothScanningIdsNotPersistent) { + // The request to scan should be automatically accepted. Store the detected // assigned to the scanned device against the one that was stored previously. ASSERT_TRUE(content::ExecJs(web_contents_, R"( var requestLEScanPromise = navigator.bluetooth.requestLEScan({ acceptAllAdvertisements: true}); )")); - RunPromptEventHandler(content::BluetoothScanningPrompt::Event::kAllow); ASSERT_TRUE(content::ExecJs(web_contents_, "requestLEScanPromise")); ASSERT_TRUE(content::ExecJs(web_contents_, R"( @@ -683,16 +632,14 @@ EXPECT_TRUE(blink::WebBluetoothDeviceId::IsValid(granted_id)); } -// TODO(crbug.com/1147582): Flaky IN_PROC_BROWSER_TEST_F(WebBluetoothTestWithNewPermissionsBackendEnabled, - DISABLED_WebBluetoothIdsUsedInWebBluetoothScanning) { - // Grant permission to scan for Bluetooth devices again, and compare the ID + WebBluetoothIdsUsedInWebBluetoothScanning) { + // The request to scan should be automatically accepted. Store the detected // assigned to the scanned device against the one that was stored previously. ASSERT_TRUE(content::ExecJs(web_contents_, R"( var requestLEScanPromise = navigator.bluetooth.requestLEScan({ acceptAllAdvertisements: true}); )")); - RunPromptEventHandler(content::BluetoothScanningPrompt::Event::kAllow); ASSERT_TRUE(content::ExecJs(web_contents_, "requestLEScanPromise")); ASSERT_TRUE(content::ExecJs(web_contents_, R"(
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 76cc631..0ed8d45 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -37,6 +37,8 @@ <structure name="IDR_ASSISTANT_OPTIN_JS" file="resources\chromeos\assistant_optin\assistant_optin.js" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> <structure name="IDR_OOBE_DEBUGGER_JS" file="resources\chromeos\login\debug\debug.js" flattenhtml="true" type="chrome_html" /> <structure name="IDR_OOBE_DEBUGGER_STUB_JS" file="resources\chromeos\login\debug\no_debug.js" flattenhtml="true" type="chrome_html" /> + <structure name="IDR_OOBE_TEST_API_JS" file="resources\chromeos\login\test_api\test_api.js" flattenhtml="true" type="chrome_html" /> + <structure name="IDR_OOBE_TEST_API_STUB_JS" file="resources\chromeos\login\test_api\no_test_api.js" flattenhtml="true" type="chrome_html" /> <!-- OOBE Components --> <structure name="IDR_OOBE_COMPONENTS_I18N_BEHAVIOR_HTML" file="resources/chromeos/login/components/oobe_i18n_behavior/oobe_i18n_behavior.html" type="chrome_html" />
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 384959a..702956e9 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1476,6 +1476,8 @@ "input_method/suggester.h", "input_method/suggestion_enums.h", "input_method/suggestion_handler_interface.h", + "input_method/tts_handler.cc", + "input_method/tts_handler.h", "input_method/ui/assistive_delegate.h", "input_method/ui/border_factory.cc", "input_method/ui/border_factory.h",
diff --git a/chrome/browser/chromeos/arc/accessibility/accessibility_info_data_wrapper.cc b/chrome/browser/chromeos/arc/accessibility/accessibility_info_data_wrapper.cc index db3276f..a6f22a8e 100644 --- a/chrome/browser/chromeos/arc/accessibility/accessibility_info_data_wrapper.cc +++ b/chrome/browser/chromeos/arc/accessibility/accessibility_info_data_wrapper.cc
@@ -25,37 +25,42 @@ void AccessibilityInfoDataWrapper::PopulateBounds( ui::AXNodeData* out_data) const { + aura::Window* window = tree_source_->GetWindow(); AccessibilityInfoDataWrapper* root = tree_source_->GetRoot(); gfx::Rect info_data_bounds = GetBounds(); gfx::RectF& out_bounds = out_data->relative_bounds.bounds; - if (root && exo::WMHelper::HasInstance()) { + if (window && root && exo::WMHelper::HasInstance()) { if (tree_source_->is_notification() || tree_source_->is_input_method_window() || root->GetId() != GetId()) { // By default, populate the bounds relative to the tree root. const gfx::Rect& root_bounds = root->GetBounds(); - info_data_bounds.Offset(-1 * root_bounds.x(), -1 * root_bounds.y()); - out_bounds = ToChromeScale(info_data_bounds); + + out_bounds = ScaleAndroidPxToChromePx(info_data_bounds, window); out_data->relative_bounds.offset_container_id = root->GetId(); } else { // For the root node of application tree, populate the bounds to be // relative to its container View. - views::Widget* widget = views::Widget::GetWidgetForNativeView( - exo::WMHelper::GetInstance()->GetActiveWindow()); + views::Widget* widget = views::Widget::GetWidgetForNativeView(window); DCHECK(widget); DCHECK(widget->widget_delegate()); DCHECK(widget->widget_delegate()->GetContentsView()); - const gfx::Rect& root_bounds = - widget->widget_delegate()->GetContentsView()->GetBoundsInScreen(); + gfx::PointF root_origin = gfx::PointF(widget->widget_delegate() + ->GetContentsView() + ->GetBoundsInScreen() + .origin()); - out_bounds = ToChromeBounds(info_data_bounds, widget); - out_bounds.Offset(-1 * root_bounds.x(), -1 * root_bounds.y()); + // Adjust the origin because a maximized window has an offset in Android. + root_origin.Offset(0, -1 * GetChromeWindowHeightOffsetInDip(window)); + + // Scale to Chrome pixels. + root_origin.Scale( + window->GetToplevelWindow()->layer()->device_scale_factor()); + + out_bounds = ScaleAndroidPxToChromePx(info_data_bounds, window); + out_bounds.Offset(-1 * root_origin.x(), -1 * root_origin.y()); } - - // |out_bounds| is in Chrome DPI here. As ARC is considered the same as web - // in Chrome automation, scale the bounds by device scale factor. - out_bounds.Scale(tree_source_->device_scale_factor()); } else { // We cannot compute global bounds, so use the raw bounds. out_bounds.SetRect(info_data_bounds.x(), info_data_bounds.y(),
diff --git a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc index 1016191..bf3f714 100644 --- a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper_unittest.cc
@@ -63,7 +63,7 @@ class TestAXTreeSourceArc : public AXTreeSourceArc { public: explicit TestAXTreeSourceArc(AXTreeSourceArc::Delegate* delegate) - : AXTreeSourceArc(delegate, 1.0) {} + : AXTreeSourceArc(delegate) {} // AXTreeSourceArc overrides. bool IsRootOfNodeTree(int32_t id) const override {
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc index 6a09638..067d52b 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -93,9 +93,14 @@ if (!active_window) return; - gfx::Rect bounds_in_screen = gfx::ToEnclosingRect(arc::ToChromeBounds( + // Convert bounds from Android pixels to Chrome DIP, and adjust coordinate to + // Chrome's screen coordinate. + gfx::Rect bounds_in_screen = gfx::ScaleToEnclosingRect( node_data->bounds_in_screen, - views::Widget::GetWidgetForNativeView(active_window))); + 1.0f / exo::WMHelper::GetInstance()->GetDeviceScaleFactorForWindow( + active_window)); + bounds_in_screen.Offset(0, + arc::GetChromeWindowHeightOffsetInDip(active_window)); bool is_editable = arc::GetBooleanProperty( node_data, arc::mojom::AccessibilityBooleanProperty::EDITABLE); @@ -424,23 +429,11 @@ auto key = KeyForNotification(notification_key); switch (state) { case arc::mojom::AccessibilityNotificationStateType::SURFACE_CREATED: { - aura::Window* window = nullptr; - auto* surface_manager = ArcNotificationSurfaceManager::Get(); - if (surface_manager) { - ArcNotificationSurface* surface = - surface_manager->GetArcSurface(notification_key); - if (surface) - window = surface->GetWindow(); - } - AXTreeSourceArc* tree_source = GetFromKey(key); - if (tree_source) { - tree_source->set_device_scale_factor( - DeviceScaleFactorFromWindow(window)); + if (tree_source) return; - } - tree_source = CreateFromKey(std::move(key), window); + tree_source = CreateFromKey(std::move(key)); UpdateTreeIdOfNotificationSurface(notification_key, tree_source->ax_tree_id()); break; @@ -546,8 +539,6 @@ return; surface->SetAXTreeId(tree->ax_tree_id()); - tree->set_device_scale_factor( - DeviceScaleFactorFromWindow(surface->GetWindow())); // Dispatch ax::mojom::Event::kChildrenChanged to force AXNodeData of the // notification updated. As order of OnNotificationSurfaceAdded call is not @@ -691,8 +682,8 @@ if (!active_window) return base::nullopt; - gfx::RectF rect_f = arc::ToChromeScale(*result_rect); - rect_f.Scale(DeviceScaleFactorFromWindow(active_window)); + const gfx::RectF& rect_f = + ScaleAndroidPxToChromePx(result_rect.value(), active_window); return gfx::ToEnclosingRect(rect_f); } @@ -804,7 +795,7 @@ TreeKey key = KeyForTaskId(task_id); AXTreeSourceArc* tree = GetFromKey(key); if (!tree) - tree = CreateFromKey(std::move(key), window); + tree = CreateFromKey(std::move(key)); // Just after the creation of window, widget has not been set yet and this // is not dispatched to ShellSurfaceBase. Thus, call this every time. @@ -876,14 +867,14 @@ return; if (!trees_.count(KeyForInputMethod())) { - auto* tree = CreateFromKey(KeyForInputMethod(), - input_method_surface->host_window()); + auto* tree = CreateFromKey(KeyForInputMethod()); input_method_surface->SetChildAxTreeId(tree->ax_tree_id()); } tree_source = GetFromKey(KeyForInputMethod()); } else { aura::Window* active_window = GetActiveWindow(); + // TODO(b/173658482): Support non-active windows. if (!active_window) return; @@ -905,7 +896,7 @@ tree_source = GetFromKey(key); if (!tree_source) { - tree_source = CreateFromKey(key, active_window); + tree_source = CreateFromKey(key); SetChildAxTreeIDForWindow(active_window, tree_source->ax_tree_id()); if (chromeos::AccessibilityManager::Get() && chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) { @@ -913,9 +904,6 @@ // compare this with TalkBack usage. base::UmaHistogramBoolean("Arc.AccessibilityWithTalkBack", false); } - } else { - tree_source->set_device_scale_factor( - DeviceScaleFactorFromWindow(active_window)); } } @@ -1017,11 +1005,8 @@ GetEventRouter()->BroadcastEvent(std::move(event)); } -AXTreeSourceArc* ArcAccessibilityHelperBridge::CreateFromKey( - TreeKey key, - aura::Window* window) { - auto tree = std::make_unique<AXTreeSourceArc>( - this, DeviceScaleFactorFromWindow(window)); +AXTreeSourceArc* ArcAccessibilityHelperBridge::CreateFromKey(TreeKey key) { + auto tree = std::make_unique<AXTreeSourceArc>(this); auto* tree_ptr = tree.get(); trees_.insert(std::make_pair(std::move(key), std::move(tree))); return tree_ptr;
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h index eabdcbf..e620fbed 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h
@@ -172,7 +172,7 @@ mojom::AccessibilityEventData* event_data) const; void DispatchCustomSpokenFeedbackToggled(bool enabled) const; - AXTreeSourceArc* CreateFromKey(TreeKey, aura::Window* window); + AXTreeSourceArc* CreateFromKey(TreeKey); AXTreeSourceArc* GetFromKey(const TreeKey&); AXTreeSourceArc* GetFromTreeId(ui::AXTreeID tree_id) const;
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc index 3bc5d67a6..8bd9acaa 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc
@@ -8,12 +8,16 @@ #include <string> #include <utility> +#include "ash/public/cpp/external_arc/message_center/arc_notification_surface.h" +#include "ash/public/cpp/external_arc/message_center/arc_notification_surface_manager.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.h" #include "chrome/browser/chromeos/arc/accessibility/accessibility_window_info_data_wrapper.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "chrome/browser/chromeos/arc/accessibility/geometry_util.h" +#include "components/exo/input_method_surface.h" +#include "components/exo/wm_helper.h" #include "extensions/browser/api/automation_internal/automation_event_router.h" #include "extensions/common/extension_messages.h" #include "ui/accessibility/ax_enums.mojom.h" @@ -47,9 +51,8 @@ } } // namespace -AXTreeSourceArc::AXTreeSourceArc(Delegate* delegate, float device_scale_factor) - : device_scale_factor_(device_scale_factor), - current_tree_serializer_(new AXTreeArcSerializer(this)), +AXTreeSourceArc::AXTreeSourceArc(Delegate* delegate) + : current_tree_serializer_(new AXTreeArcSerializer(this)), is_notification_(false), is_input_method_window_(false), delegate_(delegate) {} @@ -151,6 +154,35 @@ info_data->Serialize(out_data); } +aura::Window* AXTreeSourceArc::GetWindow() const { + if (is_notification_) { + if (!notification_key_.has_value()) + return nullptr; + + auto* surface_manager = ash::ArcNotificationSurfaceManager::Get(); + if (!surface_manager) + return nullptr; + + ash::ArcNotificationSurface* surface = + surface_manager->GetArcSurface(notification_key_.value()); + if (!surface) + return nullptr; + + return surface->GetWindow(); + } else if (is_input_method_window_) { + exo::InputMethodSurface* input_method_surface = + exo::InputMethodSurface::GetInputMethodSurface(); + if (!input_method_surface) + return nullptr; + + return input_method_surface->host_window(); + } else if (exo::WMHelper::HasInstance()) { + // TODO(b/173658482): Support non-active windows. + return exo::WMHelper::GetInstance()->GetActiveWindow(); + } + return nullptr; +} + void AXTreeSourceArc::NotifyAccessibilityEventInternal( const AXEventData& event_data) { if (window_id_ != event_data.window_id) { @@ -158,6 +190,8 @@ window_id_ = event_data.window_id; } is_notification_ = event_data.notification_key.has_value(); + if (is_notification_) + notification_key_ = event_data.notification_key; is_input_method_window_ = event_data.is_input_method_window; // Prepare the wrapper objects of mojom data from Android.
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h index 26695ad..71c2082 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h
@@ -45,7 +45,7 @@ virtual bool UseFullFocusMode() const = 0; }; - AXTreeSourceArc(Delegate* delegate, float device_scale_factor); + explicit AXTreeSourceArc(Delegate* delegate); ~AXTreeSourceArc() override; // Notify automation of an accessibility event. @@ -85,8 +85,7 @@ void SerializeNode(AccessibilityInfoDataWrapper* info_data, ui::AXNodeData* out_data) const override; - float device_scale_factor() const { return device_scale_factor_; } - void set_device_scale_factor(float dsf) { device_scale_factor_ = dsf; } + aura::Window* GetWindow() const; bool is_notification() { return is_notification_; } @@ -162,9 +161,6 @@ // Maps an AccessibilityInfoDataWrapper ID to its tree data. std::map<int32_t, std::unique_ptr<AccessibilityInfoDataWrapper>> tree_map_; - // The device scale factor of the display which the window is on. - float device_scale_factor_; - // Maps an AccessibilityInfoDataWrapper ID to its parent. std::map<int32_t, int32_t> parent_map_; @@ -176,6 +172,8 @@ bool is_notification_; bool is_input_method_window_; + base::Optional<std::string> notification_key_; + std::map<int32_t, std::string> cached_names_; std::map<int32_t, ax::mojom::Role> cached_roles_;
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc index ac008bfa..defeea1 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc
@@ -137,7 +137,7 @@ public: TestAXTreeSourceArc(AXTreeSourceArc::Delegate* delegate, MockAutomationEventRouter* router) - : AXTreeSourceArc(delegate, 1.0), router_(router) {} + : AXTreeSourceArc(delegate), router_(router) {} private: extensions::AutomationEventRouterInterface* GetAutomationEventRouter()
diff --git a/chrome/browser/chromeos/arc/accessibility/geometry_util.cc b/chrome/browser/chromeos/arc/accessibility/geometry_util.cc index 175671af0..dd775eb3 100644 --- a/chrome/browser/chromeos/arc/accessibility/geometry_util.cc +++ b/chrome/browser/chromeos/arc/accessibility/geometry_util.cc
@@ -14,28 +14,32 @@ #include "ui/views/widget/widget.h" namespace arc { -gfx::RectF ToChromeScale(const gfx::Rect& bounds) { +gfx::RectF ScaleAndroidPxToChromePx(const gfx::Rect& android_bounds, + aura::Window* window) { DCHECK(exo::WMHelper::HasInstance()); - gfx::RectF bounds_f(bounds); - bounds_f.Scale(1.0f / - exo::WMHelper::GetInstance()->GetDefaultDeviceScaleFactor()); - return bounds_f; + DCHECK(window); + + const float chrome_dsf = + window->GetToplevelWindow()->layer()->device_scale_factor(); + const float android_dsf = + exo::WMHelper::GetInstance()->GetDeviceScaleFactorForWindow(window); + if (chrome_dsf == android_dsf) + return gfx::RectF(android_bounds); + + gfx::RectF chrome_bounds(android_bounds); + chrome_bounds.Scale(chrome_dsf / android_dsf); + return chrome_bounds; } -gfx::RectF ToChromeBounds(const gfx::Rect& bounds, views::Widget* widget) { - DCHECK(widget); - gfx::RectF chrome_bounds = ToChromeScale(bounds); - +int GetChromeWindowHeightOffsetInDip(aura::Window* window) { // On Android side, content is rendered without considering height of - // caption bar, e.g. Content is rendered at y:0 instead of y:32 where 32 is - // height of caption bar. Add back height of caption bar here. - if (widget->IsMaximized()) { - chrome_bounds.Offset( - 0, - widget->non_client_view()->frame_view()->GetBoundsForClientView().y()); - } + // caption bar when it's maximized, e.g. Content is rendered at y:0 instead of + // y:32 where 32 is height of caption bar. + views::Widget* widget = views::Widget::GetWidgetForNativeView(window); + if (!widget->IsMaximized()) + return 0; - return chrome_bounds; + return widget->non_client_view()->frame_view()->GetBoundsForClientView().y(); } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/accessibility/geometry_util.h b/chrome/browser/chromeos/arc/accessibility/geometry_util.h index 02786f02..24ccb4a 100644 --- a/chrome/browser/chromeos/arc/accessibility/geometry_util.h +++ b/chrome/browser/chromeos/arc/accessibility/geometry_util.h
@@ -11,18 +11,19 @@ class RectF; } -namespace views { -class Widget; +namespace aura { +class Window; } namespace arc { -// Given ARC pixels, returns DIPs in Chrome OS main display. -// This function only scales the bounds. -gfx::RectF ToChromeScale(const gfx::Rect& rect); +// Given a rect in Android pixels, returns a scaled rectangle in Chrome pixels. +// This only scales the given bounds. +gfx::RectF ScaleAndroidPxToChromePx(const gfx::Rect& android_bounds, + aura::Window* window); -// Given ARC pixels in screen coordinate, returns DIPs in Chrome OS main -// display. This function adjusts differences between ARC and Chrome. -gfx::RectF ToChromeBounds(const gfx::Rect& rect, views::Widget* widget); +// Returns an difference of y coordinate in DIP between Android internal bounds +// and what Chrome actually renders in the screen. +int GetChromeWindowHeightOffsetInDip(aura::Window* window); } // namespace arc #endif // CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_GEOMETRY_UTIL_H_
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc index 9da10281..dfbeb3a 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
@@ -229,10 +229,6 @@ int offset_pos) override { owner_->UpdateTextInputState(); } - void OnInputContextUpdate( - const ui::IMEEngineHandlerInterface::InputContext& context) override { - owner_->UpdateTextInputState(); - } void OnCandidateClicked( const std::string& component_id, int candidate_id,
diff --git a/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl_unittest.cc index ea0b7f1d..5c0c684 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl_unittest.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl_unittest.cc
@@ -43,8 +43,6 @@ int cursor_pos, int anchor_pos, int offset_pos) override {} - void OnInputContextUpdate( - const ui::IMEEngineHandlerInterface::InputContext& context) override {} void OnCandidateClicked( const std::string& component_id, int candidate_id,
diff --git a/chrome/browser/chromeos/bluetooth/debug_logs_manager.cc b/chrome/browser/chromeos/bluetooth/debug_logs_manager.cc index e64983f9..75eb71e 100644 --- a/chrome/browser/chromeos/bluetooth/debug_logs_manager.cc +++ b/chrome/browser/chromeos/bluetooth/debug_logs_manager.cc
@@ -29,6 +29,14 @@ DebugLogsManager::DebugLogsManager(const std::string& primary_user_email, PrefService* pref_service) : primary_user_email_(primary_user_email), pref_service_(pref_service) { + // For Googlers, set the default preference of Bluetooth verbose logs to true. + if (AreDebugLogsSupported() && + !pref_service->HasPrefPath(kVerboseLoggingEnablePrefName) && + base::FeatureList::IsEnabled( + chromeos::features::kEnableBluetoothVerboseLogsForGooglers)) { + ChangeDebugLogsState(true); + } + SetVerboseLogsEnable(GetDebugLogsState() == DebugLogsState::kSupportedAndEnabled); }
diff --git a/chrome/browser/chromeos/bluetooth/debug_logs_manager_unittest.cc b/chrome/browser/chromeos/bluetooth/debug_logs_manager_unittest.cc index 487cb21..d41611e 100644 --- a/chrome/browser/chromeos/bluetooth/debug_logs_manager_unittest.cc +++ b/chrome/browser/chromeos/bluetooth/debug_logs_manager_unittest.cc
@@ -49,9 +49,33 @@ bluez::BluezDBusManager::Shutdown(); } - void SetDebugFlagState(bool debug_flag_enabled) { - feature_list_.InitWithFeatureState( - chromeos::features::kShowBluetoothDebugLogToggle, debug_flag_enabled); + void EnableDebugFlag() { is_debug_toggle_flag_enabled_ = true; } + + void EnableGooglerDefaultPrefFlag() { + is_googler_default_pref_enabled_ = true; + } + + void InitFeatures() { + std::vector<base::Feature> enabled_features; + std::vector<base::Feature> disabled_features; + + if (is_debug_toggle_flag_enabled_) { + enabled_features.push_back( + chromeos::features::kShowBluetoothDebugLogToggle); + } else { + disabled_features.push_back( + chromeos::features::kShowBluetoothDebugLogToggle); + } + + if (is_googler_default_pref_enabled_) { + enabled_features.push_back( + chromeos::features::kEnableBluetoothVerboseLogsForGooglers); + } else { + disabled_features.push_back( + chromeos::features::kEnableBluetoothVerboseLogsForGooglers); + } + + feature_list_.InitWithFeatures(enabled_features, disabled_features); } void InstantiateDebugManager(const char* email) { @@ -69,6 +93,8 @@ private: base::test::ScopedFeatureList feature_list_; + bool is_debug_toggle_flag_enabled_ = false; + bool is_googler_default_pref_enabled_ = false; bluez::FakeBluetoothDebugManagerClient* fake_bluetooth_debug_manager_client_; std::unique_ptr<DebugLogsManager> debug_logs_manager_; TestingPrefServiceSimple prefs_; @@ -77,21 +103,33 @@ }; TEST_F(DebugLogsManagerTest, FlagNotEnabled) { - SetDebugFlagState(false /* debug_flag_enabled */); + /* debug flag disabled */ + InitFeatures(); InstantiateDebugManager(kTestGooglerEmail); EXPECT_EQ(debug_manager()->GetDebugLogsState(), DebugLogsManager::DebugLogsState::kNotSupported); } TEST_F(DebugLogsManagerTest, NonGoogler) { - SetDebugFlagState(true /* debug_flag_enabled */); + EnableDebugFlag(); + InitFeatures(); InstantiateDebugManager(kTestNonGooglerEmail); EXPECT_EQ(debug_manager()->GetDebugLogsState(), DebugLogsManager::DebugLogsState::kNotSupported); } +TEST_F(DebugLogsManagerTest, GooglerDefaultPref) { + EnableDebugFlag(); + EnableGooglerDefaultPrefFlag(); + InitFeatures(); + InstantiateDebugManager(kTestGooglerEmail); + EXPECT_EQ(debug_manager()->GetDebugLogsState(), + DebugLogsManager::DebugLogsState::kSupportedAndEnabled); +} + TEST_F(DebugLogsManagerTest, ChangeDebugLogsState) { - SetDebugFlagState(true /* debug_flag_enabled */); + EnableDebugFlag(); + InitFeatures(); InstantiateDebugManager(kTestGooglerEmail); EXPECT_EQ(debug_manager()->GetDebugLogsState(), DebugLogsManager::DebugLogsState::kSupportedButDisabled); @@ -119,7 +157,8 @@ } TEST_F(DebugLogsManagerTest, SendVerboseLogsRequestUponLoginAndLogout) { - SetDebugFlagState(true /* debug_flag_enabled */); + EnableDebugFlag(); + InitFeatures(); InstantiateDebugManager(kTestGooglerEmail); EXPECT_EQ(fake_bluetooth_debug_manager_client()->bluez_level(), 0); debug_manager()->ChangeDebugLogsState( @@ -156,7 +195,8 @@ base::test::TaskEnvironment task_environment{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - SetDebugFlagState(true /* debug_flag_enabled */); + EnableDebugFlag(); + InitFeatures(); InstantiateDebugManager(kTestGooglerEmail); EXPECT_EQ(fake_bluetooth_debug_manager_client()->bluez_level(), 0); debug_manager()->ChangeDebugLogsState(
diff --git a/chrome/browser/chromeos/crosapi/browser_loader.cc b/chrome/browser/chromeos/crosapi/browser_loader.cc index 393e8fd..ed73b6f 100644 --- a/chrome/browser/chromeos/crosapi/browser_loader.cc +++ b/chrome/browser/chromeos/crosapi/browser_loader.cc
@@ -52,7 +52,7 @@ BrowserLoader::~BrowserLoader() = default; void BrowserLoader::Load(LoadCompletionCallback callback) { - DCHECK(browser_util::IsLacrosAllowed()); + DCHECK(browser_util::IsLacrosEnabled()); // TODO(crbug.com/1078607): Remove non-error logging from this class. LOG(WARNING) << "Starting lacros component load."; @@ -78,7 +78,7 @@ } void BrowserLoader::Unload() { - DCHECK(browser_util::IsLacrosAllowed()); + // Can be called even if Lacros isn't enabled, to clean up the old install. base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce(&CheckInstalledAndMaybeRemoveUserDirectory,
diff --git a/chrome/browser/chromeos/crosapi/browser_manager.cc b/chrome/browser/chromeos/crosapi/browser_manager.cc index b18db7f..b1c292f 100644 --- a/chrome/browser/chromeos/crosapi/browser_manager.cc +++ b/chrome/browser/chromeos/crosapi/browser_manager.cc
@@ -37,7 +37,6 @@ #include "chrome/browser/component_updater/cros_component_manager.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "components/prefs/pref_service.h" #include "components/session_manager/core/session_manager.h" @@ -203,7 +202,7 @@ } void BrowserManager::NewWindow() { - if (!browser_util::IsLacrosAllowed()) + if (!browser_util::IsLacrosEnabled()) return; if (!IsReady()) { @@ -438,17 +437,15 @@ // Ensure this isn't run multiple times. session_manager::SessionManager::Get()->RemoveObserver(this); - // Must be checked after user session start because it depends on user type. - if (!browser_util::IsLacrosAllowed()) - return; - // May be null in tests. if (!component_manager_) return; DCHECK(!browser_loader_); browser_loader_ = std::make_unique<BrowserLoader>(component_manager_); - if (chromeos::features::IsLacrosSupportEnabled()) { + + // Must be checked after user session start because it depends on user type. + if (browser_util::IsLacrosEnabled()) { state_ = State::LOADING; browser_loader_->Load(base::BindOnce(&BrowserManager::OnLoadComplete, weak_factory_.GetWeakPtr()));
diff --git a/chrome/browser/chromeos/crosapi/browser_util.cc b/chrome/browser/chromeos/crosapi/browser_util.cc index b58c71a..428c6ca 100644 --- a/chrome/browser/chromeos/crosapi/browser_util.cc +++ b/chrome/browser/chromeos/crosapi/browser_util.cc
@@ -21,6 +21,7 @@ #include "chrome/common/channel_info.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/crosapi/cpp/crosapi_constants.h" #include "chromeos/crosapi/mojom/crosapi.mojom.h" #include "components/exo/shell_surface_util.h" @@ -107,11 +108,14 @@ return base_path.Append("lacros"); } -bool IsLacrosAllowed() { - return IsLacrosAllowed(chrome::GetChannel()); +bool IsLacrosEnabled() { + return IsLacrosEnabled(chrome::GetChannel()); } -bool IsLacrosAllowed(Channel channel) { +bool IsLacrosEnabled(Channel channel) { + if (!base::FeatureList::IsEnabled(chromeos::features::kLacrosSupport)) + return false; + const User* user = user_manager::UserManager::Get()->GetPrimaryUser(); if (!user) return false;
diff --git a/chrome/browser/chromeos/crosapi/browser_util.h b/chrome/browser/chromeos/crosapi/browser_util.h index 76c10895..9af0e72b 100644 --- a/chrome/browser/chromeos/crosapi/browser_util.h +++ b/chrome/browser/chromeos/crosapi/browser_util.h
@@ -44,12 +44,12 @@ // Returns the user directory for lacros-chrome. base::FilePath GetUserDataDir(); -// Returns true if lacros is allowed for the current user type, chrome channel, -// etc. -bool IsLacrosAllowed(); +// Returns true if the Lacros feature is enabled and Lacros is allowed for the +// current user type, chrome channel, and enterprise policy. +bool IsLacrosEnabled(); // As above, but takes a channel. Exposed for testing. -bool IsLacrosAllowed(version_info::Channel channel); +bool IsLacrosEnabled(version_info::Channel channel); // Returns true if |window| is an exo ShellSurface window representing a Lacros // browser.
diff --git a/chrome/browser/chromeos/crosapi/browser_util_unittest.cc b/chrome/browser/chromeos/crosapi/browser_util_unittest.cc index 54cfb54..21023c55 100644 --- a/chrome/browser/chromeos/crosapi/browser_util_unittest.cc +++ b/chrome/browser/chromeos/crosapi/browser_util_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/chromeos/crosapi/browser_util.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -13,6 +14,7 @@ #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/crosapi/mojom/crosapi.mojom.h" #include "components/account_id/account_id.h" #include "components/user_manager/scoped_user_manager.h" @@ -56,41 +58,61 @@ ScopedTestingLocalState local_state_; }; -TEST_F(LacrosUtilTest, ChannelTest) { +TEST_F(LacrosUtilTest, LacrosEnabledByFlag) { AddRegularUser("user@test.com"); - EXPECT_TRUE(browser_util::IsLacrosAllowed(Channel::UNKNOWN)); - EXPECT_TRUE(browser_util::IsLacrosAllowed(Channel::CANARY)); - EXPECT_TRUE(browser_util::IsLacrosAllowed(Channel::DEV)); - EXPECT_TRUE(browser_util::IsLacrosAllowed(Channel::BETA)); - EXPECT_FALSE(browser_util::IsLacrosAllowed(Channel::STABLE)); + // Lacros is disabled because the feature isn't enabled by default. + EXPECT_FALSE(browser_util::IsLacrosEnabled()); + + // Enabling the flag enables Lacros. + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(chromeos::features::kLacrosSupport); + EXPECT_TRUE(browser_util::IsLacrosEnabled()); } -TEST_F(LacrosUtilTest, ManagedAccountLacrosAllowed) { +TEST_F(LacrosUtilTest, ChannelTest) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(chromeos::features::kLacrosSupport); + AddRegularUser("user@test.com"); + + EXPECT_TRUE(browser_util::IsLacrosEnabled(Channel::UNKNOWN)); + EXPECT_TRUE(browser_util::IsLacrosEnabled(Channel::CANARY)); + EXPECT_TRUE(browser_util::IsLacrosEnabled(Channel::DEV)); + EXPECT_TRUE(browser_util::IsLacrosEnabled(Channel::BETA)); + EXPECT_FALSE(browser_util::IsLacrosEnabled(Channel::STABLE)); +} + +TEST_F(LacrosUtilTest, ManagedAccountLacrosEnabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(chromeos::features::kLacrosSupport); AddRegularUser("user@managedchrome.com"); testing_profile_.GetProfilePolicyConnector()->OverrideIsManagedForTesting( true); g_browser_process->local_state()->SetBoolean(prefs::kLacrosAllowed, true); - EXPECT_TRUE(browser_util::IsLacrosAllowed(Channel::CANARY)); + EXPECT_TRUE(browser_util::IsLacrosEnabled(Channel::CANARY)); } -TEST_F(LacrosUtilTest, ManagedAccountLacrosNotAllowed) { +TEST_F(LacrosUtilTest, ManagedAccountLacrosDisabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(chromeos::features::kLacrosSupport); AddRegularUser("user@managedchrome.com"); testing_profile_.GetProfilePolicyConnector()->OverrideIsManagedForTesting( true); g_browser_process->local_state()->SetBoolean(prefs::kLacrosAllowed, false); - EXPECT_FALSE(browser_util::IsLacrosAllowed(Channel::CANARY)); + EXPECT_FALSE(browser_util::IsLacrosEnabled(Channel::CANARY)); } TEST_F(LacrosUtilTest, BlockedForChildUser) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(chromeos::features::kLacrosSupport); AccountId account_id = AccountId::FromUserEmail("user@test.com"); const User* user = fake_user_manager_->AddChildUser(account_id); fake_user_manager_->UserLoggedIn(account_id, user->username_hash(), /*browser_restart=*/false, /*is_child=*/true); - EXPECT_FALSE(browser_util::IsLacrosAllowed(Channel::UNKNOWN)); + EXPECT_FALSE(browser_util::IsLacrosEnabled(Channel::UNKNOWN)); } TEST_F(LacrosUtilTest, GetInterfaceVersions) {
diff --git a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc index 4a7ca7a..4300f79 100644 --- a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc +++ b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
@@ -808,8 +808,9 @@ FLAGS_USE_FILE_HANDLER)) << message_; } +// Failing: http://crbug.com/1150689 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, - FileBrowserHandlersLazy) { + DISABLED_FileBrowserHandlersLazy) { EXPECT_TRUE(RunFileSystemExtensionApiTest( "file_browser/handler_test_runner", FILE_PATH_LITERAL("manifest.json"),
diff --git a/chrome/browser/chromeos/input_method/DEPS b/chrome/browser/chromeos/input_method/DEPS index 9b133f0..08fcf878 100644 --- a/chrome/browser/chromeos/input_method/DEPS +++ b/chrome/browser/chromeos/input_method/DEPS
@@ -53,7 +53,7 @@ # TODO: This should not be an allowed dep; see # http://crbug.com/1148093 and # http://b/173144152. - "(assistive_window_controller|personal_info_suggester)\.h": [ + "tts_handler\.h": [ "!content/public/browser/tts_controller.h", ],
diff --git a/chrome/browser/chromeos/input_method/assistive_window_controller.cc b/chrome/browser/chromeos/input_method/assistive_window_controller.cc index cf54f26..4e56ea2 100644 --- a/chrome/browser/chromeos/input_method/assistive_window_controller.cc +++ b/chrome/browser/chromeos/input_method/assistive_window_controller.cc
@@ -7,7 +7,6 @@ #include <string> #include <vector> -#include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/wm/window_util.h" @@ -16,7 +15,6 @@ #include "chrome/browser/chromeos/input_method/ui/suggestion_details.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" #include "ui/base/ime/chromeos/ime_bridge.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/widget/widget.h" @@ -45,39 +43,6 @@ } // namespace -TtsHandler::TtsHandler(Profile* profile) : profile_(profile) {} -TtsHandler::~TtsHandler() = default; - -void TtsHandler::Announce(const std::string& text, - const base::TimeDelta delay) { - const bool chrome_vox_enabled = profile_->GetPrefs()->GetBoolean( - ash::prefs::kAccessibilitySpokenFeedbackEnabled); - if (!chrome_vox_enabled) - return; - - delay_timer_ = std::make_unique<base::OneShotTimer>(); - delay_timer_->Start( - FROM_HERE, delay, - base::BindOnce(&TtsHandler::Speak, base::Unretained(this), text)); -} - -void TtsHandler::OnTtsEvent(content::TtsUtterance* utterance, - content::TtsEventType event_type, - int char_index, - int length, - const std::string& error_message) {} - -void TtsHandler::Speak(const std::string& text) { - std::unique_ptr<content::TtsUtterance> utterance = - content::TtsUtterance::Create(profile_); - utterance->SetText(text); - utterance->SetEventDelegate(this); - utterance->SetCanEnqueue(true); - - auto* tts_controller = content::TtsController::GetInstance(); - tts_controller->SpeakOrEnqueue(std::move(utterance)); -} - AssistiveWindowController::AssistiveWindowController( AssistiveWindowControllerDelegate* delegate, Profile* profile,
diff --git a/chrome/browser/chromeos/input_method/assistive_window_controller.h b/chrome/browser/chromeos/input_method/assistive_window_controller.h index 7023452..c3d9a01 100644 --- a/chrome/browser/chromeos/input_method/assistive_window_controller.h +++ b/chrome/browser/chromeos/input_method/assistive_window_controller.h
@@ -9,10 +9,10 @@ #include "base/macros.h" #include "chrome/browser/chromeos/input_method/assistive_window_properties.h" +#include "chrome/browser/chromeos/input_method/tts_handler.h" #include "chrome/browser/chromeos/input_method/ui/assistive_delegate.h" #include "chrome/browser/chromeos/input_method/ui/suggestion_window_view.h" #include "chrome/browser/chromeos/input_method/ui/undo_window.h" -#include "content/public/browser/tts_controller.h" #include "ui/base/ime/chromeos/ime_assistive_window_handler_interface.h" #include "ui/gfx/native_widget_types.h" @@ -26,31 +26,6 @@ namespace input_method { -class TtsHandler : public content::UtteranceEventDelegate { - public: - explicit TtsHandler(Profile* profile); - ~TtsHandler() override; - - // Announce |text| after some |delay|. The delay is to avoid conflict with - // other ChromeVox announcements. This should be no-op if ChromeVox is not - // enabled. - void Announce(const std::string& text, - const base::TimeDelta delay = base::TimeDelta()); - - // UtteranceEventDelegate implementation. - void OnTtsEvent(content::TtsUtterance* utterance, - content::TtsEventType event_type, - int char_index, - int length, - const std::string& error_message) override; - - private: - virtual void Speak(const std::string& text); - - Profile* const profile_; - std::unique_ptr<base::OneShotTimer> delay_timer_; -}; - class AssistiveWindowControllerDelegate; // AssistiveWindowController controls different assistive windows.
diff --git a/chrome/browser/chromeos/input_method/autocorrect_manager.cc b/chrome/browser/chromeos/input_method/autocorrect_manager.cc index dbee079..26dd60e 100644 --- a/chrome/browser/chromeos/input_method/autocorrect_manager.cc +++ b/chrome/browser/chromeos/input_method/autocorrect_manager.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/chromeos/input_method/autocorrect_manager.h" +#include "base/metrics/histogram_functions.h" #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/input_method/assistive_window_properties.h" @@ -12,6 +13,24 @@ #include "ui/base/ime/chromeos/ime_input_context_handler_interface.h" #include "ui/base/l10n/l10n_util.h" +namespace { + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. Needs to match ImeAutocorrectActions +// in enums.xml. +enum class AutocorrectActions { + kWindowShown = 0, + kUnderlined = 1, + kMaxValue = kUnderlined, +}; + +void LogAssistiveAutocorrectAction(AutocorrectActions action) { + base::UmaHistogramEnumeration("InputMethod.Assistive.Autocorrect.Actions", + action); +} + +} // namespace + namespace chromeos { constexpr int kKeysUntilAutocorrectWindowHides = 4; @@ -36,6 +55,7 @@ input_context->SetAutocorrectRange(base::UTF8ToUTF16(corrected_word), start_index, start_index + corrected_word.length()); + LogAssistiveAutocorrectAction(AutocorrectActions::kUnderlined); } } @@ -99,6 +119,7 @@ button_highlighted = false; suggestion_handler_->SetAssistiveWindowProperties(context_id_, properties, &error); + LogAssistiveAutocorrectAction(AutocorrectActions::kWindowShown); } key_presses_until_underline_hide_ = kKeysUntilAutocorrectWindowHides; } else if (window_visible) {
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_base.h b/chrome/browser/chromeos/input_method/input_method_engine_base.h index 3fd9269..0d8503ed 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_base.h +++ b/chrome/browser/chromeos/input_method/input_method_engine_base.h
@@ -108,10 +108,6 @@ int anchor_pos, int offset_pos) = 0; - // Called when an InputContext's properties change while it is focused. - virtual void OnInputContextUpdate( - const IMEEngineHandlerInterface::InputContext& context) = 0; - // Called when the user clicks on an item in the candidate list. virtual void OnCandidateClicked( const std::string& component_id,
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc index f822341..982e692 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -102,8 +102,6 @@ ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback) override { std::move(callback).Run(/* handled */ true); } - void OnInputContextUpdate( - const ui::IMEEngineHandlerInterface::InputContext& context) override {} void OnCandidateClicked( const std::string& engine_id, int candidate_id,
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine.cc b/chrome/browser/chromeos/input_method/native_input_method_engine.cc index 5a87835..55f16206 100644 --- a/chrome/browser/chromeos/input_method/native_input_method_engine.cc +++ b/chrome/browser/chromeos/input_method/native_input_method_engine.cc
@@ -333,11 +333,6 @@ anchor_pos, offset_pos); } -void NativeInputMethodEngine::ImeObserver::OnInputContextUpdate( - const IMEEngineHandlerInterface::InputContext& context) { - base_observer_->OnInputContextUpdate(context); -} - void NativeInputMethodEngine::ImeObserver::OnCandidateClicked( const std::string& component_id, int candidate_id,
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine.h b/chrome/browser/chromeos/input_method/native_input_method_engine.h index d72bed68..05fe3f8 100644 --- a/chrome/browser/chromeos/input_method/native_input_method_engine.h +++ b/chrome/browser/chromeos/input_method/native_input_method_engine.h
@@ -85,8 +85,6 @@ int cursor_pos, int anchor_pos, int offset_pos) override; - void OnInputContextUpdate( - const IMEEngineHandlerInterface::InputContext& context) override; void OnCandidateClicked( const std::string& component_id, int candidate_id,
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc b/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc index 6448ddf5..12b84daf 100644 --- a/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc +++ b/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc
@@ -69,8 +69,6 @@ ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback) override { std::move(callback).Run(/*handled=*/false); } - void OnInputContextUpdate( - const ui::IMEEngineHandlerInterface::InputContext& context) override {} void OnCandidateClicked( const std::string& engine_id, int candidate_id,
diff --git a/chrome/browser/chromeos/input_method/personal_info_suggester.cc b/chrome/browser/chromeos/input_method/personal_info_suggester.cc index cb0bf79..727c884ae 100644 --- a/chrome/browser/chromeos/input_method/personal_info_suggester.cc +++ b/chrome/browser/chromeos/input_method/personal_info_suggester.cc
@@ -6,7 +6,6 @@ #include "chrome/browser/chromeos/extensions/input_method_api.h" #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" -#include "ash/public/cpp/ash_pref_names.h" #include "base/feature_list.h" #include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" @@ -23,7 +22,6 @@ #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/ui/label_formatter_utils.h" -#include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/strings/grit/components_strings.h" #include "third_party/re2/src/re2/re2.h" @@ -96,39 +94,6 @@ } // namespace -TtsHandler::TtsHandler(Profile* profile) : profile_(profile) {} -TtsHandler::~TtsHandler() = default; - -void TtsHandler::Announce(const std::string& text, - const base::TimeDelta delay) { - const bool chrome_vox_enabled = profile_->GetPrefs()->GetBoolean( - ash::prefs::kAccessibilitySpokenFeedbackEnabled); - if (!chrome_vox_enabled) - return; - - delay_timer_ = std::make_unique<base::OneShotTimer>(); - delay_timer_->Start( - FROM_HERE, delay, - base::BindOnce(&TtsHandler::Speak, base::Unretained(this), text)); -} - -void TtsHandler::OnTtsEvent(content::TtsUtterance* utterance, - content::TtsEventType event_type, - int char_index, - int length, - const std::string& error_message) {} - -void TtsHandler::Speak(const std::string& text) { - std::unique_ptr<content::TtsUtterance> utterance = - content::TtsUtterance::Create(profile_); - utterance->SetText(text); - utterance->SetEventDelegate(this); - utterance->SetCanEnqueue(true); - - auto* tts_controller = content::TtsController::GetInstance(); - tts_controller->SpeakOrEnqueue(std::move(utterance)); -} - AssistiveType ProposePersonalInfoAssistiveAction(const base::string16& text) { std::string lower_case_utf8_text = base::ToLowerASCII(base::UTF16ToUTF8(text));
diff --git a/chrome/browser/chromeos/input_method/personal_info_suggester.h b/chrome/browser/chromeos/input_method/personal_info_suggester.h index 9c0f5fab..d4675b8c 100644 --- a/chrome/browser/chromeos/input_method/personal_info_suggester.h +++ b/chrome/browser/chromeos/input_method/personal_info_suggester.h
@@ -13,8 +13,8 @@ #include "chrome/browser/chromeos/input_method/suggester.h" #include "chrome/browser/chromeos/input_method/suggestion_enums.h" #include "chrome/browser/chromeos/input_method/suggestion_handler_interface.h" +#include "chrome/browser/chromeos/input_method/tts_handler.h" #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" -#include "content/public/browser/tts_controller.h" namespace autofill { class PersonalDataManager; @@ -33,31 +33,6 @@ AssistiveType ProposePersonalInfoAssistiveAction(const base::string16& text); -class TtsHandler : public content::UtteranceEventDelegate { - public: - explicit TtsHandler(Profile* profile); - ~TtsHandler() override; - - // Announce |text| after some |delay|. The delay is to avoid conflict with - // other ChromeVox announcements. This should be no-op if ChromeVox is not - // enabled. - void Announce(const std::string& text, - const base::TimeDelta delay = base::TimeDelta()); - - // UtteranceEventDelegate implementation. - void OnTtsEvent(content::TtsUtterance* utterance, - content::TtsEventType event_type, - int char_index, - int length, - const std::string& error_message) override; - - private: - virtual void Speak(const std::string& text); - - Profile* const profile_; - std::unique_ptr<base::OneShotTimer> delay_timer_; -}; - // An agent to suggest personal information when the user types, and adopt or // dismiss the suggestion according to the user action. class PersonalInfoSuggester : public Suggester {
diff --git a/chrome/browser/chromeos/input_method/stub_input_method_engine_observer.h b/chrome/browser/chromeos/input_method/stub_input_method_engine_observer.h index f9d87f1..070f35a 100644 --- a/chrome/browser/chromeos/input_method/stub_input_method_engine_observer.h +++ b/chrome/browser/chromeos/input_method/stub_input_method_engine_observer.h
@@ -26,8 +26,6 @@ const std::string& engine_id, const InputMethodEngineBase::KeyboardEvent& event, ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback) override {} - void OnInputContextUpdate( - const ui::IMEEngineHandlerInterface::InputContext& context) override {} void OnCandidateClicked( const std::string& engine_id, int candidate_id,
diff --git a/chrome/browser/chromeos/input_method/tts_handler.cc b/chrome/browser/chromeos/input_method/tts_handler.cc new file mode 100644 index 0000000..b6390ef5 --- /dev/null +++ b/chrome/browser/chromeos/input_method/tts_handler.cc
@@ -0,0 +1,44 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/input_method/tts_handler.h" + +#include "ash/public/cpp/ash_pref_names.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "components/prefs/pref_service.h" + +namespace chromeos { +TtsHandler::TtsHandler(Profile* profile) : profile_(profile) {} +TtsHandler::~TtsHandler() = default; + +void TtsHandler::Announce(const std::string& text, + const base::TimeDelta delay) { + const bool chrome_vox_enabled = profile_->GetPrefs()->GetBoolean( + ash::prefs::kAccessibilitySpokenFeedbackEnabled); + if (!chrome_vox_enabled) + return; + + delay_timer_ = std::make_unique<base::OneShotTimer>(); + delay_timer_->Start( + FROM_HERE, delay, + base::BindOnce(&TtsHandler::Speak, base::Unretained(this), text)); +} + +void TtsHandler::OnTtsEvent(content::TtsUtterance* utterance, + content::TtsEventType event_type, + int char_index, + int length, + const std::string& error_message) {} + +void TtsHandler::Speak(const std::string& text) { + std::unique_ptr<content::TtsUtterance> utterance = + content::TtsUtterance::Create(profile_); + utterance->SetText(text); + utterance->SetEventDelegate(this); + utterance->SetCanEnqueue(true); + + auto* tts_controller = content::TtsController::GetInstance(); + tts_controller->SpeakOrEnqueue(std::move(utterance)); +} +} // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/tts_handler.h b/chrome/browser/chromeos/input_method/tts_handler.h new file mode 100644 index 0000000..705a9bc --- /dev/null +++ b/chrome/browser/chromeos/input_method/tts_handler.h
@@ -0,0 +1,43 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_TTS_HANDLER_H_ +#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_TTS_HANDLER_H_ + +#include <string> + +#include "base/timer/timer.h" +#include "content/public/browser/tts_controller.h" + +class Profile; + +namespace chromeos { + +class TtsHandler : public content::UtteranceEventDelegate { + public: + explicit TtsHandler(Profile* profile); + ~TtsHandler() override; + + // Announce |text| after some |delay|. The delay is to avoid conflict with + // other ChromeVox announcements. This should be no-op if ChromeVox is not + // enabled. + void Announce(const std::string& text, + const base::TimeDelta delay = base::TimeDelta()); + + // UtteranceEventDelegate implementation. + void OnTtsEvent(content::TtsUtterance* utterance, + content::TtsEventType event_type, + int char_index, + int length, + const std::string& error_message) override; + + private: + virtual void Speak(const std::string& text); + + Profile* const profile_; + std::unique_ptr<base::OneShotTimer> delay_timer_; +}; +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_TTS_HANDLER_H_
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 06b5fa7..8c5e520e 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -782,15 +782,9 @@ if (user_is_active) { pointing_stick_settings.SetSensitivity(sensitivity_int); } - system::PointerSensitivity sensitivity = - static_cast<system::PointerSensitivity>(sensitivity_int); - if (reason == REASON_PREF_CHANGED) { - base::UmaHistogramEnumeration("PointingStick.PointerSensitivity.Changed", - sensitivity); - } else if (reason == REASON_INITIALIZATION) { - base::UmaHistogramEnumeration("PointingStick.PointerSensitivity.Started", - sensitivity); - } + ReportSensitivityPrefApplication( + reason, "PointingStick.PointerSensitivity.Changed", + "PointingStick.PointerSensitivity.Started", sensitivity_int); } if (reason != REASON_PREF_CHANGED || pref_name == ::prefs::kTouchpadSensitivity) {
diff --git a/chrome/browser/exo_parts.cc b/chrome/browser/exo_parts.cc index 2c115294a..39a5108 100644 --- a/chrome/browser/exo_parts.cc +++ b/chrome/browser/exo_parts.cc
@@ -180,6 +180,10 @@ bool is_plugin_vm = plugin_vm::IsPluginVmAppWindow(toplevel); std::string lines(data.begin(), data.end()); std::vector<ui::FileInfo> filenames; + // Until we have mapping for other VMs, only accept from arc. + if (!IsArcWindow(source)) + return filenames; + base::FilePath path; storage::FileSystemURL url; for (const base::StringPiece& line : base::SplitStringPiece(
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc index b494048..0e2ed41 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc +++ b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
@@ -162,25 +162,6 @@ ~ImeObserverChromeOS() override = default; // chromeos::InputMethodEngineBase::Observer overrides. - void OnInputContextUpdate( - const IMEEngineHandlerInterface::InputContext& context) override { - if (extension_id_.empty() || - !HasListener(input_ime::OnInputContextUpdate::kEventName)) - return; - - input_ime::InputContext context_value; - context_value.context_id = context.id; - context_value.type = - input_ime::ParseInputContextType(ConvertInputContextType(context)); - - std::unique_ptr<base::ListValue> args( - input_ime::OnInputContextUpdate::Create(context_value)); - - DispatchEventToExtension( - extensions::events::INPUT_IME_ON_INPUT_CONTEXT_UPDATE, - input_ime::OnInputContextUpdate::kEventName, std::move(args)); - } - void OnCandidateClicked( const std::string& component_id, int candidate_id,
diff --git a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc index 9317561..4d09c1f 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
@@ -76,12 +76,12 @@ } #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) -void BindTtsStream( +void BindTtsStreamFactory( content::RenderFrameHost* render_frame_host, - mojo::PendingReceiver<chromeos::tts::mojom::TtsStream> receiver) { + mojo::PendingReceiver<chromeos::tts::mojom::TtsStreamFactory> receiver) { TtsEngineExtensionObserverChromeOS::GetInstance( Profile::FromBrowserContext(render_frame_host->GetBrowserContext())) - ->BindTtsStream(std::move(receiver)); + ->BindTtsStreamFactory(std::move(receiver)); } void BindRemoteAppsFactory( @@ -168,9 +168,11 @@ base::BindRepeating(&chromeos::CameraAppUI::ConnectToCameraAppHelper)); } - if (extension->id() == extension_misc::kGoogleSpeechSynthesisExtensionId) { - binder_map->Add<chromeos::tts::mojom::TtsStream>( - base::BindRepeating(&BindTtsStream)); + // TODO: extend to more extensions. + if (extension->id() == extension_misc::kGoogleSpeechSynthesisExtensionId || + extension->id() == extension_misc::kEspeakSpeechSynthesisExtensionId) { + binder_map->Add<chromeos::tts::mojom::TtsStreamFactory>( + base::BindRepeating(&BindTtsStreamFactory)); } if (chromeos::RemoteAppsImpl::IsAllowed(render_frame_host, extension)) {
diff --git a/chrome/browser/feedback/system_logs/chrome_system_logs_fetcher.cc b/chrome/browser/feedback/system_logs/chrome_system_logs_fetcher.cc index 01d72fc4..528e746 100644 --- a/chrome/browser/feedback/system_logs/chrome_system_logs_fetcher.cc +++ b/chrome/browser/feedback/system_logs/chrome_system_logs_fetcher.cc
@@ -27,7 +27,6 @@ #include "chrome/browser/chromeos/system_logs/shill_log_source.h" #include "chrome/browser/chromeos/system_logs/touch_log_source.h" #include "chrome/browser/chromeos/system_logs/ui_hierarchy_log_source.h" -#include "chromeos/constants/chromeos_features.h" #endif #if defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS) @@ -82,8 +81,7 @@ #endif #if defined(OS_CHROMEOS) - if (chromeos::features::IsLacrosSupportEnabled() && - crosapi::browser_util::IsLacrosAllowed()) { + if (crosapi::browser_util::IsLacrosEnabled()) { fetcher->AddSource(std::make_unique<UserLogFilesLogSource>( base::FilePath(kDefaultLogPath), kLacrosUserLogKey)); }
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc index 3267d8a5..834b8a2 100644 --- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc +++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -51,7 +51,6 @@ #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/metrics/chromeos_metrics_provider.h" #include "chrome/browser/metrics/enrollment_status.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/dbus/util/version_loader.h" #include "chromeos/settings/cros_settings_names.h" #include "chromeos/system/statistics_provider.h" @@ -257,8 +256,7 @@ // is indicated by |lacros_version| in BrowserManager being set to non-empty // string during lacros startup, attach its version in the chrome // version string. - if (chromeos::features::IsLacrosSupportEnabled() && - crosapi::browser_util::IsLacrosAllowed() && + if (crosapi::browser_util::IsLacrosEnabled() && !crosapi::BrowserManager::Get()->lacros_version().empty()) { std::string lacros_version = crosapi::BrowserManager::Get()->lacros_version();
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index c08edc3..21f011a 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -499,7 +499,7 @@ { "name": "chrome-share-screenshot", "owners": [ "jeffreycohen", "kristipark" ], - "expiry_milestone": 88 + "expiry_milestone": 90 }, { "name": "chrome-sharing-hub", @@ -894,6 +894,13 @@ "expiry_milestone": -1 }, { + "name": "disable-buffer-bw-compression", + "owners": [ "chromeos-gfx@google.com" ], + // This flag is used for QA & debugging on ChromeOS, which has no way to + // customize switches. + "expiry_milestone": -1 + }, + { "name": "disable-camera-frame-rotation-at-source", "owners": [ "chromeos-camera-eng@google.com" ], "expiry_milestone": 88 @@ -1307,6 +1314,11 @@ "expiry_milestone": 90 }, { + "name": "enable-bluetooth-verbose-logs-for-googlers", + "owners": [ "sonnysasaka" ], + "expiry_milestone": 90 + }, + { "name": "enable-browsing-data-lifetime-manager", "owners": ["ydago"], "expiry_milestone": 91 @@ -2557,7 +2569,7 @@ { "name": "files-ng", "owners": [ "adanilo", "noel" ], - "expiry_milestone": 88 + "expiry_milestone": 91 }, { "name": "files-single-partition-format",
diff --git a/chrome/browser/flag-never-expire-list.json b/chrome/browser/flag-never-expire-list.json index 354109d9..951532a 100644 --- a/chrome/browser/flag-never-expire-list.json +++ b/chrome/browser/flag-never-expire-list.json
@@ -22,6 +22,7 @@ "disable-accelerated-mjpeg-decode", "disable-accelerated-video-decode", "disable-accelerated-video-encode", + "disable-buffer-bw-compression", "disable-explicit-dma-fences", "disable-javascript-harmony-shipping", "disable-threaded-scrolling",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 76faf140..ea24142 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3779,6 +3779,11 @@ const char kCryptAuthV2EnrollmentDescription[] = "Use the CryptAuth v2 Enrollment protocol."; +const char kDisableBufferBWCompressionName[] = + "Disable buffer bandwidth compression"; +const char kDisableBufferBWCompressionDescription[] = + "Disable bandwidth compression when allocating buffers"; + const char kDisableCameraFrameRotationAtSourceName[] = "Disable camera frame rotation at source"; const char kDisableCameraFrameRotationAtSourceDescription[] = @@ -4410,6 +4415,11 @@ "Enables a toggle which can enable debug (i.e., verbose) logs for " "Bluetooth"; +const char kEnableBluetoothVerboseLogsForGooglersName[] = + "Enable Bluetooth verbose logs for Googlers"; +const char kEnableBluetoothVerboseLogsForGooglersDescription[] = + "Enables Bluetooth verbose logs for Googlers in feedback reports."; + const char kShowBluetoothDeviceBatteryName[] = "Show Bluetooth device battery"; const char kShowBluetoothDeviceBatteryDescription[] = "Enables showing the battery level of connected and supported Bluetooth "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 74b92a4..b82f41b 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2194,6 +2194,9 @@ extern const char kCryptAuthV2EnrollmentName[]; extern const char kCryptAuthV2EnrollmentDescription[]; +extern const char kDisableBufferBWCompressionName[]; +extern const char kDisableBufferBWCompressionDescription[]; + extern const char kDisableCameraFrameRotationAtSourceName[]; extern const char kDisableCameraFrameRotationAtSourceDescription[]; @@ -2581,6 +2584,9 @@ extern const char kShowBluetoothDebugLogToggleName[]; extern const char kShowBluetoothDebugLogToggleDescription[]; +extern const char kEnableBluetoothVerboseLogsForGooglersName[]; +extern const char kEnableBluetoothVerboseLogsForGooglersDescription[]; + extern const char kShowBluetoothDeviceBatteryName[]; extern const char kShowBluetoothDeviceBatteryDescription[];
diff --git a/chrome/browser/metrics/ambient_mode_metrics_provider.cc b/chrome/browser/metrics/ambient_mode_metrics_provider.cc index 0074447a..da1deac8 100644 --- a/chrome/browser/metrics/ambient_mode_metrics_provider.cc +++ b/chrome/browser/metrics/ambient_mode_metrics_provider.cc
@@ -34,11 +34,15 @@ void AmbientModeMetricsProvider::ProvideCurrentSessionData( metrics::ChromeUserMetricsExtension* uma_proto_unused) { - if (!chromeos::features::IsAmbientModeEnabled() || - !ash::AmbientClient::Get()->IsAmbientModeAllowed()) { + if (!chromeos::features::IsAmbientModeEnabled()) return; - } + auto* ambient_client = ash::AmbientClient::Get(); + if (!ambient_client || !ambient_client->IsAmbientModeAllowed()) + return; + + // |IsAmbientModeAllowed| guarantees a valid profile exists for the active + // user. PrefService* pref_service = ProfileManager::GetActiveUserProfile()->GetPrefs(); DCHECK(pref_service);
diff --git a/chrome/browser/nearby_sharing/sharesheet/nearby_share_action.cc b/chrome/browser/nearby_sharing/sharesheet/nearby_share_action.cc index 6478e90..1eaef22 100644 --- a/chrome/browser/nearby_sharing/sharesheet/nearby_share_action.cc +++ b/chrome/browser/nearby_sharing/sharesheet/nearby_share_action.cc
@@ -119,6 +119,10 @@ // The nearby WebUI requested to close through user action if (controller_) { controller_->CloseSharesheet(); + + // We need to clear out the controller here to protect against calling + // CloseShareSheet() more than once, which will cause a crash. + controller_ = nullptr; } }
diff --git a/chrome/browser/reading_list/OWNERS b/chrome/browser/reading_list/OWNERS index 0f5a30f..63dbf55a3 100644 --- a/chrome/browser/reading_list/OWNERS +++ b/chrome/browser/reading_list/OWNERS
@@ -1,4 +1,5 @@ dtrainor@chromium.org +shaktisahu@chromium.org xingliu@chromium.org # Backup reviewers:
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn index d986f2d..5db088b 100644 --- a/chrome/browser/resources/chromeos/login/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -9,6 +9,7 @@ deps = [ ":closure_compile_local", "components:closure_compile", + "test_api:closure_compile", ] }
diff --git a/chrome/browser/resources/chromeos/login/md_login.html b/chrome/browser/resources/chromeos/login/md_login.html index 311f63b9..8169690 100644 --- a/chrome/browser/resources/chromeos/login/md_login.html +++ b/chrome/browser/resources/chromeos/login/md_login.html
@@ -49,8 +49,9 @@ <script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/promise_resolver.js"></script> <script src="chrome://resources/js/util.js"></script> -<script src="chrome://oobe/debug.js"></script> +<script defer src="chrome://oobe/debug.js"></script> <script src="chrome://oobe/strings.js"></script> +<script defer src="chrome://oobe/test_api.js"></script> <link rel="stylesheet" href="api_keys_notice.css"> <link rel="stylesheet" href="oobe_screen_autolaunch.css"> <link rel="stylesheet" href="oobe_screen_auto_enrollment_check.css">
diff --git a/chrome/browser/resources/chromeos/login/oobe.html b/chrome/browser/resources/chromeos/login/oobe.html index bbc8a37..7dc40c06 100644 --- a/chrome/browser/resources/chromeos/login/oobe.html +++ b/chrome/browser/resources/chromeos/login/oobe.html
@@ -53,8 +53,9 @@ <script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/promise_resolver.js"></script> <script src="chrome://resources/js/util.js"></script> -<script src="chrome://oobe/debug.js"></script> +<script defer src="chrome://oobe/debug.js"></script> <script src="chrome://oobe/strings.js"></script> +<script defer src="chrome://oobe/test_api.js"></script> <link rel="stylesheet" href="api_keys_notice.css"> <link rel="stylesheet" href="oobe_screen_autolaunch.css">
diff --git a/chrome/browser/resources/chromeos/login/test_api/BUILD.gn b/chrome/browser/resources/chromeos/login/test_api/BUILD.gn new file mode 100644 index 0000000..4c052bc --- /dev/null +++ b/chrome/browser/resources/chromeos/login/test_api/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") + +js_type_check("closure_compile") { + deps = [ ":test_api" ] +} + +js_library("test_api") { + deps = [ + "//ui/webui/resources/js:load_time_data", + "//ui/webui/resources/js:util", + ] +}
diff --git a/chrome/browser/resources/chromeos/login/test_api/no_test_api.js b/chrome/browser/resources/chromeos/login/test_api/no_test_api.js new file mode 100644 index 0000000..6015d4d5 --- /dev/null +++ b/chrome/browser/resources/chromeos/login/test_api/no_test_api.js
@@ -0,0 +1,8 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/* + * OOBE testing API is not loaded. Please use --enable-oobe-test-api + * command line switch to load. + */
diff --git a/chrome/browser/resources/chromeos/login/test_api/test_api.js b/chrome/browser/resources/chromeos/login/test_api/test_api.js new file mode 100644 index 0000000..aabd05ba --- /dev/null +++ b/chrome/browser/resources/chromeos/login/test_api/test_api.js
@@ -0,0 +1,182 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Common testing utils methods used for OOBE tast tests. + */ + +class TestElementApi { + /** + * Returns HTMLElement with $$ support. + * @return {HTMLElement} + */ + element() { + throw 'element() should be defined!'; + } + + /** + * Returns whether the element is visible. + * @return {boolean} + */ + isVisible() { + return !this.element().hidden; + } + + /** + * Returns whether the element is enabled. + * @return {boolean} + */ + isEnabled() { + return !this.element().disabled; + } +} + +class ScreenElementApi extends TestElementApi { + constructor(id) { + super(); + this.id = id; + this.nextButton = undefined; + } + + /** @override */ + element() { + return $(this.id); + } + + /** + * Click on the primary action button ("Next" usually). + */ + clickNext() { + assert(this.nextButton); + this.nextButton.click(); + } + + /** + * Returns whether the screen should be skipped. + * @return {boolean} + */ + shouldSkip() { + return false; + } +} + +class PolymerElementApi extends TestElementApi { + constructor(parent, query) { + super(); + this.parent = parent; + this.query = query; + } + + /** @override */ + element() { + assert(this.parent.element()); + return this.parent.element().$$(this.query); + } + + /** + * Assert element is visible/enabled and click on the element. + */ + click() { + assert(this.isVisible()); + assert(this.isEnabled()); + this.element().click(); + } +} + +class TextFieldApi extends PolymerElementApi { + constructor(parent, query) { + super(parent, query); + } + + /** + * Assert element is visible/enabled and fill in the element with a value. + * @param {string} value + */ + typeInto(value) { + assert(this.isVisible()); + assert(this.isEnabled()); + this.element().value = value; + this.element().dispatchEvent(new Event('input')); + this.element().dispatchEvent(new Event('change')); + } +} + +class WelcomeScreen extends ScreenElementApi { + constructor() { + super('connect'); + let mainStep = new PolymerElementApi(this, '#welcomeScreen'); + this.nextButton = new PolymerElementApi(mainStep, '#welcomeNextButton'); + } +} + +class NetworkScreen extends ScreenElementApi { + constructor() { + super('network-selection'); + this.nextButton = new PolymerElementApi(this, '#nextButton'); + } +} + +class EulaScreen extends ScreenElementApi { + constructor() { + super('oobe-eula-md'); + this.nextButton = new PolymerElementApi(this, '#acceptButton'); + } + + /** @override */ + shouldSkip() { + // Eula screen should be skipped when it is non-branded build. + return !loadTimeData.getBoolean('isBrandedBuild'); + } +} + +class UserCreationScreen extends ScreenElementApi { + constructor() { + super('user-creation'); + this.nextButton = new PolymerElementApi(this, '#nextButton'); + } +} + +class GaiaScreen extends ScreenElementApi { + constructor() { + super('gaia-signin'); + } +} + +class ConfirmSamlPasswordScreen extends ScreenElementApi { + constructor() { + super('saml-confirm-password'); + this.passwordInput = new TextFieldApi(this, '#passwordInput'); + this.confirmPasswordInput = new TextFieldApi(this, '#confirmPasswordInput'); + this.nextButton = new PolymerElementApi(this, '#next'); + } + + /** + * Enter password input fields with password value and submit the form. + * @param {string} password + */ + enterManualPasswords(password) { + this.passwordInput.typeInto(password); + Polymer.RenderStatus.afterNextRender(assert(this.element()), () => { + this.confirmPasswordInput.typeInto(password); + Polymer.RenderStatus.afterNextRender(assert(this.element()), () => { + this.clickNext(); + }); + }); + } +} + +class OobeApiProvider { + constructor() { + this.screens = { + WelcomeScreen: new WelcomeScreen(), + NetworkScreen: new NetworkScreen(), + EulaScreen: new EulaScreen(), + UserCreationScreen: new UserCreationScreen(), + GaiaScreen: new GaiaScreen(), + ConfirmSamlPasswordScreen: new ConfirmSamlPasswordScreen(), + }; + } +} + +window.OobeAPI = new OobeApiProvider();
diff --git a/chrome/browser/resources/tab_search/app.js b/chrome/browser/resources/tab_search/app.js index b991cce..5ee44a74 100644 --- a/chrome/browser/resources/tab_search/app.js +++ b/chrome/browser/resources/tab_search/app.js
@@ -346,7 +346,19 @@ * @private */ onSearchKeyDown_(e) { - // Do not interfere with the search field's management of text selection. + // In the event the search field has focus and the first item in the list is + // selected and we receive a Shift+Tab navigation event, ensure All DOM + // items are available so that the focus can transfer to the last item in + // the list. + if (e.shiftKey && e.key === 'Tab' && + /** @type {!InfiniteList} */ (this.$.tabsList).selected === 0) { + /** @type {!InfiniteList} */ (this.$.tabsList) + .ensureAllDomItemsAvailable(); + return; + } + + // Do not interfere with the search field's management of text selection + // that relies on the Shift key. if (e.shiftKey) { return; } @@ -362,8 +374,9 @@ e.stopPropagation(); e.preventDefault(); - // For some reasons setting combobox/aria-activedescendant on tab-search-search-field - // has no effect, so manually announce a11y message here. + // For some reasons setting combobox/aria-activedescendant on + // tab-search-search-field has no effect, so manually announce a11y + // message here. this.announceA11y_( this.ariaLabel_(this.filteredOpenTabs_[this.getSelectedIndex()])); } else if (e.key === 'Enter') {
diff --git a/chrome/browser/resources/tab_search/infinite_list.js b/chrome/browser/resources/tab_search/infinite_list.js index 929dfebf..4258a2c 100644 --- a/chrome/browser/resources/tab_search/infinite_list.js +++ b/chrome/browser/resources/tab_search/infinite_list.js
@@ -102,6 +102,13 @@ return idx < this.domRepeat_.items.length; } + ensureAllDomItemsAvailable() { + const lastItemIndex = this.items.length - 1; + if (!this.isDomItemAtIndexAvailable_(lastItemIndex)) { + this.ensureDomItemsAvailableStartingAt_(lastItemIndex); + } + } + /** * Ensure we have the required DOM items to fill the current view starting * at the specified index.
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.cc b/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.cc index 3da96f18..e4cdf51 100644 --- a/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.cc +++ b/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.cc
@@ -144,27 +144,33 @@ TtsEngineExtensionObserverChromeOS::~TtsEngineExtensionObserverChromeOS() = default; -void TtsEngineExtensionObserverChromeOS::BindTtsStream( - mojo::PendingReceiver<chromeos::tts::mojom::TtsStream> receiver) { +void TtsEngineExtensionObserverChromeOS::BindTtsStreamFactory( + mojo::PendingReceiver<chromeos::tts::mojom::TtsStreamFactory> receiver) { // At this point, the component extension has loaded, and the js has requested - // a TtsStream be bound. It's safe now to update the keep alive count for - // important accessibility features. This path is also encountered if the + // a TtsStreamFactory be bound. It's safe now to update the keep alive count + // for important accessibility features. This path is also encountered if the // component extension background page forceably window.close(s) on error. UpdateGoogleSpeechSynthesisKeepAliveCountOnReload(profile_); - // Always launch a new TtsService. By assigning below, if |tts_service_| held - // a remote, it will be killed and a new one created, ensuring we only ever - // have one TtsService running. - tts_service_ = - content::ServiceProcessHost::Launch<chromeos::tts::mojom::TtsService>( - content::ServiceProcessHost::Options() - .WithDisplayName("TtsService") - .Pass()); + // Only launch a new TtsService if necessary. By assigning below, if + // |tts_service_| held a remote, it will be killed and a new one created, + // ensuring we only ever have one TtsService running. + if (!tts_service_) { + tts_service_ = + content::ServiceProcessHost::Launch<chromeos::tts::mojom::TtsService>( + content::ServiceProcessHost::Options() + .WithDisplayName("TtsService") + .Pass()); + } + // Always create a new audio stream for the tts stream. It is assumed once the + // tts stream is reset by the service, the audio stream is appropriately + // cleaned up by the audio service. mojo::PendingRemote<audio::mojom::StreamFactory> factory_remote; auto factory_receiver = factory_remote.InitWithNewPipeAndPassReceiver(); content::GetAudioService().BindStreamFactory(std::move(factory_receiver)); - tts_service_->BindTtsStream(std::move(receiver), std::move(factory_remote)); + tts_service_->BindTtsStreamFactory(std::move(receiver), + std::move(factory_remote)); } void TtsEngineExtensionObserverChromeOS::Shutdown() {
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.h b/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.h index 4a51b0e..2519479 100644 --- a/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.h +++ b/chrome/browser/speech/extension_api/tts_engine_extension_observer_chromeos.h
@@ -33,8 +33,8 @@ Profile* profile() { return profile_; } - void BindTtsStream( - mojo::PendingReceiver<chromeos::tts::mojom::TtsStream> receiver); + void BindTtsStreamFactory( + mojo::PendingReceiver<chromeos::tts::mojom::TtsStreamFactory> receiver); // Implementation of KeyedService. void Shutdown() override;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 4d7dd5c..181bc7a7 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2334,6 +2334,8 @@ "webui/chromeos/login/sync_consent_screen_handler.h", "webui/chromeos/login/terms_of_service_screen_handler.cc", "webui/chromeos/login/terms_of_service_screen_handler.h", + "webui/chromeos/login/testapi/oobe_test_api_handler.cc", + "webui/chromeos/login/testapi/oobe_test_api_handler.h", "webui/chromeos/login/tpm_error_screen_handler.cc", "webui/chromeos/login/tpm_error_screen_handler.h", "webui/chromeos/login/update_required_screen_handler.cc",
diff --git a/chrome/browser/ui/ash/assistant/assistant_test_mixin.cc b/chrome/browser/ui/ash/assistant/assistant_test_mixin.cc index 382a5d1..9cade257 100644 --- a/chrome/browser/ui/ash/assistant/assistant_test_mixin.cc +++ b/chrome/browser/ui/ash/assistant/assistant_test_mixin.cc
@@ -39,7 +39,7 @@ namespace { constexpr const char kTestUser[] = "test_user@gmail.com"; -constexpr const char kTestUserGaiaId[] = "test_user@gaia.id"; +constexpr const char kTestUserGaiaId[] = "test_user_gaia_id"; LoginManagerMixin::TestUserInfo GetTestUserInfo() { return LoginManagerMixin::TestUserInfo(
diff --git a/chrome/browser/ui/ash/chrome_launcher_prefs.cc b/chrome/browser/ui/ash/chrome_launcher_prefs.cc index a60ac3d..b0848b3f 100644 --- a/chrome/browser/ui/ash/chrome_launcher_prefs.cc +++ b/chrome/browser/ui/ash/chrome_launcher_prefs.cc
@@ -49,27 +49,28 @@ // Chrome is pinned explicitly. const char* kDefaultPinnedApps[] = { - extension_misc::kGmailAppId, extension_misc::kGoogleDocAppId, - extension_misc::kYoutubeAppId, arc::kPlayStoreAppId}; + extension_misc::kFilesManagerAppId, extension_misc::kGmailAppId, + extension_misc::kGoogleDocAppId, extension_misc::kYoutubeAppId, + arc::kPlayStoreAppId}; const char* kDefaultPinnedApps7Apps[] = { - extension_misc::kGmailAppId, extension_misc::kGoogleDocAppId, - extension_misc::kGooglePhotosAppId, extension_misc::kFilesManagerAppId, + extension_misc::kFilesManagerAppId, extension_misc::kGmailAppId, + extension_misc::kGoogleDocAppId, extension_misc::kGooglePhotosAppId, extension_misc::kYoutubeAppId, arc::kPlayStoreAppId}; -const char* kDefaultPinnedApps10Apps[] = {extension_misc::kGmailAppId, +const char* kDefaultPinnedApps10Apps[] = {extension_misc::kFilesManagerAppId, + extension_misc::kGmailAppId, extension_misc::kCalendarAppId, extension_misc::kGoogleDocAppId, extension_misc::kGoogleSheetsAppId, extension_misc::kGoogleSlidesAppId, - extension_misc::kFilesManagerAppId, extension_misc::kCameraAppId, extension_misc::kGooglePhotosAppId, arc::kPlayStoreAppId}; const char* kTabletFormFactorDefaultPinnedApps[] = { - arc::kGmailAppId, extension_misc::kGoogleDocAppId, arc::kYoutubeAppId, - arc::kPlayStoreAppId}; + extension_misc::kFilesManagerAppId, arc::kGmailAppId, + extension_misc::kGoogleDocAppId, arc::kYoutubeAppId, arc::kPlayStoreAppId}; const char kDefaultPinnedAppsKey[] = "default"; const char kDefaultPinnedApps7AppsKey[] = "7apps"; @@ -615,8 +616,7 @@ // If Lacros is enabled and allowed for this user type, ensure the Lacros icon // is pinned. Lacros doesn't support multi-signin, so only add the icon for // the primary user. - if (chromeos::features::IsLacrosSupportEnabled() && - crosapi::browser_util::IsLacrosAllowed() && + if (crosapi::browser_util::IsLacrosEnabled() && chromeos::ProfileHelper::IsPrimaryProfile(helper->profile())) { syncer::StringOrdinal lacros_position = syncable_service->GetPinPosition(extension_misc::kLacrosAppId);
diff --git a/chrome/browser/ui/ash/clipboard_image_model_factory_impl.cc b/chrome/browser/ui/ash/clipboard_image_model_factory_impl.cc index 3559347f..1ee035d 100644 --- a/chrome/browser/ui/ash/clipboard_image_model_factory_impl.cc +++ b/chrome/browser/ui/ash/clipboard_image_model_factory_impl.cc
@@ -50,9 +50,16 @@ } void ClipboardImageModelFactoryImpl::Deactivate() { - // Prevent new requests from being ran, but do not stop |request_| if it is - // running. |request_| will be cleaned up OnRequestIdle(). active_ = false; + + if (!request_ || !request_->IsModifyingClipboard()) + return; + + // Stop the currently running request if it is modifying the clipboard. + // ClipboardImageModelFactory is `Deactivate()`-ed prior to the user pasting + // and a modified clipboard could interfere with pasting from + // ClipboardHistory. + pending_list_.emplace_front(request_->StopAndGetParams()); } void ClipboardImageModelFactoryImpl::OnShutdown() {
diff --git a/chrome/browser/ui/ash/clipboard_image_model_request.cc b/chrome/browser/ui/ash/clipboard_image_model_request.cc index 5af2c156..41d9a57 100644 --- a/chrome/browser/ui/ash/clipboard_image_model_request.cc +++ b/chrome/browser/ui/ash/clipboard_image_model_request.cc
@@ -6,6 +6,8 @@ #include <memory> +#include "ash/public/cpp/clipboard_history_controller.h" +#include "ash/public/cpp/scoped_clipboard_history_pause.h" #include "base/base64.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/navigation_controller.h" @@ -14,10 +16,12 @@ #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "ui/aura/window.h" +#include "ui/base/clipboard/clipboard_data.h" +#include "ui/base/clipboard/clipboard_non_backed.h" +#include "ui/base/data_transfer_policy/data_transfer_endpoint.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/views/controls/webview/webview.h" -#include "ui/views/layout/fill_layout.h" #include "ui/views/widget/widget.h" #include "url/gurl.h" @@ -33,6 +37,39 @@ ClipboardImageModelRequest::Params::~Params() = default; +ClipboardImageModelRequest::ScopedClipboardModifier::ScopedClipboardModifier( + const std::string& html_markup) { + auto* clipboard = ui::ClipboardNonBacked::GetForCurrentThread(); + ui::DataTransferEndpoint data_dst(ui::EndpointType::kClipboardHistory); + const auto* current_data = clipboard->GetClipboardData(&data_dst); + + // No need to replace the clipboard contents if the markup is the same. + if (current_data && (html_markup == current_data->markup_data())) + return; + + // Put |html_markup| on the clipboard temporarily so it can be pasted into + // the WebContents. This is preferable to directly loading |html_markup_| in a + // data URL because pasting the data into WebContents sanitizes the markup. + // TODO(https://crbug.com/1144962): Sanitize copied HTML prior to storing it + // in the clipboard buffer. Then |html_markup_| can be loaded from a data URL + // and will not need to be pasted in this manner. + auto new_data = std::make_unique<ui::ClipboardData>(); + new_data->set_markup_data(html_markup); + + scoped_clipboard_history_pause_ = + ash::ClipboardHistoryController::Get()->CreateScopedPause(); + replaced_clipboard_data_ = clipboard->WriteClipboardData(std::move(new_data)); +} + +ClipboardImageModelRequest::ScopedClipboardModifier:: + ~ScopedClipboardModifier() { + if (!replaced_clipboard_data_) + return; + + ui::ClipboardNonBacked::GetForCurrentThread()->WriteClipboardData( + std::move(replaced_clipboard_data_)); +} + ClipboardImageModelRequest::ClipboardImageModelRequest( Profile* profile, base::RepeatingClosure on_request_finished_callback) @@ -59,6 +96,7 @@ DCHECK_EQ(base::UnguessableToken(), request_id_); request_id_ = std::move(params.id); + html_markup_ = params.html_markup; deliver_image_model_callback_ = std::move(params.callback); timeout_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(10), this, @@ -67,10 +105,17 @@ // Begin the document with the proper charset, this should prevent strange // looking characters from showing up in the render in some cases. std::string html_document( - "<!DOCTYPE html><html><head><meta " - "charset=\"UTF-8\"></meta></head><body>"); - html_document.append(params.html_markup); - html_document.append("</body></html>"); + "<!DOCTYPE html>" + "<html>" + " <head><meta charset=\"UTF-8\"></meta></head>" + " <body contenteditable='true'> " + " <script>" + // Focus the Contenteditable body to ensure WebContents::Paste() reaches + // the body. + " document.body.focus();" + " </script>" + " </body>" + "</html"); std::string encoded_html; base::Base64Encode(html_document, &encoded_html); @@ -79,19 +124,38 @@ content::NavigationController::LoadURLParams( GURL(kDataURIPrefix + encoded_html))); widget_->ShowInactive(); + + // Give some initial bounds to the NativeView to force painting in an inactive + // shown widget. + web_contents()->GetNativeView()->SetBounds(gfx::Rect(0, 0, 1, 1)); } void ClipboardImageModelRequest::Stop() { + scoped_clipboard_modifier_.reset(); weak_ptr_factory_.InvalidateWeakPtrs(); copy_surface_weak_ptr_factory_.InvalidateWeakPtrs(); timeout_timer_.Stop(); widget_->Hide(); deliver_image_model_callback_.Reset(); request_id_ = base::UnguessableToken(); - did_auto_resize_ = false; + did_stop_loading_ = false; + on_request_finished_callback_.Run(); } +ClipboardImageModelRequest::Params +ClipboardImageModelRequest::StopAndGetParams() { + DCHECK(IsRunningRequest()); + Params params(request_id_, html_markup_, + std::move(deliver_image_model_callback_)); + Stop(); + return params; +} + +bool ClipboardImageModelRequest::IsModifyingClipboard() const { + return scoped_clipboard_modifier_.has_value(); +} + bool ClipboardImageModelRequest::IsRunningRequest( base::Optional<base::UnguessableToken> request_id) const { return request_id.has_value() ? *request_id == request_id_ @@ -101,7 +165,6 @@ void ClipboardImageModelRequest::ResizeDueToAutoResize( content::WebContents* web_contents, const gfx::Size& new_size) { - did_auto_resize_ = true; web_contents->GetNativeView()->SetBounds(gfx::Rect(gfx::Point(), new_size)); // `ResizeDueToAutoResize()` can be called before and/or after @@ -112,12 +175,23 @@ } void ClipboardImageModelRequest::DidStopLoading() { - // Wait for auto resize. In some cases the data url will stop loading before - // auto resize has occurred. This will result in a incorrectly sized image. - if (!did_auto_resize_) + // `DidStopLoading()` can be called multiple times after a paste. We are only + // interested in the initial load of the data URL. + if (did_stop_loading_) return; - PostCopySurfaceTask(); + did_stop_loading_ = true; + + // Modify the clipboard so `html_markup_` can be pasted into the WebContents. + scoped_clipboard_modifier_.emplace(html_markup_); + + web_contents()->GetRenderViewHost()->GetWidget()->InsertVisualStateCallback( + base::BindOnce(&ClipboardImageModelRequest::OnVisualStateChangeFinished, + weak_ptr_factory_.GetWeakPtr())); + + // TODO(https://crbug.com/1149556): Clipboard Contents could be overwritten + // prior to the `WebContents::Paste()` completing. + web_contents()->Paste(); } void ClipboardImageModelRequest::RenderViewHostChanged( @@ -130,6 +204,14 @@ gfx::Size(1, 1), gfx::Size(INT_MAX, INT_MAX)); } +void ClipboardImageModelRequest::OnVisualStateChangeFinished(bool done) { + if (!done) + return; + + scoped_clipboard_modifier_.reset(); + PostCopySurfaceTask(); +} + void ClipboardImageModelRequest::PostCopySurfaceTask() { if (!deliver_image_model_callback_) return; @@ -142,7 +224,7 @@ FROM_HERE, base::BindOnce(&ClipboardImageModelRequest::CopySurface, copy_surface_weak_ptr_factory_.GetWeakPtr()), - base::TimeDelta::FromMilliseconds(100)); + base::TimeDelta::FromMilliseconds(250)); } void ClipboardImageModelRequest::CopySurface() {
diff --git a/chrome/browser/ui/ash/clipboard_image_model_request.h b/chrome/browser/ui/ash/clipboard_image_model_request.h index ea2f7c0..19d1ac99 100644 --- a/chrome/browser/ui/ash/clipboard_image_model_request.h +++ b/chrome/browser/ui/ash/clipboard_image_model_request.h
@@ -15,6 +15,14 @@ #include "content/public/browser/web_contents_observer.h" #include "ui/base/models/image_model.h" +namespace ash { +class ScopedClipboardHistoryPause; +} // namespace ash + +namespace ui { +class ClipboardData; +} // namespace ui + namespace views { class WebView; class Widget; @@ -49,6 +57,22 @@ ImageModelCallback callback; }; + // Places `html_markup` on the clipboard and restores the original clipboard + // contents when destructed. + class ScopedClipboardModifier { + public: + explicit ScopedClipboardModifier(const std::string& html_markup); + ScopedClipboardModifier(const ScopedClipboardModifier&) = delete; + ScopedClipboardModifier& operator=(const ScopedClipboardModifier&) = delete; + ~ScopedClipboardModifier(); + + private: + // Pauses ash::ClipboardHistory for its lifetime. + std::unique_ptr<ash::ScopedClipboardHistoryPause> + scoped_clipboard_history_pause_; + std::unique_ptr<ui::ClipboardData> replaced_clipboard_data_; + }; + ClipboardImageModelRequest( Profile* profile, base::RepeatingClosure on_request_finished_callback); @@ -65,6 +89,12 @@ // enable fast restarting of the request. void Stop(); + // `Stop()`s the request and gets the params of the running request. + Params StopAndGetParams(); + + // Whether the clipboard is being modified by this request. + bool IsModifyingClipboard() const; + // Returns whether a request with |request_id| is running, or if any request // is running if no |request_id| is supplied. bool IsRunningRequest( @@ -80,6 +110,9 @@ content::RenderViewHost* new_host) override; private: + // Called when the results of the paste are painted. + void OnVisualStateChangeFinished(bool done); + // Posts `CopySurface()` to the task sequence. void PostCopySurfaceTask(); @@ -102,8 +135,15 @@ // requests. base::UnguessableToken request_id_; - // Whether `AutoResizeDueToAutoResize()` was called. - bool did_auto_resize_ = false; + // The HTML being rendered. + std::string html_markup_; + + // Whether `DidStopLoading()` was called. Used to prevent the request from + // responding to load events that happen after the initial load. + bool did_stop_loading_ = false; + + // Responsible for temporarily replacing contents of the clipboard. + base::Optional<ScopedClipboardModifier> scoped_clipboard_modifier_; // Callback used to deliver the rendered ImageModel. ImageModelCallback deliver_image_model_callback_;
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_client_impl.cc b/chrome/browser/ui/ash/holding_space/holding_space_client_impl.cc index 2e4e099..b93ef85b 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_client_impl.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_client_impl.cc
@@ -71,6 +71,11 @@ GetHoldingSpaceKeyedService(profile_)->AddScreenshot(file_path); } +void HoldingSpaceClientImpl::AddScreenRecording( + const base::FilePath& file_path) { + GetHoldingSpaceKeyedService(profile_)->AddScreenRecording(file_path); +} + void HoldingSpaceClientImpl::CopyImageToClipboard(const HoldingSpaceItem& item, SuccessCallback callback) { holding_space_metrics::RecordItemAction(
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_client_impl.h b/chrome/browser/ui/ash/holding_space/holding_space_client_impl.h index 10153ae..027864e 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_client_impl.h +++ b/chrome/browser/ui/ash/holding_space/holding_space_client_impl.h
@@ -25,6 +25,7 @@ ~HoldingSpaceClientImpl() override; // HoldingSpaceClient: + void AddScreenRecording(const base::FilePath& file_path) override; void AddScreenshot(const base::FilePath& file_path) override; void CopyImageToClipboard(const HoldingSpaceItem&, SuccessCallback) override; void OpenDownloads(SuccessCallback callback) override;
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc b/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc index 1a6ea21..1ce5ae3 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc
@@ -5,14 +5,17 @@ #include "chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.h" #include "ash/public/cpp/ash_features.h" +#include "ash/public/cpp/capture_mode_test_api.h" #include "ash/public/cpp/holding_space/holding_space_controller.h" #include "ash/public/cpp/holding_space/holding_space_item.h" #include "ash/public/cpp/holding_space/holding_space_model.h" #include "ash/public/cpp/holding_space/holding_space_model_observer.h" #include "ash/public/cpp/holding_space/holding_space_prefs.h" +#include "ash/public/cpp/holding_space/holding_space_test_api.h" #include "base/scoped_observer.h" #include "base/test/bind.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser_window.h" #include "content/public/test/browser_test.h" #include "testing/gmock/include/gmock/gmock.h" @@ -510,6 +513,60 @@ EXPECT_EQ(1u, GetScreenCaptureViews().size()); } +// Base class for holding space UI browser tests that take screen recordings. +class HoldingSpaceUiScreenCaptureBrowserTest + : public HoldingSpaceUiBrowserTest { + public: + HoldingSpaceUiScreenCaptureBrowserTest() { + scoped_feature_list_.InitAndEnableFeature(features::kCaptureMode); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Verifies that taking a screen recording adds a screen recording holding space +// item. +IN_PROC_BROWSER_TEST_F(HoldingSpaceUiScreenCaptureBrowserTest, + AddScreenRecording) { + // Verify that no screen recordings exist in holding space UI. + Show(); + ASSERT_TRUE(IsShowing()); + EXPECT_TRUE(GetScreenCaptureViews().empty()); + + Close(); + ASSERT_FALSE(IsShowing()); + ash::CaptureModeTestApi capture_mode_test_api; + capture_mode_test_api.StartForFullscreen(/*for_video=*/true); + capture_mode_test_api.PerformCapture(); + // Record a 100 ms long video. + base::RunLoop video_recording_time; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, video_recording_time.QuitClosure(), + base::TimeDelta::FromMilliseconds(100)); + video_recording_time.Run(); + capture_mode_test_api.StopVideoRecording(); + + // Bind an observer to watch for updates to the holding space model. + testing::NiceMock<MockHoldingSpaceModelObserver> mock; + ScopedObserver<HoldingSpaceModel, HoldingSpaceModelObserver> observer{&mock}; + observer.Add(HoldingSpaceController::Get()->model()); + + base::RunLoop wait_for_item; + // Expect and wait for a screen recording item to be added to holding space. + EXPECT_CALL(mock, OnHoldingSpaceItemAdded) + .WillOnce([&](const HoldingSpaceItem* item) { + if (item->type() == HoldingSpaceItem::Type::kScreenRecording) + wait_for_item.Quit(); + }); + wait_for_item.Run(); + + // Verify that the screen recording appears in holding space UI. + Show(); + ASSERT_TRUE(IsShowing()); + EXPECT_EQ(1u, GetScreenCaptureViews().size()); +} + INSTANTIATE_TEST_SUITE_P(All, HoldingSpaceUiScreenshotBrowserTest, testing::Bool());
diff --git a/chrome/browser/ui/ash/launcher/app_window_base.cc b/chrome/browser/ui/ash/launcher/app_window_base.cc index 2805a7c2..f292dba8 100644 --- a/chrome/browser/ui/ash/launcher/app_window_base.cc +++ b/chrome/browser/ui/ash/launcher/app_window_base.cc
@@ -11,8 +11,15 @@ views::Widget* widget) : shelf_id_(shelf_id), widget_(widget) {} +AppWindowBase::~AppWindowBase() { + if (controller_) + controller_->RemoveWindow(this); +} + void AppWindowBase::SetController(AppWindowLauncherItemController* controller) { DCHECK(!controller_ || !controller); + if (!controller && controller_) + controller_->RemoveWindow(this); controller_ = controller; }
diff --git a/chrome/browser/ui/ash/launcher/app_window_base.h b/chrome/browser/ui/ash/launcher/app_window_base.h index c59798511..7f6cc06 100644 --- a/chrome/browser/ui/ash/launcher/app_window_base.h +++ b/chrome/browser/ui/ash/launcher/app_window_base.h
@@ -33,7 +33,7 @@ AppWindowBase(const ash::ShelfID& shelf_id, views::Widget* widget); - virtual ~AppWindowBase() {} + virtual ~AppWindowBase(); void SetController(AppWindowLauncherItemController* controller);
diff --git a/chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.cc index 6b3d70a..774a5f8 100644 --- a/chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.cc
@@ -67,7 +67,7 @@ void AppWindowLauncherItemController::AddWindow(ui::BaseWindow* app_window) { aura::Window* window = app_window->GetNativeWindow(); - if (window) + if (window && !observed_windows_.IsObserving(window)) observed_windows_.Add(window); if (window && window->GetProperty(ash::kHideInShelfKey)) hidden_windows_.push_front(app_window); @@ -88,7 +88,7 @@ void AppWindowLauncherItemController::RemoveWindow(ui::BaseWindow* app_window) { DCHECK(app_window); aura::Window* window = app_window->GetNativeWindow(); - if (window) + if (window && observed_windows_.IsObserving(window)) observed_windows_.Remove(window); if (app_window == last_active_window_) last_active_window_ = nullptr; @@ -98,12 +98,9 @@ } else { iter = std::find(hidden_windows_.begin(), hidden_windows_.end(), app_window); - if (iter != hidden_windows_.end()) { - hidden_windows_.erase(iter); - } else { - NOTREACHED(); + if (iter == hidden_windows_.end()) return; - } + hidden_windows_.erase(iter); } UpdateShelfItemIcon(); }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index edf39fcf8..adceb89e 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -417,6 +417,11 @@ base::FilePath(), Manifest::UNPACKED, manifest, Extension::NO_FLAGS, extension_misc::kYoutubeAppId, &error); + // Fake File Manager app. + extension_files_app_ = Extension::Create( + base::FilePath(), Manifest::UNPACKED, manifest, Extension::NO_FLAGS, + extension_misc::kFilesManagerAppId, &error); + MaybeStartWebAppProvider(); } @@ -788,6 +793,8 @@ result += "Doc"; } else if (app == extension_youtube_app_->id()) { result += "Youtube"; + } else if (app == extension_files_app_->id()) { + result += "Files"; } else if (app == extension_platform_app_->id()) { result += "Platform_App"; } else if (app == arc_support_host_->id()) { @@ -962,6 +969,7 @@ scoped_refptr<Extension> extension_gmail_app_; scoped_refptr<Extension> extension_doc_app_; scoped_refptr<Extension> extension_youtube_app_; + scoped_refptr<Extension> extension_files_app_; scoped_refptr<Extension> extension_platform_app_; scoped_refptr<Extension> arc_support_host_; @@ -1085,6 +1093,7 @@ extension_service_->AddExtension(extension_gmail_app_.get()); extension_service_->AddExtension(extension_doc_app_.get()); extension_service_->AddExtension(extension_youtube_app_.get()); + extension_service_->AddExtension(extension_files_app_.get()); extension_service_->AddExtension(arc_support_host_.get()); std::string error; @@ -1102,7 +1111,6 @@ {extension_misc::kCalendarAppId, "Calendar"}, {extension_misc::kGoogleSheetsAppId, "Sheets"}, {extension_misc::kGoogleSlidesAppId, "Slides"}, - {extension_misc::kFilesManagerAppId, "Files"}, {extension_misc::kCameraAppId, "Camera"}, {extension_misc::kGooglePhotosAppId, "Photos"}, }; @@ -1364,6 +1372,8 @@ EXPECT_EQ("Chrome, Doc, Youtube, App1", GetPinnedAppStatus()); AddExtension(extension_gmail_app_.get()); EXPECT_EQ("Chrome, Gmail, Doc, Youtube, App1", GetPinnedAppStatus()); + AddExtension(extension_files_app_.get()); + EXPECT_EQ("Chrome, Files, Gmail, Doc, Youtube, App1", GetPinnedAppStatus()); } TEST_F(ChromeLauncherControllerSplitSettingsSyncTest, DefaultApps) { @@ -1390,28 +1400,29 @@ EXPECT_EQ("Chrome, Lacros", GetPinnedAppStatus()); } -TEST_F(ChromeLauncherControllerExtendedShelfTest, ExtendedShefDefault) { +TEST_F(ChromeLauncherControllerExtendedShelfTest, ExtendedShelfDefault) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( kEnableExtendedShelfLayout, {std::pair<std::string, std::string>("app_count", "0")}); InitLauncherController(); - EXPECT_EQ("Chrome, Gmail, Doc, Youtube, Play Store", GetPinnedAppStatus()); + EXPECT_EQ("Chrome, Files, Gmail, Doc, Youtube, Play Store", + GetPinnedAppStatus()); } -TEST_F(ChromeLauncherControllerExtendedShelfTest, ExtendedShef7Apps) { +TEST_F(ChromeLauncherControllerExtendedShelfTest, ExtendedShelf7Apps) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( kEnableExtendedShelfLayout, {std::pair<std::string, std::string>("app_count", "7")}); InitLauncherController(); - EXPECT_EQ("Chrome, Gmail, Doc, Photos, Files, Youtube, Play Store", + EXPECT_EQ("Chrome, Files, Gmail, Doc, Photos, Youtube, Play Store", GetPinnedAppStatus()); } -TEST_F(ChromeLauncherControllerExtendedShelfTest, ExtendedShef10Apps) { +TEST_F(ChromeLauncherControllerExtendedShelfTest, ExtendedShelf10Apps) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( kEnableExtendedShelfLayout, @@ -1419,14 +1430,15 @@ InitLauncherController(); EXPECT_EQ( - "Chrome, Gmail, Calendar, Doc, Sheets, Slides, Files, Camera, Photos, " + "Chrome, Files, Gmail, Calendar, Doc, Sheets, Slides, Camera, Photos, " "Play Store", GetPinnedAppStatus()); } TEST_F(ChromeLauncherControllerExtendedShelfTest, UpgradeFromDefault) { InitLauncherController(); - EXPECT_EQ("Chrome, Gmail, Doc, Youtube, Play Store", GetPinnedAppStatus()); + EXPECT_EQ("Chrome, Files, Gmail, Doc, Youtube, Play Store", + GetPinnedAppStatus()); // Upgrade happens only in case default layout is active. base::test::ScopedFeatureList scoped_feature_list; @@ -1438,15 +1450,15 @@ AddExtension(extension1_.get()); EXPECT_EQ( - "Chrome, Gmail, Calendar, Doc, Sheets, Slides, Files, Camera, Photos, " + "Chrome, Files, Gmail, Calendar, Doc, Sheets, Slides, Camera, Photos, " "Play Store", GetPinnedAppStatus()); } -TEST_F(ChromeLauncherControllerExtendedShelfTest, NoDefaultAfterExperemental) { +TEST_F(ChromeLauncherControllerExtendedShelfTest, NoDefaultAfterExperimental) { const std::string expectations = - "Chrome, Gmail, Calendar, Doc, Sheets, " - "Slides, Files, Camera, Photos, Play Store"; + "Chrome, Files, Gmail, Calendar, Doc, Sheets, " + "Slides, Camera, Photos, Play Store"; { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( @@ -1473,7 +1485,7 @@ TEST_F(ChromeLauncherControllerExtendedShelfTest, NoUpgradeFromNonDefault) { InitLauncherController(); launcher_controller_->UnpinAppWithID(extension_misc::kYoutubeAppId); - EXPECT_EQ("Chrome, Gmail, Doc, Play Store", GetPinnedAppStatus()); + EXPECT_EQ("Chrome, Files, Gmail, Doc, Play Store", GetPinnedAppStatus()); // Upgrade does not happen due to default pin layout change. base::test::ScopedFeatureList scoped_feature_list; @@ -1484,7 +1496,7 @@ // Trigger layout update, app_id does not matter. AddExtension(extension1_.get()); - EXPECT_EQ("Chrome, Gmail, Doc, Play Store", GetPinnedAppStatus()); + EXPECT_EQ("Chrome, Files, Gmail, Doc, Play Store", GetPinnedAppStatus()); } TEST_F(ChromeLauncherControllerWithArcTest, ArcAppPinCrossPlatformWorkflow) {
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc index f95e35a..dfcdf0c 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc
@@ -356,10 +356,16 @@ base::Unretained(this))); SetAcceptCallback(base::BindOnce( &LocalCardMigrationDialogView::OnDialogAccepted, base::Unretained(this))); + RegisterWindowClosingCallback(base::BindOnce( + &LocalCardMigrationDialogView::OnWindowClosing, base::Unretained(this))); + // This should be a modal dialog blocking the browser since we don't want + // users to lose progress in the migration workflow until they are done. + SetModalType(ui::MODAL_TYPE_WINDOW); set_close_on_deactivate(false); set_margins(gfx::Insets()); set_fixed_width(ChromeLayoutProvider::Get()->GetDistanceMetric( DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH)); + SetShowCloseButton(false); } LocalCardMigrationDialogView::~LocalCardMigrationDialogView() {} @@ -376,29 +382,6 @@ GetWidget()->Close(); } -ui::ModalType LocalCardMigrationDialogView::GetModalType() const { - // This should be a modal dialog blocking the browser since we don't want - // users to lose progress in the migration workflow until they are done. - return ui::MODAL_TYPE_WINDOW; -} - -bool LocalCardMigrationDialogView::ShouldShowCloseButton() const { - return false; -} - -// TODO(crbug.com/867194): Update this method when adding feedback. -bool LocalCardMigrationDialogView::IsDialogButtonEnabled( - ui::DialogButton button) const { - // If the dialog is offer dialog and all checkboxes are unchecked, disable the - // save button. - if (controller_->GetViewState() == LocalCardMigrationDialogState::kOffered && - button == ui::DIALOG_BUTTON_OK) { - DCHECK(offer_view_); - return !offer_view_->GetSelectedCardGuids().empty(); - } - return true; -} - void LocalCardMigrationDialogView::OnDialogAccepted() { switch (controller_->GetViewState()) { case LocalCardMigrationDialogState::kOffered: @@ -424,19 +407,31 @@ } } -void LocalCardMigrationDialogView::WindowClosing() { +void LocalCardMigrationDialogView::OnWindowClosing() { if (controller_) { controller_->OnDialogClosed(); controller_ = nullptr; } } +bool LocalCardMigrationDialogView::ShouldOkButtonBeEnabled() const { + if (controller_->GetViewState() == LocalCardMigrationDialogState::kOffered) { + DCHECK(offer_view_) << "This method can't be called before ConstructView"; + return !offer_view_->GetSelectedCardGuids().empty(); + } + return true; +} + void LocalCardMigrationDialogView::DeleteCard(const std::string& guid) { controller_->DeleteCard(guid); ConstructView(); UpdateLayout(); } +void LocalCardMigrationDialogView::OnCardCheckboxToggled() { + SetButtonEnabled(ui::DIALOG_BUTTON_OK, ShouldOkButtonBeEnabled()); +} + // TODO(crbug.com/913571): Figure out a way to avoid two consecutive layouts. void LocalCardMigrationDialogView::UpdateLayout() { Layout(); @@ -481,6 +476,7 @@ offer_view_->SetID(DialogViewId::MAIN_CONTENT_VIEW_MIGRATION_OFFER_DIALOG); card_list_view_ = offer_view_->card_list_view_; AddChildView(offer_view_); + SetButtonEnabled(ui::DIALOG_BUTTON_OK, ShouldOkButtonBeEnabled()); } else { AddChildView(CreateFeedbackContentView(controller_, this).release()); }
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h index 94d4074..6121bc5 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h
@@ -33,14 +33,9 @@ void ShowDialog() override; void CloseDialog() override; - // views::BubbleDialogDelegateView: - ui::ModalType GetModalType() const override; - bool ShouldShowCloseButton() const override; - bool IsDialogButtonEnabled(ui::DialogButton button) const override; - void WindowClosing() override; - // Called by MigratableCardView when the user clicks the trash can button. // |guid| is the GUID of the credit card to be deleted. + void OnCardCheckboxToggled(); void DeleteCard(const std::string& guid); void UpdateLayout(); @@ -50,6 +45,8 @@ void ConstructView(); void OnDialogAccepted(); void OnDialogCancelled(); + void OnWindowClosing(); + bool ShouldOkButtonBeEnabled() const; base::string16 GetOkButtonLabel() const; base::string16 GetCancelButtonLabel() const;
diff --git a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc index da7c2f6f..3bf384e1 100644 --- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc +++ b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
@@ -212,7 +212,7 @@ void MigratableCardView::CheckboxPressed() { // If the button clicked is a checkbox. Enable/disable the save // button if needed. - parent_dialog_->DialogModelChanged(); + parent_dialog_->OnCardCheckboxToggled(); // The warning text will be visible only when user unchecks the checkbox. checkbox_uncheck_text_container_->SetVisible(!checkbox_->GetChecked()); InvalidateLayout();
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc index fe57952..5829db2 100644 --- a/chrome/browser/ui/views/hung_renderer_view.cc +++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -106,6 +106,10 @@ widget_observer_.RemoveAll(); tab_observers_.clear(); render_widget_host_ = nullptr; + + // Inform the table model observers that we cleared the model. + if (observer_) + observer_->OnModelChanged(); } void HungPagesTableModel::RestartHangMonitorTimeout() {
diff --git a/chrome/browser/ui/views/hung_renderer_view.h b/chrome/browser/ui/views/hung_renderer_view.h index 5166530..1d487ae 100644 --- a/chrome/browser/ui/views/hung_renderer_view.h +++ b/chrome/browser/ui/views/hung_renderer_view.h
@@ -155,6 +155,11 @@ // Returns true if the frame is in the foreground. static bool IsFrameActive(content::WebContents* contents); + views::TableView* table_for_testing() { return hung_pages_table_; } + HungPagesTableModel* table_model_for_testing() { + return hung_pages_table_model_.get(); + } + virtual void ShowForWebContents( content::WebContents* contents, content::RenderWidgetHost* render_widget_host,
diff --git a/chrome/browser/ui/views/hung_renderer_view_browsertest.cc b/chrome/browser/ui/views/hung_renderer_view_browsertest.cc index 7372ebd..dfd6205 100644 --- a/chrome/browser/ui/views/hung_renderer_view_browsertest.cc +++ b/chrome/browser/ui/views/hung_renderer_view_browsertest.cc
@@ -21,6 +21,7 @@ #include "content/public/browser/web_contents_delegate.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" +#include "ui/views/accessibility/view_accessibility.h" // Interactive UI tests for the hung renderer (aka page unresponsive) dialog. class HungRendererDialogViewBrowserTest : public DialogBrowserTest { @@ -77,7 +78,7 @@ // This is what happens when HungRendererDialogView::ShowForWebContents // returns early if the frame or the dialog are not active. HungRendererDialogView::Create(browser()->window()->GetNativeWindow()); - EXPECT_TRUE(HungRendererDialogView::GetInstance()); + ASSERT_TRUE(HungRendererDialogView::GetInstance()); // Simulate the renderer becoming responsive again. content::WebContents* web_contents = @@ -87,3 +88,34 @@ content::WebContentsDelegate* web_contents_delegate = browser(); web_contents_delegate->RendererResponsive(web_contents, render_widget_host); } + +IN_PROC_BROWSER_TEST_F(HungRendererDialogViewBrowserTest, ProcessClosed) { + HungRendererDialogView* dialog = + HungRendererDialogView::Create(browser()->window()->GetNativeWindow()); + ASSERT_TRUE(dialog); + + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + + // The Hung Dialog requires window activation, window activations does not + // work reliably in browser tests, especially in Mac because of the activation + // policy for obtaining window key status is set to prohibited. Instead of + // showing the window, populate the table model instead. + dialog->table_model_for_testing()->InitForWebContents( + web_contents, + web_contents->GetMainFrame()->GetRenderViewHost()->GetWidget(), + base::DoNothing::Repeatedly()); + + // Makes sure the virtual accessibility views are in sync with the model when + // the dialog is created. Should consist of a single item. + views::ViewAccessibility& view_accessibility = + dialog->table_for_testing()->GetViewAccessibility(); + EXPECT_EQ(size_t{1}, view_accessibility.virtual_children().size()); + + // Simulate an abrupt ending to webcontents. The accessibility tree for the + // TableView depends on the Hung Render View table model to send the right + // events. By checking the virtual tree, we can guarantee the sync is correct. + dialog->EndForWebContents( + web_contents, + web_contents->GetMainFrame()->GetRenderViewHost()->GetWidget()); + EXPECT_EQ(size_t{0}, view_accessibility.virtual_children().size()); +}
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.h b/chrome/browser/ui/views/intent_picker_bubble_view.h index a20bb5f..ee1d0d05 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view.h +++ b/chrome/browser/ui/views/intent_picker_bubble_view.h
@@ -128,6 +128,12 @@ DismissBubble); FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS, ShowBubbleTwice); + FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS, + PushStateLoadingTest); + FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS, + PushStateURLChangeTest); + FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS, + ReloadAfterInstall); static std::unique_ptr<IntentPickerBubbleView> CreateBubbleViewForTesting( views::View* anchor_view,
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc index 9e4252a..6bb7b36f 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc +++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
@@ -39,6 +39,8 @@ #include "components/services/app_service/public/cpp/intent_util.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "content/public/test/browser_test.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/widget/any_widget_observer.h" #include "url/gurl.h" @@ -453,3 +455,134 @@ EXPECT_TRUE(intent_picker_bubble()->GetVisible()); EXPECT_EQ(2U, intent_picker_bubble()->GetScrollViewSize()); } + +// Test that loading a page with pushState() call that doesn't change URL work +// as normal. +IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS, + PushStateLoadingTest) { + ASSERT_TRUE(embedded_test_server()->Start()); + const GURL test_url = + embedded_test_server()->GetURL("/intent_picker/push_state_test.html"); + std::string app_name = "test_name"; + auto app_id = AddArcAppWithIntentFilter(app_name, test_url); + PageActionIconView* intent_picker_view = GetIntentPickerIcon(); + + chrome::NewTab(browser()); + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); + + // Navigate from a link. + NavigateParams params(browser(), test_url, + ui::PageTransition::PAGE_TRANSITION_LINK); + + views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{}, + "IntentPickerBubbleView"); + // Navigates and waits for loading to finish. + ui_test_utils::NavigateToURL(¶ms); + + waiter.WaitIfNeededAndGet(); + EXPECT_TRUE(intent_picker_view->GetVisible()); + ASSERT_TRUE(intent_picker_bubble()); + EXPECT_TRUE(intent_picker_bubble()->GetVisible()); + EXPECT_EQ(1U, intent_picker_bubble()->GetScrollViewSize()); + auto& app_info = intent_picker_bubble()->app_info_for_testing(); + ASSERT_EQ(1U, app_info.size()); + EXPECT_EQ(app_id, app_info[0].launch_name); + EXPECT_EQ(app_name, app_info[0].display_name); + + // Launch the default selected app. + EXPECT_EQ(0U, launched_arc_apps().size()); + intent_picker_bubble()->AcceptDialog(); + WaitForAppService(); + ASSERT_EQ(1U, launched_arc_apps().size()); + EXPECT_EQ(app_name, launched_arc_apps()[0].activity->package_name); + EXPECT_EQ(test_url.spec(), launched_arc_apps()[0].intent->data); +} + +// Test that loading a page with pushState() call that changes URL +// updates the intent picker view. +IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS, + PushStateURLChangeTest) { + ASSERT_TRUE(embedded_test_server()->Start()); + const GURL test_url = + embedded_test_server()->GetURL("/intent_picker/push_state_test.html"); + std::string app_name = "test_name"; + auto app_id = AddArcAppWithIntentFilter(app_name, test_url); + PageActionIconView* intent_picker_view = GetIntentPickerIcon(); + + chrome::NewTab(browser()); + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); + + // Navigate from a link. + NavigateParams params(browser(), test_url, + ui::PageTransition::PAGE_TRANSITION_LINK); + + views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{}, + "IntentPickerBubbleView"); + // Navigates and waits for loading to finish. + ui_test_utils::NavigateToURL(¶ms); + + waiter.WaitIfNeededAndGet(); + EXPECT_TRUE(intent_picker_view->GetVisible()); + ASSERT_TRUE(intent_picker_bubble()); + EXPECT_TRUE(intent_picker_bubble()->GetVisible()); + EXPECT_EQ(1U, intent_picker_bubble()->GetScrollViewSize()); + auto& app_info = intent_picker_bubble()->app_info_for_testing(); + ASSERT_EQ(1U, app_info.size()); + EXPECT_EQ(app_id, app_info[0].launch_name); + EXPECT_EQ(app_name, app_info[0].display_name); + EXPECT_TRUE(intent_picker_bubble()->Close()); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + content::TestNavigationObserver observer(web_contents); + SimulateMouseClickOrTapElementWithId(web_contents, "push_to_new_url_button"); + observer.WaitForNavigationFinished(); + EXPECT_FALSE(intent_picker_view->GetVisible()); +} + +// Test that reload a page after app installation will show intent picker. +IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS, + ReloadAfterInstall) { + GURL test_url("https://www.google.com/"); + PageActionIconView* intent_picker_view = GetIntentPickerIcon(); + + chrome::NewTab(browser()); + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); + + // Navigate from a link. + NavigateParams params(browser(), test_url, + ui::PageTransition::PAGE_TRANSITION_LINK); + + // Navigates and waits for loading to finish. + ui_test_utils::NavigateToURL(¶ms); + + WaitForAppService(); + EXPECT_FALSE(intent_picker_view->GetVisible()); + + std::string app_name = "test_name"; + auto app_id = AddArcAppWithIntentFilter(app_name, test_url); + + // Reload the page and the intent picker should show up. + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + content::TestNavigationObserver observer(web_contents); + chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); + observer.WaitForNavigationFinished(); + + EXPECT_TRUE(intent_picker_view->GetVisible()); + + ClickIconToShowBubble(); + EXPECT_EQ(1U, intent_picker_bubble()->GetScrollViewSize()); + auto& app_info = intent_picker_bubble()->app_info_for_testing(); + ASSERT_EQ(1U, app_info.size()); + EXPECT_EQ(app_id, app_info[0].launch_name); + EXPECT_EQ(app_name, app_info[0].display_name); + + // Launch the default selected app. + EXPECT_EQ(0U, launched_arc_apps().size()); + intent_picker_bubble()->AcceptDialog(); + WaitForAppService(); + ASSERT_EQ(1U, launched_arc_apps().size()); + EXPECT_EQ(app_name, launched_arc_apps()[0].activity->package_name); + EXPECT_EQ(test_url.spec(), launched_arc_apps()[0].intent->data); +}
diff --git a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc index fa12bc3..8b71363 100644 --- a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc +++ b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc
@@ -63,7 +63,7 @@ // computation of |anchor_bounds| in CreateMediaRouterDialog() below, but // just doing the same thing here doesn't work. I suspect that approach // will work, though, once the issue causing the blue border is fixed. - scoped_widget_observer_.Add( + scoped_widget_observations_.AddObservation( MediaDialogView::ShowDialog(media_button, service, profile)); return true; } else { @@ -104,7 +104,8 @@ dialog_creation_time, activation_location); } - scoped_widget_observer_.Add(CastDialogView::GetCurrentDialogWidget()); + scoped_widget_observations_.AddObservation( + CastDialogView::GetCurrentDialogWidget()); if (dialog_creation_callback_) dialog_creation_callback_.Run(); @@ -129,11 +130,11 @@ } void MediaRouterDialogControllerViews::OnWidgetClosing(views::Widget* widget) { - DCHECK(scoped_widget_observer_.IsObserving(widget)); + DCHECK(scoped_widget_observations_.IsObservingSource(widget)); if (ui_) ui_->LogMediaSinkStatus(); Reset(); - scoped_widget_observer_.Remove(widget); + scoped_widget_observations_.RemoveObservation(widget); } void MediaRouterDialogControllerViews::SetDialogCreationCallbackForTesting(
diff --git a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h index 5351b6c..40f19f28 100644 --- a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h +++ b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/observer_list.h" -#include "base/scoped_observer.h" +#include "base/scoped_multi_source_observation.h" #include "chrome/browser/ui/media_router/media_router_ui_service.h" #include "components/media_router/browser/media_router_dialog_controller.h" #include "content/public/browser/web_contents_user_data.h" @@ -73,8 +73,8 @@ base::RepeatingClosure dialog_creation_callback_; - ScopedObserver<views::Widget, views::WidgetObserver> scoped_widget_observer_{ - this}; + base::ScopedMultiSourceObservation<views::Widget, views::WidgetObserver> + scoped_widget_observations_{this}; // Service that provides MediaRouterActionController. It outlives |this|. MediaRouterUIService* const media_router_ui_service_;
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc index 734e371..d8bbf6d 100644 --- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc +++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
@@ -49,7 +49,7 @@ #if defined(OS_CHROMEOS) #include "ash/public/cpp/window_properties.h" #include "base/callback.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" @@ -67,7 +67,7 @@ FullscreenWindowObserver(aura::Window* observed_window, base::RepeatingClosure on_fullscreen_change) : on_fullscreen_change_(on_fullscreen_change) { - observed_window_.Add(observed_window); + window_observation_.Observe(observed_window); } ~FullscreenWindowObserver() override = default; @@ -89,12 +89,13 @@ } void OnWindowDestroying(aura::Window* window) override { - observed_window_.Remove(window); + window_observation_.RemoveObservation(); } base::RepeatingClosure on_fullscreen_change_; - ScopedObserver<aura::Window, aura::WindowObserver> observed_window_{this}; + base::ScopedObservation<aura::Window, aura::WindowObserver> + window_observation_{this}; DISALLOW_COPY_AND_ASSIGN(FullscreenWindowObserver); };
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc index 8ca1d8f..4d12f607 100644 --- a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc +++ b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc
@@ -9,6 +9,7 @@ #include "base/i18n/rtl.h" #include "base/strings/string16.h" +#include "base/time/time.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sharesheet/sharesheet_metrics.h" @@ -24,11 +25,15 @@ #include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/compositor/closure_animation_observer.h" +#include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/animation/tween.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/font_list.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image_skia.h" +#include "ui/gfx/transform_util.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/bubble/bubble_border.h" #include "ui/views/bubble/bubble_frame_view.h" @@ -72,6 +77,9 @@ constexpr int kSpacing = 24; constexpr int kTitleLineHeight = 24; +constexpr float kSharesheetOpacityTranslucent = 0.0f; +constexpr float kSharesheetOpacityOpaque = 1.0f; + constexpr char kTitleFont[] = "GoogleSans, Medium, 16px"; constexpr char kExpandViewTitleFont[] = "Roboto, Medium, 15px"; @@ -162,9 +170,9 @@ main_view_->RequestFocus(); main_view_->GetViewAccessibility().OverrideName( l10n_util::GetStringUTF16(IDS_SHARESHEET_TITLE_LABEL)); - views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this); + views::BubbleDialogDelegateView::CreateBubble(this); GetWidget()->GetRootView()->Layout(); - widget->Show(); + ShowWidgetWithAnimateFadeIn(); if (expanded_view_ == nullptr || expanded_view_->children().size() > 1) { SetToDefaultBubbleSizing(); @@ -290,20 +298,20 @@ UpdateAnchorPosition(); } +// This function is called from a ShareAction or after an app launches. void SharesheetBubbleView::CloseBubble() { - views::Widget* widget = View::GetWidget(); - widget->CloseWithReason(views::Widget::ClosedReason::kAcceptButtonClicked); - // Reset all bubble values. - active_target_ = base::string16(); - intent_.reset(); - keyboard_highlighted_target_ = 0; - SetToDefaultBubbleSizing(); + if (!is_bubble_closing_) { + CloseWidgetWithAnimateFadeOut( + views::Widget::ClosedReason::kAcceptButtonClicked); + } } void SharesheetBubbleView::OnKeyEvent(ui::KeyEvent* event) { + // Ignore key press if bubble is closing. // TODO(crbug.com/1141741) Update to OnKeyPressed. if (!IsKeyboardCodeArrow(event->key_code()) || - event->type() != ui::ET_KEY_RELEASED || default_view_ == nullptr) { + event->type() != ui::ET_KEY_RELEASED || default_view_ == nullptr || + is_bubble_closing_) { return; } @@ -368,21 +376,23 @@ return gfx::Size(width_, height_); } -void SharesheetBubbleView::OnWidgetDestroyed(views::Widget* widget) { - // If there is no active_target_ value, the user cancelled without making a - // selection and we will record this. - if (user_cancelled_) { +void SharesheetBubbleView::OnWidgetActivationChanged(views::Widget* widget, + bool active) { + // Catch widgets that are closing due to the user clicking out of the bubble. + // If |user_selection_made_| we should not close the bubble here as it will be + // closed in a different code path. + if (!active && !user_selection_made_) { + if (close_callback_) { + std::move(close_callback_).Run(sharesheet::SharesheetResult::kCancel); + } sharesheet::SharesheetMetrics::RecordSharesheetActionMetrics( sharesheet::SharesheetMetrics::UserAction::kCancelled); - } - delegate_->OnBubbleClosed(active_target_); - if (close_callback_) { - std::move(close_callback_).Run(sharesheet::SharesheetResult::kCancel); + CloseWidgetWithAnimateFadeOut(views::Widget::ClosedReason::kLostFocus); } } void SharesheetBubbleView::CreateBubble() { - set_close_on_deactivate(true); + set_close_on_deactivate(false); SetButtons(ui::DIALOG_BUTTON_NONE); SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -418,6 +428,7 @@ } void SharesheetBubbleView::TargetButtonPressed(TargetInfo target) { + user_selection_made_ = true; auto type = target.type; if (type == sharesheet::TargetType::kAction) active_target_ = target.launch_name; @@ -426,7 +437,6 @@ delegate_->OnTargetSelected(target.launch_name, type, std::move(intent_), share_action_view_); intent_.reset(); - user_cancelled_ = false; if (close_callback_) std::move(close_callback_).Run(sharesheet::SharesheetResult::kSuccess); } @@ -454,3 +464,61 @@ width_ = kDefaultBubbleWidth; height_ = kDefaultBubbleHeight; } + +void SharesheetBubbleView::ShowWidgetWithAnimateFadeIn() { + constexpr float kSharesheetScaleUpFactor = 0.8f; + constexpr base::TimeDelta kSharesheetScaleUpTime = + base::TimeDelta::FromMilliseconds(150); + constexpr base::TimeDelta kSharesheetOpacityFadeInTime = + base::TimeDelta::FromMilliseconds(100); + + views::Widget* widget = View::GetWidget(); + ui::Layer* layer = widget->GetLayer(); + + layer->SetOpacity(kSharesheetOpacityTranslucent); + widget->ShowInactive(); + gfx::Transform transform = gfx::GetScaleTransform( + gfx::Rect(layer->size()).CenterPoint(), kSharesheetScaleUpFactor); + layer->SetTransform(transform); + auto scoped_settings = + std::make_unique<ui::ScopedLayerAnimationSettings>(layer->GetAnimator()); + + scoped_settings->SetTransitionDuration(kSharesheetScaleUpTime); + scoped_settings->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); + layer->SetTransform(gfx::Transform()); + + scoped_settings->SetTransitionDuration(kSharesheetOpacityFadeInTime); + scoped_settings->SetTweenType(gfx::Tween::Type::LINEAR); + layer->SetOpacity(kSharesheetOpacityOpaque); + widget->Activate(); +} + +void SharesheetBubbleView::CloseWidgetWithAnimateFadeOut( + views::Widget::ClosedReason closed_reason) { + constexpr base::TimeDelta kSharesheetOpacityFadeOutTime = + base::TimeDelta::FromMilliseconds(80); + + is_bubble_closing_ = true; + ui::Layer* layer = View::GetWidget()->GetLayer(); + // If open animation is still running, abort it as we are now closing. + layer->GetAnimator()->AbortAllAnimations(); + auto scoped_settings = + std::make_unique<ui::ScopedLayerAnimationSettings>(layer->GetAnimator()); + scoped_settings->SetTweenType(gfx::Tween::Type::LINEAR); + scoped_settings->SetTransitionDuration(kSharesheetOpacityFadeOutTime); + layer->SetOpacity(kSharesheetOpacityTranslucent); + // We are closing the native widget during the close animation which results + // in destroying the layer and the animation and the observer not calling + // back. Thus it is safe to use base::Unretained here. + scoped_settings->AddObserver(new ui::ClosureAnimationObserver( + base::BindOnce(&SharesheetBubbleView::CloseWidgetWithReason, + base::Unretained(this), closed_reason))); +} + +void SharesheetBubbleView::CloseWidgetWithReason( + views::Widget::ClosedReason closed_reason) { + View::GetWidget()->CloseWithReason(closed_reason); + + // Bubble is deleted here. + delegate_->OnBubbleClosed(active_target_); +}
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.h b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.h index 562698ee..fc8f91e1 100644 --- a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.h +++ b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.h
@@ -57,7 +57,7 @@ // views::BubbleDialogDelegateView: gfx::Size CalculatePreferredSize() const override; - void OnWidgetDestroyed(views::Widget* widget) override; + void OnWidgetActivationChanged(views::Widget* widget, bool active) override; void CreateBubble(); std::unique_ptr<views::View> MakeScrollableTargetView( @@ -69,6 +69,9 @@ void TargetButtonPressed(TargetInfo target); void UpdateAnchorPosition(); void SetToDefaultBubbleSizing(); + void ShowWidgetWithAnimateFadeIn(); + void CloseWidgetWithAnimateFadeOut(views::Widget::ClosedReason closed_reason); + void CloseWidgetWithReason(views::Widget::ClosedReason closed_reason); // Owns this class. sharesheet::SharesheetServiceDelegate* delegate_; @@ -78,8 +81,9 @@ int width_ = 0; int height_ = 0; - bool user_cancelled_ = true; bool show_expanded_view_ = false; + bool is_bubble_closing_ = false; + bool user_selection_made_ = false; size_t keyboard_highlighted_target_ = 0;
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 121f655bd..c546a70 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -80,6 +80,7 @@ #include "chrome/browser/ui/webui/chromeos/login/supervision_transition_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_handler.h" #include "chrome/browser/ui/webui/chromeos/login/tpm_error_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/update_required_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h" @@ -144,6 +145,8 @@ constexpr char kProductLogoPath[] = "product-logo.png"; constexpr char kRecommendAppListViewHTMLPath[] = "recommend_app_list_view.html"; constexpr char kRecommendAppListViewJSPath[] = "recommend_app_list_view.js"; +constexpr char kTestAPIJSPath[] = "test_api.js"; + // Components constexpr char kCommonStylesHTML[] = "components/common_styles.html"; constexpr char kI18nBehaviorHTML[] = "components/oobe_i18n_behavior.html"; @@ -290,6 +293,17 @@ } } +void AddTestAPIResources(content::WebUIDataSource* source) { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + bool enable_test_api = + command_line->HasSwitch(::chromeos::switches::kEnableOobeTestAPI); + if (enable_test_api) { + source->AddResourcePath(kTestAPIJSPath, IDR_OOBE_TEST_API_JS); + } else { + source->AddResourcePath(kTestAPIJSPath, IDR_OOBE_TEST_API_STUB_JS); + } +} + // Default and non-shared resource definition for kOobeDisplay display type. // chrome://oobe/oobe void AddOobeDisplayTypeDefaultResources(content::WebUIDataSource* source) { @@ -344,6 +358,7 @@ AddMarketingOptInResources(source); AddDebuggerResources(source); + AddTestAPIResources(source); source->AddResourcePath(kKeyboardUtilsJSPath, IDR_KEYBOARD_UTILS_JS); source->OverrideContentSecurityPolicy( @@ -606,6 +621,13 @@ std::make_unique<DebugOverlayHandler>(js_calls_container_.get())); } + bool enable_test_api = + command_line->HasSwitch(::chromeos::switches::kEnableOobeTestAPI); + if (enable_test_api) { + AddWebUIHandler( + std::make_unique<OobeTestAPIHandler>(js_calls_container_.get())); + } + base::DictionaryValue localized_strings; GetLocalizedStrings(&localized_strings);
diff --git a/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_browsertest.cc b/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_browsertest.cc new file mode 100644 index 0000000..48ad0f8 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_browsertest.cc
@@ -0,0 +1,54 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "build/branding_buildflags.h" +#include "chrome/browser/chromeos/login/test/oobe_base_test.h" +#include "chrome/browser/chromeos/login/test/test_condition_waiter.h" +#include "chromeos/constants/chromeos_switches.h" +#include "content/public/test/browser_test.h" + +namespace chromeos { + +class OobeTestApiTest : public OobeBaseTest { + public: + OobeTestApiTest() {} + ~OobeTestApiTest() override {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(switches::kEnableOobeTestAPI); + OobeBaseTest::SetUpCommandLine(command_line); + } +}; + +IN_PROC_BROWSER_TEST_F(OobeTestApiTest, OobeAPI) { + test::OobeJS().CreateWaiter("window.OobeAPI")->Wait(); + test::OobeJS() + .CreateWaiter("OobeAPI.screens.WelcomeScreen.isVisible()") + ->Wait(); + test::OobeJS().Evaluate("OobeAPI.screens.WelcomeScreen.clickNext()"); + test::OobeJS() + .CreateWaiter("OobeAPI.screens.NetworkScreen.isVisible()") + ->Wait(); + test::OobeJS().Evaluate("OobeAPI.screens.NetworkScreen.clickNext()"); + +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + test::OobeJS().ExpectFalse("OobeAPI.screens.EulaScreen.shouldSkip()"); + test::OobeJS().CreateWaiter("OobeAPI.screens.EulaScreen.isVisible()")->Wait(); + test::OobeJS().Evaluate("OobeAPI.screens.EulaScreen.clickNext()"); +#else + test::OobeJS().ExpectTrue("OobeAPI.screens.EulaScreen.shouldSkip()"); +#endif +} + +class NoOobeTestApiTest : public OobeBaseTest { + public: + NoOobeTestApiTest() {} + ~NoOobeTestApiTest() override {} +}; + +IN_PROC_BROWSER_TEST_F(NoOobeTestApiTest, NoOobeAPI) { + test::OobeJS().ExpectFalse("window.OobeAPI"); +} + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_handler.cc b/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_handler.cc new file mode 100644 index 0000000..5c3beb7 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_handler.cc
@@ -0,0 +1,27 @@ +// 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/webui/chromeos/login/testapi/oobe_test_api_handler.h" + +#include "build/branding_buildflags.h" + +namespace chromeos { + +OobeTestAPIHandler::OobeTestAPIHandler(JSCallsContainer* js_calls_container) + : BaseWebUIHandler(js_calls_container) { + DCHECK(js_calls_container); +} + +OobeTestAPIHandler::~OobeTestAPIHandler() {} + +void OobeTestAPIHandler::DeclareLocalizedValues( + ::login::LocalizedValuesBuilder* builder) {} + +void OobeTestAPIHandler::Initialize() {} + +void OobeTestAPIHandler::GetAdditionalParameters(base::DictionaryValue* dict) { + dict->SetBoolean("isBrandedBuild", BUILDFLAG(GOOGLE_CHROME_BRANDING)); +} + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_handler.h b/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_handler.h new file mode 100644 index 0000000..220776d --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/login/testapi/oobe_test_api_handler.h
@@ -0,0 +1,29 @@ +// Copyright (c) 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_TESTAPI_OOBE_TEST_API_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_TESTAPI_OOBE_TEST_API_HANDLER_H_ + +#include "base/values.h" +#include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h" + +namespace chromeos { + +class OobeTestAPIHandler : public BaseWebUIHandler { + public: + explicit OobeTestAPIHandler(JSCallsContainer* js_calls_container); + ~OobeTestAPIHandler() override; + OobeTestAPIHandler(const OobeTestAPIHandler&) = delete; + OobeTestAPIHandler& operator=(const OobeTestAPIHandler&) = delete; + + // WebUIMessageHandler implementation: + void DeclareLocalizedValues( + ::login::LocalizedValuesBuilder* builder) override; + void Initialize() override; + void GetAdditionalParameters(base::DictionaryValue* dict) override; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_TESTAPI_OOBE_TEST_API_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc index b4c82c13..f2f552b 100644 --- a/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc
@@ -41,7 +41,8 @@ mojom::SearchResultDefaultRank::kHigh, mojom::SearchResultType::kSubpage, {.subpage = mojom::Subpage::kCrostiniDetails}, - {IDS_OS_SETTINGS_TAG_CROSTINI_ALT1, SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_CROSTINI_ALT1, IDS_OS_SETTINGS_TAG_CROSTINI_ALT2, + SearchConcept::kAltTagEnd}}, {IDS_OS_SETTINGS_TAG_CROSTINI_USB_PREFERENCES, mojom::kCrostiniUsbPreferencesSubpagePath, mojom::SearchResultIcon::kPenguin, @@ -93,7 +94,8 @@ mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSection, {.section = mojom::Section::kCrostini}, - {IDS_OS_SETTINGS_TAG_CROSTINI_ALT1, SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_CROSTINI_ALT1, IDS_OS_SETTINGS_TAG_CROSTINI_ALT2, + SearchConcept::kAltTagEnd}}, {IDS_OS_SETTINGS_TAG_CROSTINI_SETUP, mojom::kCrostiniSectionPath, mojom::SearchResultIcon::kPenguin,
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 475535d..70e9d740 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1605722062-63dbc729233b875bed4d9f1fa158097610c580cf.profdata +chrome-linux-master-1605743960-c6eb23d92bd5ebb2b738686f930937312c075c5e.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index c114476..c05ea1ae 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1605689852-f178b38050a80e7ec32f221b3018d4e55c9e1dbc.profdata +chrome-win32-master-1605732977-09df8fbd862d08eaa283942ed13244c34d12f091.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index ec82fcdb..2416e65 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1605700503-d95dd16f6b81bc506b282993a455cc1291c6d3ef.profdata +chrome-win64-master-1605732977-d582403d24e72f4b574d0b095493057d717a9e6c.profdata
diff --git a/chrome/common/extensions/api/input_ime.json b/chrome/common/extensions/api/input_ime.json index bdde0826..b0a8078 100644 --- a/chrome/common/extensions/api/input_ime.json +++ b/chrome/common/extensions/api/input_ime.json
@@ -719,6 +719,7 @@ } ] }, + // TODO(crbug.com/1148579): Deprecate onInputContextUpdate. { "name": "onInputContextUpdate", "type": "function",
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index b34ae4af..26e390a 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -2008,8 +2008,7 @@ const char kEnableAuthNegotiatePort[] = "auth.enable_negotiate_port"; // Allowlist containing servers for which Integrated Authentication is enabled. -// Note that this used to be `kAuthServerWhitelist`, hence the difference -// between the variable name and the string value. +// This pref should match |android_webview::prefs::kAuthServerAllowlist|. const char kAuthServerAllowlist[] = "auth.server_allowlist"; // Allowlist containing servers Chrome is allowed to do Kerberos delegation
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc index 485212d..11fa44e 100644 --- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -175,9 +175,10 @@ source_map->RegisterSource("chromeos.ime.service", IDR_IME_SERVICE_BINDINGS_JS); - source_map->RegisterSource("chromeos.tts.mojom.tts_stream.mojom", - IDR_TTS_STREAM_MOJOM_JS); - source_map->RegisterSource("chromeos.tts.stream", IDR_TTS_STREAM_BINDINGS_JS); + source_map->RegisterSource("chromeos.tts.mojom.tts_stream_factory.mojom", + IDR_TTS_STREAM_FACTORY_MOJOM_JS); + source_map->RegisterSource("chromeos.tts.stream_factory", + IDR_TTS_STREAM_FACTORY_BINDINGS_JS); // Imprivata API. source_map->RegisterSource("chromeos.remote_apps.mojom-lite",
diff --git a/chrome/renderer/resources/extensions/chromeos_tts_stream_bindings.js b/chrome/renderer/resources/extensions/chromeos_tts_stream_factory_bindings.js similarity index 67% rename from chrome/renderer/resources/extensions/chromeos_tts_stream_bindings.js rename to chrome/renderer/resources/extensions/chromeos_tts_stream_factory_bindings.js index de636071..20356b8 100644 --- a/chrome/renderer/resources/extensions/chromeos_tts_stream_bindings.js +++ b/chrome/renderer/resources/extensions/chromeos_tts_stream_factory_bindings.js
@@ -9,11 +9,11 @@ } mojo.config.autoLoadMojomDeps = false; -loadScript('chromeos.tts.mojom.tts_stream.mojom'); +loadScript('chromeos.tts.mojom.tts_stream_factory.mojom'); (function() { - let ptr = new chromeos.tts.mojom.TtsStreamPtr; + let ptr = new chromeos.tts.mojom.TtsStreamFactoryPtr; Mojo.bindInterface( - chromeos.tts.mojom.TtsStream.name, mojo.makeRequest(ptr).handle); + chromeos.tts.mojom.TtsStreamFactory.name, mojo.makeRequest(ptr).handle); exports.$set('returnValue', ptr); })();
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd index 6de99fc..a8b0bd1 100644 --- a/chrome/renderer/resources/renderer_resources.grd +++ b/chrome/renderer/resources/renderer_resources.grd
@@ -70,8 +70,8 @@ <include name="IDR_REMOTE_APPS_MOJOM_LITE_JS" file="${mojom_root}\chromeos\components\remote_apps\mojom\remote_apps.mojom-lite.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_MOJO_URL_MOJOM_LITE_JS" file="${mojom_root}\url\mojom\url.mojom-lite.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_TTS_STREAM_BINDINGS_JS" file="extensions\chromeos_tts_stream_bindings.js" type="BINDATA" /> - <include name="IDR_TTS_STREAM_MOJOM_JS" file="${mojom_root}\chromeos\services\tts\public\mojom\tts_service.mojom.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_TTS_STREAM_FACTORY_BINDINGS_JS" file="extensions\chromeos_tts_stream_factory_bindings.js" type="BINDATA" /> + <include name="IDR_TTS_STREAM_FACTORY_MOJOM_JS" file="${mojom_root}\chromeos\services\tts\public\mojom\tts_service.mojom.js" use_base_dir="false" type="BINDATA" /> </if> <!-- Media Router Mojo service and bindings. --> <include name="IDR_MEDIA_CONTROLLER_MOJOM_JS" file="${mojom_root}\components\media_router\common\mojom\media_controller.mojom.js" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 05bbef22..9030af1 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2791,6 +2791,7 @@ "../browser/ui/webui/chromeos/login/js_calls_container_test_api.cc", "../browser/ui/webui/chromeos/login/js_calls_container_test_api.h", "../browser/ui/webui/chromeos/login/oobe_display_chooser_browsertest.cc", + "../browser/ui/webui/chromeos/login/testapi/oobe_test_api_browsertest.cc", "../browser/ui/webui/chromeos/smb_shares/smb_credentials_dialog_browsertest.cc", "../browser/ui/webui/chromeos/system_web_dialog_browsertest.cc", "../browser/ui/webui/settings/chromeos/account_manager_handler_browsertest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ViewUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ViewUtils.java index 1bc2f1c..4b814b9e 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ViewUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ViewUtils.java
@@ -11,6 +11,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -188,4 +189,8 @@ "The view has layout requested.", view.isLayoutRequested(), is(false)); }); } + + public static MotionEvent createMotionEvent(float x, float y) { + return MotionEvent.obtain(0, 0, 0, x, y, 0); + } }
diff --git a/chrome/test/data/intent_picker/push_state_test.html b/chrome/test/data/intent_picker/push_state_test.html new file mode 100644 index 0000000..b9c427d --- /dev/null +++ b/chrome/test/data/intent_picker/push_state_test.html
@@ -0,0 +1,17 @@ +<html> +<head> +<script> +window.onload = function() { + history.pushState("", ""); +} + +function pushToNewUrl() { + history.pushState("", "", "/newurl.html"); +} +</script> +</head> + +<body> +<button id="push_to_new_url_button" onclick="pushToNewUrl()">push to new url</button> +</body> +</html> \ No newline at end of file
diff --git a/chrome/test/data/webui/tab_search/tab_search_app_test.js b/chrome/test/data/webui/tab_search/tab_search_app_test.js index e2c396b..1317125 100644 --- a/chrome/test/data/webui/tab_search/tab_search_app_test.js +++ b/chrome/test/data/webui/tab_search/tab_search_app_test.js
@@ -12,7 +12,7 @@ import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../../chai_assert.js'; import {flushTasks, waitAfterNextRender} from '../../test_util.m.js'; -import {sampleData} from './tab_search_test_data.js'; +import {generateSampleDataFromSiteNames, sampleData} from './tab_search_test_data.js'; import {initLoadTimeDataWithDefaults} from './tab_search_test_helper.js'; import {TestTabSearchApiProxy} from './test_tab_search_api_proxy.js'; @@ -164,6 +164,27 @@ assertEquals(0, tabSearchApp.getSelectedIndex()); }); + test( + 'Verify all list items are present when Shift+Tab navigating from the search field to the last item', + async () => { + const siteNames = Array.from({length: 20}, (_, i) => 'site' + (i + 1)); + const testData = generateSampleDataFromSiteNames(siteNames); + await setupTest(testData); + + const numTabs = + testData.windows.reduce((total, w) => total + w.tabs.length, 0); + const searchField = /** @type {!TabSearchSearchField} */ + (tabSearchApp.shadowRoot.querySelector('#searchField')); + + keyDownOn(searchField, 0, ['shift'], 'Tab'); + await waitAfterNextRender(tabSearchApp); + + // Since default actions are not triggered via simulated events we rely + // on asserting the expected DOM item count necessary to focus the last + // item is present. + assertEquals(siteNames.length, queryRows().length); + }); + test('Key with modifiers should not affect selected item', async () => { await setupTest(sampleData());
diff --git a/chrome/test/enterprise/e2e/.vpython b/chrome/test/enterprise/e2e/.vpython index 5a12cb01..744b85c 100644 --- a/chrome/test/enterprise/e2e/.vpython +++ b/chrome/test/enterprise/e2e/.vpython
@@ -11,8 +11,8 @@ wheel: < name: "infra/celab/celab/windows-amd64" - # Source: https://ci.chromium.org/p/celab/builders/ci/Windows/b8877198546412479520 - version: "LveMRjyFsgdFha5yWzmDnWx3MqNWA5j9Xt_brzfxWx8C" + # Source: https://ci.chromium.org/p/celab/builders/ci/Windows/b8863242163218578192 + version: "IQHknf30R2DyRmnCQ9PWQToO1x-rS7ecoTeaDqncGmoC" > # googleapiclient
diff --git a/chrome/test/enterprise/e2e/policy/cloud_management_enrollment_token/cloud_management_enrollment_token.py b/chrome/test/enterprise/e2e/policy/cloud_management_enrollment_token/cloud_management_enrollment_token.py index 02596315..3599ee4f 100644 --- a/chrome/test/enterprise/e2e/policy/cloud_management_enrollment_token/cloud_management_enrollment_token.py +++ b/chrome/test/enterprise/e2e/policy/cloud_management_enrollment_token/cloud_management_enrollment_token.py
@@ -44,6 +44,6 @@ os.path.join(local_dir, 'cloud_enrollment_webdriver.py')) # Verify CBCM status legend self.assertIn('Machine policies', output) - self.assertIn('CLIENT2019', output) + self.assertIn('CLIENT2016', output) self.assertIn(token, output) self.assertIn('Policy cache OK', output)
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index d26410e..740237e 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -127,8 +127,8 @@ #define MAYBE_PPAPI_NACL(test_name) test_name #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ - defined(ADDRESS_SANITIZER) -// http://crbug.com/633067, http://crbug.com/727989 + defined(OS_MACOSX) || defined(ADDRESS_SANITIZER) +// http://crbug.com/633067, http://crbug.com/727989, http://crbug.com/1076806 #define MAYBE_PPAPI_PNACL(test_name) DISABLED_##test_name #else #define MAYBE_PPAPI_PNACL(test_name) test_name
diff --git a/chrome/updater/mac/BUILD.gn b/chrome/updater/mac/BUILD.gn index 4369361..b0b0c26 100644 --- a/chrome/updater/mac/BUILD.gn +++ b/chrome/updater/mac/BUILD.gn
@@ -121,8 +121,7 @@ ] } -# TODO(crbug.com/1112471): Get this to run cleanly under Python 3. -python2_action("updater_install_script") { +action("updater_install_script") { script = "embed_variables.py" inputs = [ @@ -142,8 +141,7 @@ ] } -# TODO(crbug.com/1112471): Get this to run cleanly under Python 3. -python2_action("browser_install_script") { +action("browser_install_script") { script = "embed_variables.py" inputs = [
diff --git a/chrome/updater/mac/embed_variables.py b/chrome/updater/mac/embed_variables.py index 1e26802c..b0ac883 100644 --- a/chrome/updater/mac/embed_variables.py +++ b/chrome/updater/mac/embed_variables.py
@@ -2,12 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import ConfigParser -import glob import optparse import os -import shutil -import subprocess import sys @@ -28,7 +24,7 @@ fin.close() fout.close() - os.chmod(output_file, 0755) + os.chmod(output_file, 0o755) def parse_options():
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index a12d612..91bc55d6 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -460,7 +460,6 @@ "webview/webview_window_manager.cc", "webview/webview_window_manager.h", ] - configs += [ "//third_party/grpc:grpc_config" ] deps += [ ":web_contents_provider", "//chromecast/browser/webview/proto", @@ -468,6 +467,7 @@ "//components/exo/wayland", "//content/public/browser", "//services/viz/privileged/mojom/compositing", + "//third_party/grpc:grpc++", "//ui/display/manager", ] }
diff --git a/chromecast/browser/accessibility/flutter/BUILD.gn b/chromecast/browser/accessibility/flutter/BUILD.gn index b9043f10..0124a3b38 100644 --- a/chromecast/browser/accessibility/flutter/BUILD.gn +++ b/chromecast/browser/accessibility/flutter/BUILD.gn
@@ -26,7 +26,7 @@ "//content/public/browser", "//extensions/browser/api", "//skia", - "//third_party/grpc:grpcpp", + "//third_party/grpc:grpc++", "//ui/views", ] }
diff --git a/chromecast/browser/accessibility/proto/BUILD.gn b/chromecast/browser/accessibility/proto/BUILD.gn index e1e606b..2cd3e9c 100644 --- a/chromecast/browser/accessibility/proto/BUILD.gn +++ b/chromecast/browser/accessibility/proto/BUILD.gn
@@ -7,7 +7,7 @@ ] deps = [ - "//third_party/grpc:grpcpp", + "//third_party/grpc:grpc++", "//third_party/protobuf:protobuf_lite", ]
diff --git a/chromecast/browser/webview/client/BUILD.gn b/chromecast/browser/webview/client/BUILD.gn index 784185012..8680ac8 100644 --- a/chromecast/browser/webview/client/BUILD.gn +++ b/chromecast/browser/webview/client/BUILD.gn
@@ -21,5 +21,6 @@ "//ui/events:events_base", "//ui/events/types:headers", "//ui/gl", + "//third_party/grpc:grpc++", ] }
diff --git a/chromecast/browser/webview/proto/BUILD.gn b/chromecast/browser/webview/proto/BUILD.gn index 3a1fdd1..25e7b3e 100644 --- a/chromecast/browser/webview/proto/BUILD.gn +++ b/chromecast/browser/webview/proto/BUILD.gn
@@ -4,6 +4,6 @@ import("//third_party/grpc/grpc_library.gni") -cc_grpc_library("proto") { +grpc_library("proto") { sources = [ "webview.proto" ] }
diff --git a/chromeos/components/file_manager/resources/gen_main_html.py b/chromeos/components/file_manager/resources/gen_main_html.py index 624c8f31..72bb0f7 100755 --- a/chromeos/components/file_manager/resources/gen_main_html.py +++ b/chromeos/components/file_manager/resources/gen_main_html.py
@@ -35,7 +35,7 @@ sys.stdout.write(line.replace('href="', href)) else: sys.stdout.write(line) - # Remove files app foreground/js <script> tags: SWA app must lazy-load + # Remove files app foreground/js <script> tags: SWA app must load # them after the SWA app has initialized needed resources. elif line.find('<script src="foreground/js/') == -1: sys.stdout.write(line)
diff --git a/chromeos/components/media_app_ui/resources/app.html b/chromeos/components/media_app_ui/resources/app.html index f573ccc..b06ef75 100644 --- a/chromeos/components/media_app_ui/resources/app.html +++ b/chromeos/components/media_app_ui/resources/app.html
@@ -11,11 +11,14 @@ } </style> -<script src="/js/app_main.js"></script> +<!-- Order is important for these files since "app_main.js" reads from + `window.loadTimeData`. --> <script src="/media_app_app_scripts.js"></script> <!-- Populates `window.loadTimeData`, needs to be after "media_app_app_scripts.js" which loads "load_time_data.js" --> <script src="/strings.js"></script> +<script src="/js/app_main.js"></script> + </html>
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index f093af4..e458532 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -157,7 +157,7 @@ // Enable or disables running the Camera App as a System Web App. const base::Feature kCameraSystemWebApp{"CameraSystemWebApp", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // If enabled, will use the CDM in the Chrome OS daemon rather than loading the // CDM using the library CDM interface. @@ -398,6 +398,10 @@ // Enables "Linux and Chrome OS" support. Allows a Linux version of Chrome // ("lacros-chrome") to run as a Wayland client with this instance of Chrome // ("ash-chrome") acting as the Wayland server and window manager. +// NOTE: Use crosapi::browser_util::IsLacrosEnabled() instead of checking the +// feature directly. Lacros is not allowed for certain user types and can be +// disabled by policy. These restrictions will be lifted when Lacros development +// is complete. const base::Feature kLacrosSupport{"LacrosSupport", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -543,6 +547,10 @@ const base::Feature kShowBluetoothDebugLogToggle{ "ShowBluetoothDebugLogToggle", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables or disables verbose Bluetooth log collection for Googlers. +const base::Feature kEnableBluetoothVerboseLogsForGooglers{ + "EnableBluetoothVerboseLogsForGooglers", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables or disables showing the battery level in the System Tray and Settings // UI for supported Bluetooth Devices. const base::Feature kShowBluetoothDeviceBattery{ @@ -709,10 +717,6 @@ return base::FeatureList::IsEnabled(kKerberosSettingsSection); } -bool IsLacrosSupportEnabled() { - return base::FeatureList::IsEnabled(kLacrosSupport); -} - bool IsLoginDeviceManagementDisclosureEnabled() { return base::FeatureList::IsEnabled(kLoginDeviceManagementDisclosure); }
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index 1b0a79c..d9c79b2 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -252,6 +252,8 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kShowBluetoothDebugLogToggle; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const base::Feature kEnableBluetoothVerboseLogsForGooglers; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kShowBluetoothDeviceBattery; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kShowPlayInDemoMode; @@ -316,7 +318,6 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsInstantTetheringBackgroundAdvertisingSupported(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsKerberosSettingsSectionEnabled(); -COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsLacrosSupportEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsLoginDeviceManagementDisclosureEnabled(); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsLoginDisplayPasswordButtonEnabled();
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc index 69957b9..cc23c4d 100644 --- a/chromeos/constants/chromeos_switches.cc +++ b/chromeos/constants/chromeos_switches.cc
@@ -547,6 +547,9 @@ // testing. Limited to ChromeOS-on-linux and test images only. const char kShowOobeDevOverlay[] = "show-oobe-dev-overlay"; +// Enables OOBE testing API for tast tests. +const char kEnableOobeTestAPI[] = "enable-oobe-test-api"; + // Specifies directory for screenshots taken with OOBE UI Debugger. const char kOobeScreenshotDirectory[] = "oobe-screenshot-dir";
diff --git a/chromeos/constants/chromeos_switches.h b/chromeos/constants/chromeos_switches.h index 480bafd..fc46394 100644 --- a/chromeos/constants/chromeos_switches.h +++ b/chromeos/constants/chromeos_switches.h
@@ -208,6 +208,7 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kShelfHotseat[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kShowLoginDevOverlay[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kShowOobeDevOverlay[]; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kEnableOobeTestAPI[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kOobeScreenshotDirectory[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
diff --git a/chromeos/services/tts/BUILD.gn b/chromeos/services/tts/BUILD.gn index 05bb3072..e87ba327 100644 --- a/chromeos/services/tts/BUILD.gn +++ b/chromeos/services/tts/BUILD.gn
@@ -8,6 +8,10 @@ sources = [ "constants.cc", "constants.h", + "google_tts_stream.cc", + "google_tts_stream.h", + "playback_tts_stream.cc", + "playback_tts_stream.h", "tts_service.cc", "tts_service.h", ]
diff --git a/chromeos/services/tts/chrome_tts.h b/chromeos/services/tts/chrome_tts.h index 817f8c0..09485c15 100644 --- a/chromeos/services/tts/chrome_tts.h +++ b/chromeos/services/tts/chrome_tts.h
@@ -15,10 +15,10 @@ void GoogleTtsShutdown(); bool GoogleTtsInstallVoice(const char* voice_name, - const char* voice_bytes, + const uint8_t* voice_bytes, int size); -bool GoogleTtsInitBuffered(const char* text_jspb, int text_jspb_len); +bool GoogleTtsInitBuffered(const uint8_t* text_jspb, int text_jspb_len); int GoogleTtsReadBuffered(float* audio_channel_buffer, size_t* frames_written);
diff --git a/chromeos/services/tts/google_tts_stream.cc b/chromeos/services/tts/google_tts_stream.cc new file mode 100644 index 0000000..1870133d --- /dev/null +++ b/chromeos/services/tts/google_tts_stream.cc
@@ -0,0 +1,166 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/tts/google_tts_stream.h" + +#include <dlfcn.h> +#include <sys/resource.h> + +#include "base/files/file_util.h" +#include "chromeos/services/tts/constants.h" +#include "chromeos/services/tts/tts_service.h" + +namespace chromeos { +namespace tts { + +// Simple helper to bridge logging in the shared library to Chrome's logging. +void HandleLibraryLogging(int severity, const char* message) { + switch (severity) { + case logging::LOG_INFO: + // Suppressed. + break; + case logging::LOG_WARNING: + LOG(WARNING) << message; + break; + case logging::LOG_FATAL: + case logging::LOG_ERROR: + LOG(ERROR) << message; + break; + default: + break; + } +} + +// GoogleTtsStream is mostly glue code that adapts the TtsStream interface into +// a form needed by libchrometts.so. As is convention with shared objects, the +// lifetime of all arguments passed to the library is scoped to the function. +// +// To keep the library interface stable and prevent name mangling, all library +// methods utilize C features only. + +GoogleTtsStream::GoogleTtsStream( + TtsService* owner, + mojo::PendingReceiver<mojom::GoogleTtsStream> receiver) + : owner_(owner), stream_receiver_(this, std::move(receiver)) { + bool loaded = libchrometts_.Load(kLibchromettsPath); + if (!loaded) { + LOG(ERROR) << "Unable to load libchrometts.so."; + exit(0); + } else { + libchrometts_.GoogleTtsSetLogger(HandleLibraryLogging); + } + + stream_receiver_.set_disconnect_handler(base::BindOnce( + [](TtsService* owner) { + // The remote which lives in component extension js has been + // disconnected due to destruction or error. + owner->MaybeExit(); + }, + owner)); +} + +GoogleTtsStream::~GoogleTtsStream() = default; + +bool GoogleTtsStream::IsBound() const { + return stream_receiver_.is_bound(); +} + +void GoogleTtsStream::InstallVoice(const std::string& voice_name, + const std::vector<uint8_t>& voice_bytes, + InstallVoiceCallback callback) { + // Create a directory to place extracted voice data. + base::FilePath voice_data_path(kTempDataDirectory); + voice_data_path = voice_data_path.Append(voice_name); + if (base::DirectoryExists(voice_data_path)) { + std::move(callback).Run(true); + return; + } + + if (!base::CreateDirectoryAndGetError(voice_data_path, nullptr)) { + std::move(callback).Run(false); + return; + } + + std::move(callback).Run(libchrometts_.GoogleTtsInstallVoice( + voice_data_path.value().c_str(), &voice_bytes[0], voice_bytes.size())); +} + +void GoogleTtsStream::SelectVoice(const std::string& voice_name, + SelectVoiceCallback callback) { + base::FilePath path_prefix = + base::FilePath(kTempDataDirectory).Append(voice_name); + base::FilePath pipeline_path = path_prefix.Append("pipeline"); + std::move(callback).Run(libchrometts_.GoogleTtsInit( + pipeline_path.value().c_str(), path_prefix.value().c_str())); +} + +void GoogleTtsStream::Speak(const std::vector<uint8_t>& text_jspb, + SpeakCallback callback) { + bool status = + libchrometts_.GoogleTtsInitBuffered(&text_jspb[0], text_jspb.size()); + if (!status) { + stream_receiver_.reset(); + owner_->MaybeExit(); + return; + } + + owner_->Play(std::move(callback)); + is_buffering_ = true; + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&GoogleTtsStream::ReadMoreFrames, + weak_factory_.GetWeakPtr(), true /* is_first_buffer */)); +} + +void GoogleTtsStream::Stop() { + owner_->Stop(); + is_buffering_ = false; + libchrometts_.GoogleTtsFinalizeBuffered(); +} + +void GoogleTtsStream::SetVolume(float volume) { + owner_->SetVolume(volume); +} + +void GoogleTtsStream::Pause() { + owner_->Pause(); +} + +void GoogleTtsStream::Resume() { + owner_->Resume(); +} + +void GoogleTtsStream::ReadMoreFrames(bool is_first_buffer) { + if (!is_buffering_) { + return; + } + + TtsService::AudioBuffer buf; + buf.frames.resize(libchrometts_.GoogleTtsGetFramesInAudioBuffer()); + size_t frames_in_buf = 0; + buf.status = + libchrometts_.GoogleTtsReadBuffered(&buf.frames[0], &frames_in_buf); + + buf.frames.resize(frames_in_buf); + + buf.char_index = -1; + if (libchrometts_.GoogleTtsGetTimepointsCount() > 0) + buf.char_index = libchrometts_.GoogleTtsGetTimepointsCharIndexAtIndex(0); + + buf.is_first_buffer = is_first_buffer; + + owner_->AddAudioBuffer(std::move(buf)); + + if (buf.status <= 0) + return; + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&GoogleTtsStream::ReadMoreFrames, + weak_factory_.GetWeakPtr(), false /* is_first_buffer */)); +} + +} // namespace tts +} // namespace chromeos
diff --git a/chromeos/services/tts/google_tts_stream.h b/chromeos/services/tts/google_tts_stream.h new file mode 100644 index 0000000..30a9e24 --- /dev/null +++ b/chromeos/services/tts/google_tts_stream.h
@@ -0,0 +1,60 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_TTS_GOOGLE_TTS_STREAM_H_ +#define CHROMEOS_SERVICES_TTS_GOOGLE_TTS_STREAM_H_ + +#include "chromeos/services/tts/public/mojom/tts_service.mojom.h" +#include "library_loaders/libchrometts.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace chromeos { +namespace tts { + +class TtsService; + +class GoogleTtsStream : public mojom::GoogleTtsStream { + public: + GoogleTtsStream(TtsService* owner, + mojo::PendingReceiver<mojom::GoogleTtsStream> receiver); + ~GoogleTtsStream() override; + + bool IsBound() const; + + private: + // mojom::GoogleTtsStream: + void InstallVoice(const std::string& voice_name, + const std::vector<uint8_t>& voice_bytes, + InstallVoiceCallback callback) override; + void SelectVoice(const std::string& voice_name, + SelectVoiceCallback callback) override; + void Speak(const std::vector<uint8_t>& text_jspb, + SpeakCallback callback) override; + void Stop() override; + void SetVolume(float volume) override; + void Pause() override; + void Resume() override; + + void ReadMoreFrames(bool is_first_buffer); + + // Owning service. + TtsService* owner_; + + // Prebuilt. + LibChromeTtsLoader libchrometts_; + + // Connection to tts in the component extension. + mojo::Receiver<mojom::GoogleTtsStream> stream_receiver_; + + // Whether buffering is in progress. + bool is_buffering_ = false; + + base::WeakPtrFactory<GoogleTtsStream> weak_factory_{this}; +}; + +} // namespace tts +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_TTS_GOOGLE_TTS_STREAM_H_
diff --git a/chromeos/services/tts/playback_tts_stream.cc b/chromeos/services/tts/playback_tts_stream.cc new file mode 100644 index 0000000..90dc388a --- /dev/null +++ b/chromeos/services/tts/playback_tts_stream.cc
@@ -0,0 +1,71 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/services/tts/playback_tts_stream.h" + +#include "chromeos/services/tts/constants.h" +#include "chromeos/services/tts/tts_service.h" + +namespace chromeos { +namespace tts { + +PlaybackTtsStream::PlaybackTtsStream( + TtsService* owner, + mojo::PendingReceiver<mojom::PlaybackTtsStream> receiver) + : owner_(owner), stream_receiver_(this, std::move(receiver)) { + stream_receiver_.set_disconnect_handler(base::BindOnce( + [](TtsService* owner) { + // The remote which lives in component extension js has been + // disconnected due to destruction or error. + owner->MaybeExit(); + }, + owner)); +} + +PlaybackTtsStream::~PlaybackTtsStream() = default; + +bool PlaybackTtsStream::IsBound() const { + return stream_receiver_.is_bound(); +} + +void PlaybackTtsStream::Play(PlayCallback callback) { + owner_->Play(std::move(callback)); + + // A small buffer to signal the start of the audio for this utterance. + TtsService::AudioBuffer buf; + buf.frames.resize(1, 0); + buf.status = 1; + buf.is_first_buffer = true; + owner_->AddAudioBuffer(std::move(buf)); +} + +void PlaybackTtsStream::SendAudioBuffer( + const std::vector<float>& samples_buffer, + int32_t char_index, + bool is_done) { + TtsService::AudioBuffer buf; + buf.frames = samples_buffer; + buf.status = is_done ? 0 : 1; + buf.char_index = char_index; + owner_->AddAudioBuffer(std::move(buf)); +} + +void PlaybackTtsStream::Stop() { + owner_->Stop(); +} + +void PlaybackTtsStream::SetVolume(float volume) { + owner_->SetVolume(volume); +} + +void PlaybackTtsStream::Pause() { + owner_->Pause(); +} + +void PlaybackTtsStream::Resume() { + owner_->Resume(); +} + +} // namespace tts +} // namespace chromeos
diff --git a/chromeos/services/tts/playback_tts_stream.h b/chromeos/services/tts/playback_tts_stream.h new file mode 100644 index 0000000..c58250e --- /dev/null +++ b/chromeos/services/tts/playback_tts_stream.h
@@ -0,0 +1,46 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_TTS_PLAYBACK_TTS_STREAM_H_ +#define CHROMEOS_SERVICES_TTS_PLAYBACK_TTS_STREAM_H_ + +#include "chromeos/services/tts/public/mojom/tts_service.mojom.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace chromeos { +namespace tts { + +class TtsService; + +class PlaybackTtsStream : public mojom::PlaybackTtsStream { + public: + PlaybackTtsStream(TtsService* owner, + mojo::PendingReceiver<mojom::PlaybackTtsStream> receiver); + ~PlaybackTtsStream() override; + + bool IsBound() const; + + private: + // mojom::PlaybackTtsStream: + void Play(PlayCallback callback) override; + void SendAudioBuffer(const std::vector<float>& samples_buffer, + int32_t char_index, + bool is_done) override; + void Stop() override; + void SetVolume(float volume) override; + void Pause() override; + void Resume() override; + + // Owning service. + TtsService* owner_; + + // Connection to tts in the component extension. + mojo::Receiver<mojom::PlaybackTtsStream> stream_receiver_; +}; + +} // namespace tts +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_TTS_PLAYBACK_TTS_STREAM_H_
diff --git a/chromeos/services/tts/public/mojom/tts_service.mojom b/chromeos/services/tts/public/mojom/tts_service.mojom index 927fbde3..2651df92 100644 --- a/chromeos/services/tts/public/mojom/tts_service.mojom +++ b/chromeos/services/tts/public/mojom/tts_service.mojom
@@ -6,17 +6,49 @@ import "services/audio/public/mojom/stream_factory.mojom"; -// The main interface to the TTS engine on Chrome OS. Only used by and private -// to the Chrome OS Google TTS engine component extension. TtsService lives in a -// tts-sandboxed process. TtsEngineExtensionObserver, the other end of this -// interface, in the browser process, brokers a connection between TtsService -// and the Google TTS engine component extension through a TtsStream, but does -// not participate otherwise. +// The main interface to TTS engines on Chrome OS. Only used by and private to +// the Chrome OS Google and Espeak TTS engine component extensions. TtsService +// lives in a tts-sandboxed process. TtsEngineExtensionObserver, the other end +// of this interface, in the browser process, brokers a connection between +// TtsService and the TTS engine component extension through a TtsStreamFactory, +// but does not participate otherwise. +// +// Graph of audio data flow: +// +// <-component extension<----------------- +// / \ +// [Google|Playback]Stream TtsEventObserver +// | | +// ----------- ----------------- +// \ / +// ->TtsService-> +// <-> +// AudioOutputStream +// <-> +// AudioService interface TtsService { - // Binds a TtsStream to this service and returns an AudioOutputStream receiver - // which this service uses to play audio. - BindTtsStream(pending_receiver<TtsStream> receiver, - pending_remote<audio.mojom.StreamFactory> stream_factory); + // Binds a TtsStreamFactory implemented by this service. Returns an + // AudioOutputStream remote which is bound to AudioService in the browser and + // which pulls audio data for output. + BindTtsStreamFactory(pending_receiver<TtsStreamFactory> receiver, + pending_remote<audio.mojom.StreamFactory> stream_factory); +}; + +// Interface to create various types of tts streams. +// +// The remote is in a component extension; the receiver is the tts ervice +// utility process. +interface TtsStreamFactory { + // Obtains the tts stream used by the Google tts component extension. + CreateGoogleTtsStream() => (pending_remote<GoogleTtsStream> stream); + + // Obtains the tts stream used by extensions that can perform audio generation + // and only require output services. Currently used only by the private Espeak + // tts engine extension. + CreatePlaybackTtsStream() => ( + pending_remote<PlaybackTtsStream> stream, + int32 sample_rate, + int32 buffer_size); }; // Interface for the Google component TTS engine to control @@ -41,7 +73,7 @@ // // Note that the component extension may call Stop() early, if the TTS api // wants to, for example, stop speech. -interface TtsStream { +interface GoogleTtsStream { // Forward and install the |voice_name| encoded by |voice_bytes|. InstallVoice(string voice_name, array<uint8> voice_bytes) => (bool success); @@ -66,8 +98,59 @@ Resume(); }; -// Returned to callers of TtsStream.speak(). It receives notable events -// pertaining to the text spoken. +// Interface for a tts engine to control the TtsService's production of audio +// for engines like Espeak, which send raw audio data. +// +// The remote is in a component extension; the receiver is the tts ervice +// utility process. +// +// Example usage: +// Play() - starts playback of an utterance like 'hello world' +// SendAudioBuffer(<first 1024 frames of audio>, 0, false) +// SendAudioBuffer(<1024 more frames of audio>, -1, false) +// ... +// SendAudioBuffer(<1024 more frames of audio>, 4, false) +// ... +// SendAudioBuffer(<1024 more frames of audio>, 11, true) +// Stop() +// +// Note: Espeak-ng is currently the only remote utilizing this interface. It is +// a private component extension to CHrome OS. Its sources can be found here: +// https://chromium.googlesource.com/chromiumos/third_party/espeak-ng +interface PlaybackTtsStream { + // Start playback of audio. + Play() + => (pending_receiver<TtsEventObserver> event_observer); + + // Send audio data to the tts service; expected to be called after Play, + // Resume and before Stop, Pause. + // + // |char_index| annotates the |frames_buffer| as the character index within + // the text being spoken. This is pass along in + // |TtsEventObserver.onTimepoint| at the moment when the buffer is being + // played. + // + // |last_buffer| indicates whether or not this is the last buffer of a + // particular tts utterance string. + SendAudioBuffer( + array<float> frames_buffer, int32 char_index, bool last_buffer); + + // Stops on-going audio playback. + Stop(); + + // Sets volume of audio playback (0.0 to 1.0). + SetVolume(float volume); + + // Pauses audio playback. + Pause(); + + // Resumes audio playback. + Resume(); +}; + +// Returned to callers of GoogleTtsStream.speak() and +// PlaybackTtsStream.Play(). It receives notable events pertaining to the text +// spoken. interface TtsEventObserver { // TtsStream.Speak started speech playback. OnStart();
diff --git a/chromeos/services/tts/tts_service.cc b/chromeos/services/tts/tts_service.cc index 043597f..4a1f572 100644 --- a/chromeos/services/tts/tts_service.cc +++ b/chromeos/services/tts/tts_service.cc
@@ -16,118 +16,66 @@ namespace chromeos { namespace tts { -// Simple helper to bridge logging in the shared library to Chrome's logging. -void HandleLibraryLogging(int severity, const char* message) { - switch (severity) { - case logging::LOG_INFO: - // Suppressed. - break; - case logging::LOG_WARNING: - LOG(WARNING) << message; - break; - case logging::LOG_ERROR: - LOG(ERROR) << message; - break; - default: - break; - } -} - -// TtsService is mostly glue code that adapts the TtsStream interface into a -// form needed by libchrometts.so. As is convention with shared objects, the -// lifetime of all arguments passed to the library is scoped to the function. -// -// To keep the library interface stable and prevent name mangling, all library -// methods utilize C features only. +namespace { +constexpr int kDefaultSampleRate = 22050; +constexpr int kDefaultBufferSize = 512; +} // namespace TtsService::TtsService(mojo::PendingReceiver<mojom::TtsService> receiver) - : service_receiver_(this, std::move(receiver)), stream_receiver_(this) { + : service_receiver_(this, std::move(receiver)), tts_stream_factory_(this) { if (setpriority(PRIO_PROCESS, 0, -10 /* real time audio */) != 0) { PLOG(ERROR) << "Unable to request real time priority; performance will be " "impacted."; } - bool loaded = libchrometts_.Load(kLibchromettsPath); - if (!loaded) { - LOG(ERROR) << "Unable to load libchrometts.so."; - exit(0); - } else { - libchrometts_.GoogleTtsSetLogger(HandleLibraryLogging); - } } TtsService::~TtsService() = default; -void TtsService::BindTtsStream( - mojo::PendingReceiver<mojom::TtsStream> receiver, +void TtsService::BindTtsStreamFactory( + mojo::PendingReceiver<mojom::TtsStreamFactory> receiver, mojo::PendingRemote<audio::mojom::StreamFactory> factory) { - stream_receiver_.Bind(std::move(receiver)); - stream_receiver_.set_disconnect_handler(base::BindOnce([] { - // The remote which lives in component extension js has been disconnected - // due to destruction or error. - exit(0); - })); + tts_stream_factory_.Bind(std::move(receiver)); - // TODO(accessibility): The sample rate below can change based on the audio - // data retrieved. Plumb this data through and re-create the output device if - // it changes. - media::AudioParameters params( - media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, - 22050 /* sample rate */, libchrometts_.GoogleTtsGetFramesInAudioBuffer()); + // TODO(accessibility): make it possible to change this dynamically. + media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::CHANNEL_LAYOUT_MONO, kDefaultSampleRate, + kDefaultBufferSize); output_device_ = std::make_unique<audio::OutputDevice>( std::move(factory), params, this, std::string()); } -void TtsService::InstallVoice(const std::string& voice_name, - const std::vector<uint8_t>& voice_bytes, - InstallVoiceCallback callback) { - // Create a directory to place extracted voice data. - base::FilePath voice_data_path(kTempDataDirectory); - voice_data_path = voice_data_path.Append(voice_name); - if (base::DirectoryExists(voice_data_path)) { - std::move(callback).Run(true); - return; - } - - if (!base::CreateDirectoryAndGetError(voice_data_path, nullptr)) { - std::move(callback).Run(false); - return; - } - - std::move(callback).Run(libchrometts_.GoogleTtsInstallVoice( - voice_data_path.value().c_str(), (char*)&voice_bytes[0], - voice_bytes.size())); +void TtsService::CreateGoogleTtsStream(CreateGoogleTtsStreamCallback callback) { + mojo::PendingRemote<mojom::GoogleTtsStream> remote; + auto receiver = remote.InitWithNewPipeAndPassReceiver(); + google_tts_stream_ = + std::make_unique<GoogleTtsStream>(this, std::move(receiver)); + std::move(callback).Run(std::move(remote)); } -void TtsService::SelectVoice(const std::string& voice_name, - SelectVoiceCallback callback) { - base::FilePath path_prefix = - base::FilePath(kTempDataDirectory).Append(voice_name); - base::FilePath pipeline_path = path_prefix.Append("pipeline"); - std::move(callback).Run(libchrometts_.GoogleTtsInit( - pipeline_path.value().c_str(), path_prefix.value().c_str())); +void TtsService::CreatePlaybackTtsStream( + CreatePlaybackTtsStreamCallback callback) { + mojo::PendingRemote<mojom::PlaybackTtsStream> remote; + auto receiver = remote.InitWithNewPipeAndPassReceiver(); + playback_tts_stream_ = + std::make_unique<PlaybackTtsStream>(this, std::move(receiver)); + std::move(callback).Run(std::move(remote), kDefaultSampleRate, + kDefaultBufferSize); } -void TtsService::Speak(const std::vector<uint8_t>& text_jspb, - SpeakCallback callback) { +void TtsService::Play( + base::OnceCallback<void(::mojo::PendingReceiver<mojom::TtsEventObserver>)> + callback) { tts_event_observer_.reset(); auto pending_receiver = tts_event_observer_.BindNewPipeAndPassReceiver(); std::move(callback).Run(std::move(pending_receiver)); - bool status = libchrometts_.GoogleTtsInitBuffered((char*)&text_jspb[0], - text_jspb.size()); - if (!status) { - tts_event_observer_->OnError(); - return; - } - output_device_->Play(); +} - is_playing_ = true; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&TtsService::ReadMoreFrames, base::Unretained(this), - true /* is_first_buffer */)); +void TtsService::AddAudioBuffer(AudioBuffer buf) { + base::AutoLock al(state_lock_); + buffers_.emplace_back(std::move(buf)); } void TtsService::Stop() { @@ -148,6 +96,13 @@ output_device_->Play(); } +void TtsService::MaybeExit() { + if (google_tts_stream_ && !google_tts_stream_->IsBound() && + playback_tts_stream_ && !playback_tts_stream_->IsBound()) { + exit(0); + } +} + int TtsService::Render(base::TimeDelta delay, base::TimeTicks delay_timestamp, int prior_frames_skipped, @@ -164,7 +119,6 @@ const AudioBuffer& buf = buffers_.front(); status = buf.status; - // Done, 0, or error, -1. if (status <= 0) { if (status == -1) @@ -201,48 +155,9 @@ void TtsService::OnRenderError() {} void TtsService::StopLocked(bool clear_buffers) { - if (!is_playing_) - return; - output_device_->Pause(); - if (clear_buffers) { + if (clear_buffers) buffers_.clear(); - libchrometts_.GoogleTtsFinalizeBuffered(); - } - - is_playing_ = false; -} - -void TtsService::ReadMoreFrames(bool is_first_buffer) { - if (!is_playing_) - return; - - AudioBuffer buf; - buf.frames.resize(libchrometts_.GoogleTtsGetFramesInAudioBuffer()); - size_t frames_in_buf = 0; - buf.status = - libchrometts_.GoogleTtsReadBuffered(&buf.frames[0], &frames_in_buf); - - buf.frames.resize(frames_in_buf); - - buf.char_index = -1; - if (libchrometts_.GoogleTtsGetTimepointsCount() > 0) - buf.char_index = libchrometts_.GoogleTtsGetTimepointsCharIndexAtIndex(0); - - buf.is_first_buffer = is_first_buffer; - - { - base::AutoLock al(state_lock_); - buffers_.emplace_back(std::move(buf)); - } - - if (buf.status <= 0) - return; - - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&TtsService::ReadMoreFrames, base::Unretained(this), - false /* is_first_buffer */)); } TtsService::AudioBuffer::AudioBuffer() = default;
diff --git a/chromeos/services/tts/tts_service.h b/chromeos/services/tts/tts_service.h index 3eb7682..a69c1b2fd 100644 --- a/chromeos/services/tts/tts_service.h +++ b/chromeos/services/tts/tts_service.h
@@ -7,6 +7,8 @@ #include "base/synchronization/lock.h" #include "base/thread_annotations.h" +#include "chromeos/services/tts/google_tts_stream.h" +#include "chromeos/services/tts/playback_tts_stream.h" #include "chromeos/services/tts/public/mojom/tts_service.mojom.h" #include "library_loaders/libchrometts.h" #include "media/base/audio_renderer_sink.h" @@ -21,30 +23,48 @@ namespace tts { class TtsService : public mojom::TtsService, - public mojom::TtsStream, + public mojom::TtsStreamFactory, public media::AudioRendererSink::RenderCallback { public: + // Helper group of state to pass from main thread to audio thread. + struct AudioBuffer { + AudioBuffer(); + ~AudioBuffer(); + AudioBuffer(const AudioBuffer& other) = delete; + AudioBuffer(AudioBuffer&& other); + + std::vector<float> frames; + int char_index = -1; + int status = 0; + bool is_first_buffer = false; + }; + explicit TtsService(mojo::PendingReceiver<mojom::TtsService> receiver); ~TtsService() override; + // Audio operations. + void Play( + base::OnceCallback<void(::mojo::PendingReceiver<mojom::TtsEventObserver>)> + callback); + void AddAudioBuffer(AudioBuffer buf); + void Stop(); + void SetVolume(float volume); + void Pause(); + void Resume(); + + // Maybe exit this process. + void MaybeExit(); + private: // mojom::TtsService: - void BindTtsStream( - mojo::PendingReceiver<mojom::TtsStream> receiver, + void BindTtsStreamFactory( + mojo::PendingReceiver<mojom::TtsStreamFactory> receiver, mojo::PendingRemote<audio::mojom::StreamFactory> factory) override; - // mojom::TtsStream: - void InstallVoice(const std::string& voice_name, - const std::vector<uint8_t>& voice_bytes, - InstallVoiceCallback callback) override; - void SelectVoice(const std::string& voice_name, - SelectVoiceCallback callback) override; - void Speak(const std::vector<uint8_t>& text_jspb, - SpeakCallback callback) override; - void Stop() override; - void SetVolume(float volume) override; - void Pause() override; - void Resume() override; + // mojom::GoogleTtsStream: + void CreateGoogleTtsStream(CreateGoogleTtsStreamCallback callback) override; + void CreatePlaybackTtsStream( + CreatePlaybackTtsStreamCallback callback) override; // media::AudioRendererSink::RenderCallback: int Render(base::TimeDelta delay, @@ -57,44 +77,27 @@ void StopLocked(bool clear_buffers = true) EXCLUSIVE_LOCKS_REQUIRED(state_lock_); - void ReadMoreFrames(bool is_first_buffer); - // Connection to tts in the browser. mojo::Receiver<mojom::TtsService> service_receiver_; + // Factory creating various types of streams. + mojo::Receiver<mojom::TtsStreamFactory> tts_stream_factory_; + + std::unique_ptr<GoogleTtsStream> google_tts_stream_; + + std::unique_ptr<PlaybackTtsStream> playback_tts_stream_; + // Protects access to state from main thread and audio thread. base::Lock state_lock_; - // Prebuilt. - LibChromeTtsLoader libchrometts_; - - // Connection to tts in the component extension. - mojo::Receiver<mojom::TtsStream> stream_receiver_; - // Connection to send tts events to component extension. mojo::Remote<mojom::TtsEventObserver> tts_event_observer_; // Outputs speech synthesis to audio. std::unique_ptr<audio::OutputDevice> output_device_; - // Helper group of state to pass from main thread to audio thread. - struct AudioBuffer { - AudioBuffer(); - ~AudioBuffer(); - AudioBuffer(const AudioBuffer& other) = delete; - AudioBuffer(AudioBuffer&& other); - - std::vector<float> frames; - int char_index; - int status; - bool is_first_buffer; - }; - // The queue of audio buffers to be played by the audio thread. std::deque<AudioBuffer> buffers_ GUARDED_BY(state_lock_); - - // Tracks whether the output device is playing audio. - bool is_playing_ = false; }; } // namespace tts
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java index f61b44e6..e5a7393f 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListener.java
@@ -75,7 +75,7 @@ /** * @param end The last motion event canceling the swipe. */ - default void onSwipeFinished(MotionEvent end) {} + default void onSwipeFinished() {} /** * @param direction The {@link ScrollDirection} representing the swipe direction. @@ -155,7 +155,7 @@ final int action = event.getAction(); if ((action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) && mDirection != ScrollDirection.UNKNOWN) { - mHandler.onSwipeFinished(event); + mHandler.onSwipeFinished(); mDirection = ScrollDirection.UNKNOWN; consumed = true; } @@ -182,11 +182,6 @@ // ============================================================================================ @Override - public boolean onDown(MotionEvent e) { - return true; - } - - @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (mHandler == null || e1 == null || e2 == null) return false; @@ -216,7 +211,7 @@ if (mDirection != ScrollDirection.UNKNOWN) { mHandler.onSwipeUpdated(e2, e2.getRawX() - mMotionStartPoint.x, - e2.getRawY() - mMotionStartPoint.y, distanceX, distanceY); + e2.getRawY() - mMotionStartPoint.y, -distanceX, -distanceY); return true; }
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListenerTest.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListenerTest.java index 5c49277..cad49a3 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListenerTest.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/SwipeGestureListenerTest.java
@@ -88,10 +88,6 @@ } } Assert.assertTrue("Can not found the expected first move event", found); - - Mockito.verify(mHandler).onSwipeFinished(argumentCaptor.capture()); - Assert.assertEquals(argumentCaptor.getValue().getRawX(), - eventStream.get(eventStream.size() - 1).getRawX(), 0.1); } private List<MotionEvent> buildEventStream(
diff --git a/components/cronet/tools/generate_accept_languages.py b/components/cronet/tools/generate_accept_languages.py index f50e8a5..2db0a44 100644 --- a/components/cronet/tools/generate_accept_languages.py +++ b/components/cronet/tools/generate_accept_languages.py
@@ -13,6 +13,8 @@ # * assumes that there is only one relevant element with the # IDS_ACCEPT_LANGUAGES attribute +from __future__ import print_function + import os import re import sys @@ -40,10 +42,10 @@ def main(): with open(sys.argv[1] + "/accept_languages_table.h", "w+") as f: - print >>f, HEADER + print(HEADER, file=f) for (locale, accept_langs) in gen_accept_langs_table().items(): - print >>f, LINE(locale, accept_langs) - print >>f, FOOTER + print(LINE(locale, accept_langs), file=f) + print(FOOTER, file=f) if __name__ == "__main__": main()
diff --git a/components/cronet/tools/hide_symbols.py b/components/cronet/tools/hide_symbols.py index 5873cec..374982c1 100755 --- a/components/cronet/tools/hide_symbols.py +++ b/components/cronet/tools/hide_symbols.py
@@ -12,10 +12,13 @@ # This way, we can reduce risk of symbol conflict when linking it into apps # by exposing internal symbols, especially in third-party libraries. +from __future__ import print_function + import glob import optparse import os import subprocess +import sys # Mapping from GN's target_cpu attribute to ld's -arch parameter. @@ -59,12 +62,12 @@ assert not args developer_dir = subprocess.check_output( - ['xcode-select', '--print-path']).strip() + ['xcode-select', '--print-path'], universal_newlines=True).strip() xctoolchain_libs = glob.glob(developer_dir + '/Toolchains/XcodeDefault.xctoolchain/usr/lib' + '/clang/*/lib/darwin/*.ios.a') - print "Adding xctoolchain_libs: ", xctoolchain_libs + print("Adding xctoolchain_libs: ", xctoolchain_libs) # ld -r concatenates multiple .o files and .a files into a single .o file, # while "hiding" symbols not marked as visible. @@ -131,9 +134,9 @@ ret = os.system('xcrun nm -u "' + options.output_obj + '" | grep ___cxa_pure_virtual') if ret == 0: - print "ERROR: Found undefined libc++ symbols, " + \ - "is libc++ indcluded in dependencies?" - exit(2) + print("ERROR: Found undefined libc++ symbols, " + "is libc++ included in dependencies?") + sys.exit(2) if __name__ == "__main__":
diff --git a/components/exo/wayland/clients/color_space.cc b/components/exo/wayland/clients/color_space.cc index f83f5712..1f8100ba 100644 --- a/components/exo/wayland/clients/color_space.cc +++ b/components/exo/wayland/clients/color_space.cc
@@ -30,7 +30,7 @@ } void WriteMixedPrimaries(gbm_bo* bo, const gfx::Size& size) { - CHECK_EQ(gbm_bo_get_plane_count(bo), 1u); + CHECK_EQ(gbm_bo_get_plane_count(bo), 1); uint32_t stride; void* mapped_data; void* void_data = gbm_bo_map(bo, 0, 0, size.width(), size.height(),
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java index a1f0e9ad..c8cc0c5 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java
@@ -180,6 +180,12 @@ public static final String TAB_SWITCHER_BUTTON_CLICKED = "tab_switcher_button_clicked"; + /** Read later related events. */ + public static final String READ_LATER_CONTEXT_MENU_TAPPED = "read_later_context_menu_tapped"; + public static final String READ_LATER_ARTICLE_SAVED = "read_later_article_saved"; + public static final String READ_LATER_BOOKMARK_FOLDER_OPENED = + "read_later_bookmark_folder_opened"; + /** Video tutorial related events. */ public static final String VIDEO_TUTORIAL_DISMISSED_SUMMARY = "video_tutorial_iph_dismissed_summary";
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java index 80897ccf..8106516 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -65,6 +65,8 @@ String TRANSLATE_MENU_BUTTON_FEATURE = "IPH_TranslateMenuButton"; String EXPLORE_SITES_TILE_FEATURE = "IPH_ExploreSitesTile"; String READ_LATER_CONTEXT_MENU_FEATURE = "IPH_ReadLaterContextMenu"; + String READ_LATER_APP_MENU_BOOKMARK_THIS_PAGE_FEATURE = "IPH_ReadLaterAppMenuBookmarkThisPage"; + String READ_LATER_APP_MENU_BOOKMARKS_FEATURE = "IPH_ReadLaterAppMenuBookmarks"; /** * An IPH feature that encourages users to get better translations by enabling access to page
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index c9ca2cc..9050024 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -77,6 +77,10 @@ "IPH_QuietNotificationPrompts", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHReadLaterContextMenuFeature{ "IPH_ReadLaterContextMenu", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kIPHReadLaterAppMenuBookmarkThisPageFeature{ + "IPH_ReadLaterAppMenuBookmarkThisPage", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kIPHReadLaterAppMenuBookmarksFeature{ + "IPH_ReadLaterAppMenuBookmarks", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHEphemeralTabFeature{"IPH_EphemeralTab", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHFeedCardMenuFeature{"IPH_FeedCardMenu",
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index 430dd77..139b5dc7 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -66,6 +66,8 @@ extern const base::Feature kIPHPreviewsOmniboxUIFeature; extern const base::Feature kIPHQuietNotificationPromptsFeature; extern const base::Feature kIPHReadLaterContextMenuFeature; +extern const base::Feature kIPHReadLaterAppMenuBookmarkThisPageFeature; +extern const base::Feature kIPHReadLaterAppMenuBookmarksFeature; extern const base::Feature kIPHTabGroupsQuicklyComparePagesFeature; extern const base::Feature kIPHTabGroupsTapToSeeAnotherTabFeature; extern const base::Feature kIPHTabGroupsYourTabsAreTogetherFeature;
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index 7cb71bc..5580aeb 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -50,6 +50,8 @@ &kIPHPwaInstallAvailableFeature, &kIPHQuietNotificationPromptsFeature, &kIPHReadLaterContextMenuFeature, + &kIPHReadLaterAppMenuBookmarkThisPageFeature, + &kIPHReadLaterAppMenuBookmarksFeature, &kIPHTabGroupsQuicklyComparePagesFeature, &kIPHTabGroupsTapToSeeAnotherTabFeature, &kIPHTabGroupsYourTabsAreTogetherFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index b5c166e..bc3e77f9 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -101,6 +101,10 @@ "IPH_QuietNotificationPrompts"); DEFINE_VARIATION_PARAM(kIPHReadLaterContextMenuFeature, "IPH_ReadLaterContextMenu"); +DEFINE_VARIATION_PARAM(kIPHReadLaterAppMenuBookmarkThisPageFeature, + "IPH_ReadLaterAppMenuBookmarkThisPage"); +DEFINE_VARIATION_PARAM(kIPHReadLaterAppMenuBookmarksFeature, + "IPH_ReadLaterAppMenuBookmarks"); DEFINE_VARIATION_PARAM(kIPHTabGroupsQuicklyComparePagesFeature, "IPH_TabGroupsQuicklyComparePages"); DEFINE_VARIATION_PARAM(kIPHTabGroupsTapToSeeAnotherTabFeature, @@ -195,6 +199,8 @@ VARIATION_ENTRY(kIPHPwaInstallAvailableFeature), VARIATION_ENTRY(kIPHQuietNotificationPromptsFeature), VARIATION_ENTRY(kIPHReadLaterContextMenuFeature), + VARIATION_ENTRY(kIPHReadLaterAppMenuBookmarkThisPageFeature), + VARIATION_ENTRY(kIPHReadLaterAppMenuBookmarksFeature), VARIATION_ENTRY(kIPHTabGroupsQuicklyComparePagesFeature), VARIATION_ENTRY(kIPHTabGroupsTapToSeeAnotherTabFeature), VARIATION_ENTRY(kIPHTabGroupsYourTabsAreTogetherFeature),
diff --git a/components/history/core/browser/top_sites_database.cc b/components/history/core/browser/top_sites_database.cc index 69acd49..9407eda7 100644 --- a/components/history/core/browser/top_sites_database.cc +++ b/components/history/core/browser/top_sites_database.cc
@@ -564,13 +564,12 @@ } sql::Database* TopSitesDatabase::CreateDB(const base::FilePath& db_name) { - std::unique_ptr<sql::Database> db(new sql::Database()); // Settings copied from FaviconDatabase. + auto db = std::make_unique<sql::Database>(sql::DatabaseOptions{ + .exclusive_locking = false, .page_size = 4096, .cache_size = 32}); db->set_histogram_tag("TopSites"); db->set_error_callback( base::BindRepeating(&DatabaseErrorCallback, db.get(), db_name)); - db->set_page_size(4096); - db->set_cache_size(32); if (!db->Open(db_name)) return nullptr;
diff --git a/components/javascript_dialogs/app_modal_dialog_manager.cc b/components/javascript_dialogs/app_modal_dialog_manager.cc index 16967487..723b95bb 100644 --- a/components/javascript_dialogs/app_modal_dialog_manager.cc +++ b/components/javascript_dialogs/app_modal_dialog_manager.cc
@@ -240,7 +240,7 @@ ShouldDisplaySuppressCheckbox(extra_data), true, // is_before_unload_dialog is_reload, - base::BindOnce(&AppModalDialogManager::OnBeforeUnloadDialogClosed, + base::BindOnce(&AppModalDialogManager::OnDialogClosed, base::Unretained(this), web_contents, std::move(callback)))); } @@ -290,24 +290,6 @@ javascript_dialog_extra_data_.erase(web_contents); } -void AppModalDialogManager::OnBeforeUnloadDialogClosed( - content::WebContents* web_contents, - DialogClosedCallback callback, - bool success, - const base::string16& user_input) { - enum class StayVsLeave { - STAY = 0, - LEAVE = 1, - MAX, - }; - UMA_HISTOGRAM_ENUMERATION( - "JSDialogs.OnBeforeUnloadStayVsLeave", - static_cast<int>(success ? StayVsLeave::LEAVE : StayVsLeave::STAY), - static_cast<int>(StayVsLeave::MAX)); - - OnDialogClosed(web_contents, std::move(callback), success, user_input); -} - void AppModalDialogManager::OnDialogClosed(content::WebContents* web_contents, DialogClosedCallback callback, bool success,
diff --git a/components/javascript_dialogs/app_modal_dialog_manager.h b/components/javascript_dialogs/app_modal_dialog_manager.h index 97bb6b5..b21870d 100644 --- a/components/javascript_dialogs/app_modal_dialog_manager.h +++ b/components/javascript_dialogs/app_modal_dialog_manager.h
@@ -77,12 +77,6 @@ AppModalDialogManager(); ~AppModalDialogManager() override; - // Wrapper around OnDialogClosed; logs UMA stats before continuing on. - void OnBeforeUnloadDialogClosed(content::WebContents* web_contents, - DialogClosedCallback callback, - bool success, - const base::string16& user_input); - // Wrapper around a DialogClosedCallback so that we can intercept it before // passing it onto the original callback. void OnDialogClosed(content::WebContents* web_contents,
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerMediator.java b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerMediator.java index 37431d93..278f528 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerMediator.java +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerMediator.java
@@ -113,7 +113,7 @@ // TODO(sinansahin): See if we need special handling for #onFling. @Override - public void onSwipeFinished(MotionEvent end) { + public void onSwipeFinished() { cancelAnyAnimations(); // No need to animate if the message banner is in resting position.
diff --git a/components/safe_browsing/core/features.cc b/components/safe_browsing/core/features.cc index 6bd1a1b..af8dd69 100644 --- a/components/safe_browsing/core/features.cc +++ b/components/safe_browsing/core/features.cc
@@ -97,10 +97,6 @@ #endif }; -const base::Feature kRealTimeUrlLookupEnabledForAllAndroidDevices{ - "SafeBrowsingRealTimeUrlLookupEnabledForAllAndroidDevices", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kRealTimeUrlLookupEnabledForEnterprise{ "SafeBrowsingRealTimeUrlLookupEnabledForEnterprise", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -174,7 +170,6 @@ {&kPasswordProtectionForSignedInUsers, true}, {&kPromptAppForDeepScanning, true}, {&kRealTimeUrlLookupEnabled, true}, - {&kRealTimeUrlLookupEnabledForAllAndroidDevices, true}, {&kRealTimeUrlLookupEnabledForEP, true}, {&kRealTimeUrlLookupEnabledForEnterprise, true}, {&kRealTimeUrlLookupEnabledForEPWithToken, true},
diff --git a/components/safe_browsing/core/features.h b/components/safe_browsing/core/features.h index 79df1359..7655c04a 100644 --- a/components/safe_browsing/core/features.h +++ b/components/safe_browsing/core/features.h
@@ -83,10 +83,6 @@ // Controls whether the real time URL lookup is enabled. extern const base::Feature kRealTimeUrlLookupEnabled; -// Controls whether the real time URL lookup is enabled for all Android devices. -// This flag is in effect only if |kRealTimeUrlLookupEnabled| is true. -extern const base::Feature kRealTimeUrlLookupEnabledForAllAndroidDevices; - // Controls whether to do real time URL lookup for enterprise users. If both // this feature and the enterprise policies are enabled, the enterprise real // time URL lookup will be enabled and the consumer real time URL lookup will be
diff --git a/components/safe_browsing/core/realtime/policy_engine.cc b/components/safe_browsing/core/realtime/policy_engine.cc index ed86fc1..b8c66837 100644 --- a/components/safe_browsing/core/realtime/policy_engine.cc +++ b/components/safe_browsing/core/realtime/policy_engine.cc
@@ -30,10 +30,6 @@ namespace safe_browsing { -#if defined(OS_ANDROID) -const int kDefaultMemoryThresholdMb = 4096; -#endif - // static bool RealTimePolicyEngine::IsInExcludedCountry( const std::string& country_code) { @@ -42,24 +38,7 @@ // static bool RealTimePolicyEngine::IsUrlLookupEnabled() { - if (!base::FeatureList::IsEnabled(kRealTimeUrlLookupEnabled)) - return false; -#if defined(OS_ANDROID) - // On Android, performs real time URL lookup only if - // |kRealTimeUrlLookupEnabled| is enabled, and system memory is larger than - // threshold, or the feature flag - // |kRealTimeUrlLookupEnabledForAllAndroidDevices| is enabled. - int memory_threshold_mb = base::GetFieldTrialParamByFeatureAsInt( - kRealTimeUrlLookupEnabled, kRealTimeUrlLookupMemoryThresholdMb, - kDefaultMemoryThresholdMb); - bool is_high_end_device = - base::SysInfo::AmountOfPhysicalMemoryMB() >= memory_threshold_mb; - return is_high_end_device || - base::FeatureList::IsEnabled( - kRealTimeUrlLookupEnabledForAllAndroidDevices); -#else - return true; -#endif + return base::FeatureList::IsEnabled(kRealTimeUrlLookupEnabled); } // static
diff --git a/components/safe_browsing/core/realtime/policy_engine.h b/components/safe_browsing/core/realtime/policy_engine.h index 148bcd9..c2338a4 100644 --- a/components/safe_browsing/core/realtime/policy_engine.h +++ b/components/safe_browsing/core/realtime/policy_engine.h
@@ -27,14 +27,6 @@ enum class ResourceType; -#if defined(OS_ANDROID) -// A parameter controlled by finch experiment. -// On Android, performs real time URL lookup only if |kRealTimeUrlLookupEnabled| -// is enabled, and system memory is larger than threshold. -const char kRealTimeUrlLookupMemoryThresholdMb[] = - "SafeBrowsingRealTimeUrlLookupMemoryThresholdMb"; -#endif - // This class implements the logic to decide whether the real time lookup // feature is enabled for a given user/profile. // TODO(crbug.com/1050859): To make this class build in IOS, remove
diff --git a/components/safe_browsing/core/realtime/policy_engine_unittest.cc b/components/safe_browsing/core/realtime/policy_engine_unittest.cc index c8751ea..f8bfc78 100644 --- a/components/safe_browsing/core/realtime/policy_engine_unittest.cc +++ b/components/safe_browsing/core/realtime/policy_engine_unittest.cc
@@ -18,11 +18,6 @@ #include "components/user_prefs/user_prefs.h" #include "testing/platform_test.h" -#if defined(OS_ANDROID) -#include "base/strings/string_number_conversions.h" -#include "base/system/sys_info.h" -#endif - namespace safe_browsing { class RealTimePolicyEngineTest : public PlatformTest { @@ -67,84 +62,6 @@ sync_preferences::TestingPrefServiceSyncable pref_service_; }; -#if defined(OS_ANDROID) -// Real time URL check on Android is controlled by system memory size, the -// following tests test that logic. -TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_LargeMemorySize) { - base::test::ScopedFeatureList feature_list; - int system_memory_size = base::SysInfo::AmountOfPhysicalMemoryMB(); - int memory_size_threshold = system_memory_size - 1; - feature_list.InitWithFeaturesAndParameters( - /* enabled_features */ {{kRealTimeUrlLookupEnabled, - {{kRealTimeUrlLookupMemoryThresholdMb, - base::NumberToString( - memory_size_threshold)}}}}, - /* disabled_features */ {}); - pref_service_.SetUserPref( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, - std::make_unique<base::Value>(true)); - EXPECT_TRUE(CanPerformFullURLLookup(/* is_off_the_record */ false)); -} - -TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_SmallMemorySize) { - base::test::ScopedFeatureList feature_list; - int system_memory_size = base::SysInfo::AmountOfPhysicalMemoryMB(); - int memory_size_threshold = system_memory_size + 1; - feature_list.InitWithFeaturesAndParameters( - /* enabled_features */ {{kRealTimeUrlLookupEnabled, - {{kRealTimeUrlLookupMemoryThresholdMb, - base::NumberToString( - memory_size_threshold)}}}}, - /* disabled_features */ {kRealTimeUrlLookupEnabledForAllAndroidDevices}); - pref_service_.SetUserPref( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, - std::make_unique<base::Value>(true)); - EXPECT_FALSE(CanPerformFullURLLookup(/* is_off_the_record */ false)); -} - -TEST_F(RealTimePolicyEngineTest, - TestCanPerformFullURLLookup_SmallMemorySizeWithAllDevicesFlagEnabled) { - base::test::ScopedFeatureList feature_list; - int system_memory_size = base::SysInfo::AmountOfPhysicalMemoryMB(); - int memory_size_threshold = system_memory_size + 1; - feature_list.InitWithFeaturesAndParameters( - /* enabled_features */ {{kRealTimeUrlLookupEnabled, - {{kRealTimeUrlLookupMemoryThresholdMb, - base::NumberToString(memory_size_threshold)}}}, - {kRealTimeUrlLookupEnabledForAllAndroidDevices, - {}}}, - /* disabled_features */ {}); - pref_service_.SetUserPref( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, - std::make_unique<base::Value>(true)); - EXPECT_TRUE(CanPerformFullURLLookup(/* is_off_the_record */ false)); -} - -TEST_F(RealTimePolicyEngineTest, - TestCanPerformFullURLLookup_DisabledUrlLookupWithLargeMemorySize) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeaturesAndParameters( - /* enabled_features */ {}, - /* disabled_features */ {kRealTimeUrlLookupEnabled}); - EXPECT_FALSE(CanPerformFullURLLookup(/* is_off_the_record */ false)); -} - -TEST_F(RealTimePolicyEngineTest, - TestCanPerformFullURLLookup_DisabledUrlLookupWithAllDevicesFlagEnabled) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeaturesAndParameters( - /* enabled_features */ {{kRealTimeUrlLookupEnabledForAllAndroidDevices, - {}}}, - /* disabled_features */ {kRealTimeUrlLookupEnabled}); - pref_service_.SetUserPref( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, - std::make_unique<base::Value>(true)); - // |kRealTimeUrlLookupEnabledForAllAndroidDevices| is in effect only if - // |kRealTimeUrlLookupEnabled| is set to true. - EXPECT_FALSE(CanPerformFullURLLookup(/* is_off_the_record */ false)); -} -#endif // defined(OS_ANDROID) - TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_DisabledUrlLookup) { base::test::ScopedFeatureList feature_list; @@ -234,21 +151,10 @@ TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_NonEpUsersEnabledWhenRTLookupForEpDisabled) { base::test::ScopedFeatureList feature_list; -#if defined(OS_ANDROID) - int system_memory_size = base::SysInfo::AmountOfPhysicalMemoryMB(); - int memory_size_threshold = system_memory_size - 1; - feature_list.InitWithFeaturesAndParameters( - /* enabled_features */ {{kRealTimeUrlLookupEnabled, - {{kRealTimeUrlLookupMemoryThresholdMb, - base::NumberToString(memory_size_threshold)}}}, - {kRealTimeUrlLookupEnabledWithToken, {}}}, - /* disabled_features */ {kRealTimeUrlLookupEnabledForEP}); -#else feature_list.InitWithFeatures( /* enabled_features */ {kRealTimeUrlLookupEnabled, kRealTimeUrlLookupEnabledWithToken}, /* disabled_features */ {kRealTimeUrlLookupEnabledForEP}); -#endif pref_service_.SetUserPref( unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, std::make_unique<base::Value>(true)); @@ -260,21 +166,10 @@ TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookupWithToken_SyncControlled) { base::test::ScopedFeatureList feature_list; -#if defined(OS_ANDROID) - int system_memory_size = base::SysInfo::AmountOfPhysicalMemoryMB(); - int memory_size_threshold = system_memory_size - 1; - feature_list.InitWithFeaturesAndParameters( - /* enabled_features */ {{kRealTimeUrlLookupEnabled, - {{kRealTimeUrlLookupMemoryThresholdMb, - base::NumberToString(memory_size_threshold)}}}, - {kRealTimeUrlLookupEnabledWithToken, {}}}, - /* disabled_features */ {}); -#else feature_list.InitWithFeatures( /* enabled_features */ {kRealTimeUrlLookupEnabled, kRealTimeUrlLookupEnabledWithToken}, /* disabled_features */ {}); -#endif pref_service_.SetUserPref( unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, std::make_unique<base::Value>(true));
diff --git a/components/safe_browsing/core/realtime/url_lookup_service_unittest.cc b/components/safe_browsing/core/realtime/url_lookup_service_unittest.cc index 14e40ee..b7f663f1 100644 --- a/components/safe_browsing/core/realtime/url_lookup_service_unittest.cc +++ b/components/safe_browsing/core/realtime/url_lookup_service_unittest.cc
@@ -24,12 +24,6 @@ #include "services/network/test/test_url_loader_factory.h" #include "testing/platform_test.h" -#if defined(OS_ANDROID) -#include "base/strings/string_number_conversions.h" -#include "base/system/sys_info.h" -#include "components/safe_browsing/core/realtime/policy_engine.h" -#endif - using ::testing::_; namespace safe_browsing { @@ -137,31 +131,6 @@ test_pref_service_.SetUserPref( unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, std::make_unique<base::Value>(true)); -#if defined(OS_ANDROID) - int system_memory_size = base::SysInfo::AmountOfPhysicalMemoryMB(); - int memory_size_threshold = system_memory_size - 1; - if (is_with_token_enabled) { - feature_list_.InitWithFeaturesAndParameters( - /* enabled_features */ {{kRealTimeUrlLookupEnabled, - { { - kRealTimeUrlLookupMemoryThresholdMb, - base::NumberToString(memory_size_threshold) - } }}, - { kRealTimeUrlLookupEnabledWithToken, - {} }}, - /* disabled_features */ {}); - } else { - feature_list_.InitWithFeaturesAndParameters( - /* enabled_features */ {{ - kRealTimeUrlLookupEnabled, - { - { kRealTimeUrlLookupMemoryThresholdMb, - base::NumberToString(memory_size_threshold) } - } - }}, - /* disabled_features */ {}); - } -#else if (is_with_token_enabled) { feature_list_.InitWithFeatures( {kRealTimeUrlLookupEnabled, kRealTimeUrlLookupEnabledWithToken}, {}); @@ -169,7 +138,6 @@ feature_list_.InitWithFeatures({kRealTimeUrlLookupEnabled}, {kRealTimeUrlLookupEnabledWithToken}); } -#endif } void SetupPrimaryAccount() {
diff --git a/components/search/ntp_features.cc b/components/search/ntp_features.cc index 9ce4a41..8cb42f4 100644 --- a/components/search/ntp_features.cc +++ b/components/search/ntp_features.cc
@@ -23,7 +23,7 @@ // If enabled, the OneGooleBar is loaded in an iframe. Otherwise, it is inlined. const base::Feature kIframeOneGoogleBar{"IframeOneGoogleBar", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; // If enabled, queries that are frequently repeated by the user (and are // expected to be issued again) are shown as most visited tiles.
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 8e1f0976..7ef94f0f 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -690,147 +690,150 @@ TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize"); #endif // !OS_ANDROID - // If we are on a platform where the default allocator is overridden (shim - // layer on windows, tcmalloc on Linux Desktop) smoke-tests that the - // overriding logic is working correctly. If not causes a hard crash, as its - // unexpected absence has security implications. - CHECK(base::allocator::IsAllocatorInitialized()); - -#if defined(OS_POSIX) || defined(OS_FUCHSIA) - if (!process_type.empty()) { - // When you hit Ctrl-C in a terminal running the browser - // process, a SIGINT is delivered to the entire process group. - // When debugging the browser process via gdb, gdb catches the - // SIGINT for the browser process (and dumps you back to the gdb - // console) but doesn't for the child processes, killing them. - // The fix is to have child processes ignore SIGINT; they'll die - // on their own when the browser process goes away. - // - // Note that we *can't* rely on BeingDebugged to catch this case because - // we are the child process, which is not being debugged. - // TODO(evanm): move this to some shared subprocess-init function. - if (!base::debug::BeingDebugged()) - signal(SIGINT, SIG_IGN); - } + // If we are on a platform where the default allocator is overridden (shim + // layer on windows, tcmalloc on Linux Desktop) smoke-tests that the + // overriding logic is working correctly. If not causes a hard crash, as its + // unexpected absence has security implications. + CHECK(base::allocator::IsAllocatorInitialized()); +#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + base::allocator::EnablePartitionAllocMemoryReclaimer(); #endif - RegisterPathProvider(); +#if defined(OS_POSIX) || defined(OS_FUCHSIA) + if (!process_type.empty()) { + // When you hit Ctrl-C in a terminal running the browser + // process, a SIGINT is delivered to the entire process group. + // When debugging the browser process via gdb, gdb catches the + // SIGINT for the browser process (and dumps you back to the gdb + // console) but doesn't for the child processes, killing them. + // The fix is to have child processes ignore SIGINT; they'll die + // on their own when the browser process goes away. + // + // Note that we *can't* rely on BeingDebugged to catch this case because + // we are the child process, which is not being debugged. + // TODO(evanm): move this to some shared subprocess-init function. + if (!base::debug::BeingDebugged()) + signal(SIGINT, SIG_IGN); + } +#endif + + RegisterPathProvider(); #if defined(OS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) - // On Android, we have two ICU data files. A main one with most languages - // that is expected to always be available and an extra one that is - // installed separately via a dynamic feature module. If the extra ICU data - // file is available we have to apply it _before_ the main ICU data file. - // Otherwise, the languages of the extra ICU file will be overridden. - if (process_type.empty()) { - TRACE_EVENT0("startup", "InitializeICU"); - // In browser process load ICU data files from disk. - std::string split_name; - if (GetContentClient()->browser()->ShouldLoadExtraIcuDataFile( - &split_name)) { - if (!base::i18n::InitializeExtraICU(split_name)) { - return TerminateForFatalInitializationError(); - } - } - if (!base::i18n::InitializeICU()) { - return TerminateForFatalInitializationError(); - } - } else { - // In child process map ICU data files loaded by browser process. - int icu_extra_data_fd = g_fds->MaybeGet(kAndroidICUExtraDataDescriptor); - if (icu_extra_data_fd != -1) { - auto icu_extra_data_region = - g_fds->GetRegion(kAndroidICUExtraDataDescriptor); - if (!base::i18n::InitializeExtraICUWithFileDescriptor( - icu_extra_data_fd, icu_extra_data_region)) { - return TerminateForFatalInitializationError(); - } - } - int icu_data_fd = g_fds->MaybeGet(kAndroidICUDataDescriptor); - if (icu_data_fd == -1) { - return TerminateForFatalInitializationError(); - } - auto icu_data_region = g_fds->GetRegion(kAndroidICUDataDescriptor); - if (!base::i18n::InitializeICUWithFileDescriptor(icu_data_fd, - icu_data_region)) { + // On Android, we have two ICU data files. A main one with most languages + // that is expected to always be available and an extra one that is + // installed separately via a dynamic feature module. If the extra ICU data + // file is available we have to apply it _before_ the main ICU data file. + // Otherwise, the languages of the extra ICU file will be overridden. + if (process_type.empty()) { + TRACE_EVENT0("startup", "InitializeICU"); + // In browser process load ICU data files from disk. + std::string split_name; + if (GetContentClient()->browser()->ShouldLoadExtraIcuDataFile( + &split_name)) { + if (!base::i18n::InitializeExtraICU(split_name)) { return TerminateForFatalInitializationError(); } } -#else - if (!base::i18n::InitializeICU()) + if (!base::i18n::InitializeICU()) { return TerminateForFatalInitializationError(); + } + } else { + // In child process map ICU data files loaded by browser process. + int icu_extra_data_fd = g_fds->MaybeGet(kAndroidICUExtraDataDescriptor); + if (icu_extra_data_fd != -1) { + auto icu_extra_data_region = + g_fds->GetRegion(kAndroidICUExtraDataDescriptor); + if (!base::i18n::InitializeExtraICUWithFileDescriptor( + icu_extra_data_fd, icu_extra_data_region)) { + return TerminateForFatalInitializationError(); + } + } + int icu_data_fd = g_fds->MaybeGet(kAndroidICUDataDescriptor); + if (icu_data_fd == -1) { + return TerminateForFatalInitializationError(); + } + auto icu_data_region = g_fds->GetRegion(kAndroidICUDataDescriptor); + if (!base::i18n::InitializeICUWithFileDescriptor(icu_data_fd, + icu_data_region)) { + return TerminateForFatalInitializationError(); + } + } +#else + if (!base::i18n::InitializeICU()) + return TerminateForFatalInitializationError(); #endif // OS_ANDROID && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) - InitializeV8IfNeeded(command_line, process_type); + InitializeV8IfNeeded(command_line, process_type); - blink::TrialTokenValidator::SetOriginTrialPolicyGetter( - base::BindRepeating([]() -> blink::OriginTrialPolicy* { - if (auto* client = GetContentClient()) - return client->GetOriginTrialPolicy(); - return nullptr; - })); + blink::TrialTokenValidator::SetOriginTrialPolicyGetter( + base::BindRepeating([]() -> blink::OriginTrialPolicy* { + if (auto* client = GetContentClient()) + return client->GetOriginTrialPolicy(); + return nullptr; + })); #if !defined(OFFICIAL_BUILD) #if defined(OS_WIN) - bool should_enable_stack_dump = !process_type.empty(); + bool should_enable_stack_dump = !process_type.empty(); #else - bool should_enable_stack_dump = true; + bool should_enable_stack_dump = true; #endif - // Print stack traces to stderr when crashes occur. This opens up security - // holes so it should never be enabled for official builds. This needs to - // happen before crash reporting is initialized (which for chrome happens in - // the call to PreSandboxStartup() on the delegate below), because otherwise - // this would interfere with signal handlers used by crash reporting. - if (should_enable_stack_dump && - !command_line.HasSwitch(switches::kDisableInProcessStackTraces)) { - base::debug::EnableInProcessStackDumping(); - } + // Print stack traces to stderr when crashes occur. This opens up security + // holes so it should never be enabled for official builds. This needs to + // happen before crash reporting is initialized (which for chrome happens in + // the call to PreSandboxStartup() on the delegate below), because otherwise + // this would interfere with signal handlers used by crash reporting. + if (should_enable_stack_dump && + !command_line.HasSwitch(switches::kDisableInProcessStackTraces)) { + base::debug::EnableInProcessStackDumping(); + } - base::debug::VerifyDebugger(); + base::debug::VerifyDebugger(); #endif // !defined(OFFICIAL_BUILD) - delegate_->PreSandboxStartup(); + delegate_->PreSandboxStartup(); #if defined(OS_WIN) - if (!InitializeSandbox( - sandbox::policy::SandboxTypeFromCommandLine(command_line), - params.sandbox_info)) - return TerminateForFatalInitializationError(); + if (!InitializeSandbox( + sandbox::policy::SandboxTypeFromCommandLine(command_line), + params.sandbox_info)) + return TerminateForFatalInitializationError(); #elif defined(OS_MAC) - // Only the GPU process still runs the V1 sandbox. - bool v2_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch( - sandbox::switches::kSeatbeltClientName); + // Only the GPU process still runs the V1 sandbox. + bool v2_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch( + sandbox::switches::kSeatbeltClientName); - if (!v2_enabled && process_type == switches::kGpuProcess) { - if (!InitializeSandbox()) { - return TerminateForFatalInitializationError(); - } - } else if (v2_enabled) { - CHECK(sandbox::Seatbelt::IsSandboxed()); + if (!v2_enabled && process_type == switches::kGpuProcess) { + if (!InitializeSandbox()) { + return TerminateForFatalInitializationError(); } + } else if (v2_enabled) { + CHECK(sandbox::Seatbelt::IsSandboxed()); + } #endif - delegate_->SandboxInitialized(process_type); + delegate_->SandboxInitialized(process_type); #if BUILDFLAG(USE_ZYGOTE_HANDLE) - if (process_type.empty()) { - // The sandbox host needs to be initialized before forking a thread to - // start the ServiceManager, and after setting up the sandbox and invoking - // SandboxInitialized(). - InitializeZygoteSandboxForBrowserProcess( - *base::CommandLine::ForCurrentProcess()); + if (process_type.empty()) { + // The sandbox host needs to be initialized before forking a thread to + // start the ServiceManager, and after setting up the sandbox and invoking + // SandboxInitialized(). + InitializeZygoteSandboxForBrowserProcess( + *base::CommandLine::ForCurrentProcess()); - // We can only enable startup tracing after - // InitializeZygoteSandboxForBrowserProcess(), because the latter may fork - // and run code that calls trace event macros in the forked process (which - // could cause all sorts of issues, like writing to the same tracing SMB - // from two processes). - tracing::EnableStartupTracingIfNeeded(); - } + // We can only enable startup tracing after + // InitializeZygoteSandboxForBrowserProcess(), because the latter may fork + // and run code that calls trace event macros in the forked process (which + // could cause all sorts of issues, like writing to the same tracing SMB + // from two processes). + tracing::EnableStartupTracingIfNeeded(); + } #endif // BUILDFLAG(USE_ZYGOTE_HANDLE) - // Return -1 to indicate no early termination. - return -1; + // Return -1 to indicate no early termination. + return -1; } int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
diff --git a/content/browser/browsing_instance.cc b/content/browser/browsing_instance.cc index 0061b20..2fdd2b3f3 100644 --- a/content/browser/browsing_instance.cc +++ b/content/browser/browsing_instance.cc
@@ -54,15 +54,6 @@ default_process_->AddObserver(this); } -bool BrowsingInstance::IsDefaultSiteInstance( - const SiteInstanceImpl* site_instance) const { - return site_instance != nullptr && site_instance == default_site_instance_; -} - -bool BrowsingInstance::IsSiteInDefaultSiteInstance(const GURL& site_url) const { - return site_url_set_.find(site_url) != site_url_set_.end(); -} - bool BrowsingInstance::HasSiteInstance(const SiteInfo& site_info) { return site_instance_map_.find(site_info) != site_instance_map_.end(); } @@ -97,25 +88,6 @@ return ComputeSiteInfoForURL(url_info); } -bool BrowsingInstance::TrySettingDefaultSiteInstance( - SiteInstanceImpl* site_instance, - const UrlInfo& url_info) { - DCHECK(!site_instance->HasSite()); - const SiteInfo site_info = ComputeSiteInfoForURL(url_info); - if (default_site_instance_ || - !SiteInstanceImpl::CanBePlacedInDefaultSiteInstance( - isolation_context_, url_info.url, site_info)) { - return false; - } - - // Note: |default_site_instance_| must be set before SetSite() call to - // properly trigger default SiteInstance behavior inside that method. - default_site_instance_ = site_instance; - site_instance->SetSiteInfoToDefault(); - site_url_set_.insert(site_info.site_url()); - return true; -} - scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURLHelper( const UrlInfo& url_info, bool allow_default_instance) { @@ -134,21 +106,15 @@ if (!site_instance) { site_instance = new SiteInstanceImpl(this); - // Keep a copy of the pointer so it can be used for other URLs. This is - // safe because the SiteInstanceImpl destructor will call - // UnregisterSiteInstance() to clear this copy when the last - // reference to |site_instance| is destroyed. - // Note: This assignment MUST happen before the SetSite() call to ensure - // this instance is not added to |site_instance_map_| when SetSite() - // calls RegisterSiteInstance(). - default_site_instance_ = site_instance.get(); - + // Note: |default_site_instance_| will get set inside this call + // via RegisterSiteInstance(). site_instance->SetSiteInfoToDefault(); + DCHECK_EQ(default_site_instance_, site_instance.get()); } - // Add |site_url| to the set so we can keep track of all the sites the + // Add |site_info| to the set so we can keep track of all the sites the // the default SiteInstance has been returned for. - site_url_set_.insert(site_info.site_url()); + site_instance->AddSiteInfoToDefault(site_info); return site_instance; } @@ -159,10 +125,13 @@ DCHECK(site_instance->browsing_instance_.get() == this); DCHECK(site_instance->HasSite()); - // Explicitly prevent the |default_site_instance_| from being added since + // Explicitly prevent the default SiteInstance from being added since // the map is only supposed to contain instances that map to a single site. - if (site_instance == default_site_instance_) + if (site_instance->IsDefaultSiteInstance()) { + CHECK(!default_site_instance_); + default_site_instance_ = site_instance; return; + } const SiteInfo& site_info = site_instance->GetSiteInfo();
diff --git a/content/browser/browsing_instance.h b/content/browser/browsing_instance.h index 8e22428d..65e627f2fa 100644 --- a/content/browser/browsing_instance.h +++ b/content/browser/browsing_instance.h
@@ -172,25 +172,9 @@ void SetDefaultProcess(RenderProcessHost* default_process); RenderProcessHost* default_process() const { return default_process_; } - bool IsDefaultSiteInstance(const SiteInstanceImpl* site_instance) const; - - // Returns true if |site_url| has been used to get a SiteInstance from this - // object and the default SiteInstance was returned. This simply indicates - // the site may be directed to the default SiteInstance process, but it does - // not indicate that the site has already been committed to that process. - // Returns false if no request for |site_url| has resulted in this object - // returning the default SiteInstance. - // TODO(wjmaclean): Update this function to use SiteInfo instead. - // https://crbug.com/1085275 - bool IsSiteInDefaultSiteInstance(const GURL& site_url) const; - - // Attempts to convert |site_instance| into a default SiteInstance, - // if |url_info| can be placed inside a default SiteInstance, and the default - // SiteInstance has not already been set for this object. - // Returns true if |site_instance| was successfully converted to a default - // SiteInstance. Otherwise, returns false. - bool TrySettingDefaultSiteInstance(SiteInstanceImpl* site_instance, - const UrlInfo& url_info); + bool HasDefaultSiteInstance() const { + return default_site_instance_ != nullptr; + } // Helper function used by other methods in this class to ensure consistent // mapping between |url_info| and SiteInfo. This method will never return a @@ -248,11 +232,6 @@ // BrowsingInstance and the SiteInstanceImpl. SiteInstanceImpl* default_site_instance_; - // Keeps track of the site URLs that this object mapped to the - // |default_site_instance_|. - // TODO(wjmaclean): Revise this to store SiteInfos instead of GURLs. - std::set<GURL> site_url_set_; - // The cross-origin isolation status of the BrowsingInstance. This indicates // whether this BrowsingInstance is hosting only cross-origin isolated pages // and if so, from which top level origin.
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index b4dacc22..e19c2e67 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -282,6 +282,7 @@ switches::kOzonePlatform, switches::kDisableExplicitDmaFences, switches::kOzoneDumpFile, + switches::kDisableBufferBWCompression, #endif #if defined(USE_X11) switches::kX11Display,
diff --git a/content/browser/loader/prefetch_url_loader_service.cc b/content/browser/loader/prefetch_url_loader_service.cc index 9ceb661e..b3d7b76f 100644 --- a/content/browser/loader/prefetch_url_loader_service.cc +++ b/content/browser/loader/prefetch_url_loader_service.cc
@@ -5,6 +5,7 @@ #include "content/browser/loader/prefetch_url_loader_service.h" #include "base/bind.h" +#include "base/debug/dump_without_crashing.h" #include "base/feature_list.h" #include "base/time/default_tick_clock.h" #include "content/browser/loader/prefetch_url_loader.h" @@ -28,6 +29,14 @@ #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" +namespace { +void DumpWithoutCrashing(const network::ResourceRequest& request) { + DEBUG_ALIAS_FOR_GURL(prefetch_buf, request.url); + DEBUG_ALIAS_FOR_GURL(initiator_buf, request.request_initiator->GetURL()); + base::debug::DumpWithoutCrashing(); +} +} // namespace + namespace content { struct PrefetchURLLoaderService::BindContext { @@ -162,9 +171,18 @@ // Recursive prefetch from a cross-origin main resource prefetch. if (resource_request.recursive_prefetch_token) { - // TODO(crbug.com/1123715): Figure out why we're seeing this condition hold - // true in the field. + // A request's |recursive_prefetch_token| is only provided if the request is + // a recursive prefetch. This means it is expected that the current + // context's |cross_origin_factory| was already created. if (!current_context.cross_origin_factory) { + // This could happen due to a compromised renderer passing in a recursive + // prefetch token for a request that's not a recursive prefetch. Cancel + // the request. + DVLOG(1) << "Recursive prefetch token unexpectedly set."; + DumpWithoutCrashing(resource_request); + mojo::Remote<network::mojom::URLLoaderClient>(std::move(client)) + ->OnComplete( + network::URLLoaderCompletionStatus(net::ERR_INVALID_ARGUMENT)); return; } @@ -178,6 +196,8 @@ // a request in a special way. We'll cancel the request. if (isolation_info_iterator == current_context.prefetch_isolation_infos.end()) { + DVLOG(1) << "Recursive prefetch request is missing prefetch isolation"; + DumpWithoutCrashing(resource_request); mojo::Remote<network::mojom::URLLoaderClient>(std::move(client)) ->OnComplete( network::URLLoaderCompletionStatus(net::ERR_INVALID_ARGUMENT));
diff --git a/content/browser/renderer_host/render_frame_message_filter_browsertest.cc b/content/browser/renderer_host/cookie_browsertest.cc similarity index 96% rename from content/browser/renderer_host/render_frame_message_filter_browsertest.cc rename to content/browser/renderer_host/cookie_browsertest.cc index 117f0e0d..f80f027 100644 --- a/content/browser/renderer_host/render_frame_message_filter_browsertest.cc +++ b/content/browser/renderer_host/cookie_browsertest.cc
@@ -106,10 +106,7 @@ } // namespace -// TODO(crbug.com/965982): document.cookie is now handled by the -// RestrictedCookieManager, not the RenderFrameMessageFilter, so these cookie -// tests should be moved accordingly. -class RenderFrameMessageFilterBrowserTest : public ContentBrowserTest { +class CookieBrowserTest : public ContentBrowserTest { protected: void SetUp() override { base::CommandLine::ForCurrentProcess()->AppendSwitch( @@ -132,7 +129,7 @@ // Exercises basic cookie operations via javascript, including an http page // interacting with secure cookies. -IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, Cookies) { +IN_PROC_BROWSER_TEST_F(CookieBrowserTest, Cookies) { SetupCrossSiteRedirector(embedded_test_server()); ASSERT_TRUE(embedded_test_server()->Start()); @@ -206,7 +203,7 @@ } // Ensure "priority" cookie option is settable via document.cookie. -IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, CookiePriority) { +IN_PROC_BROWSER_TEST_F(CookieBrowserTest, CookiePriority) { ASSERT_TRUE(embedded_test_server()->Start()); struct { @@ -233,7 +230,7 @@ // SameSite cookies (that aren't marked as http-only) should be available to // JavaScript. -IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, SameSiteCookies) { +IN_PROC_BROWSER_TEST_F(CookieBrowserTest, SameSiteCookies) { // Must use HTTPS because SameSite=None cookies must be Secure. net::EmbeddedTestServer server(net::EmbeddedTestServer::TYPE_HTTPS); server.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES); @@ -374,8 +371,7 @@ // for wrong URLs are rejected. // TODO(https://crbug.com/954603): This should actually result in renderer // kills. -IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, - CrossSiteCookieSecurityEnforcement) { +IN_PROC_BROWSER_TEST_F(CookieBrowserTest, CrossSiteCookieSecurityEnforcement) { // The code under test is only active under site isolation. if (!AreAllSitesIsolatedForTesting()) { return;
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 19f90228..dd1340d 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1846,6 +1846,23 @@ blink_frame_widget_->ShowContextMenu(source_type, point); } +void RenderWidgetHostImpl::InsertVisualStateCallback( + VisualStateCallback callback) { + if (!blink_frame_widget_) { + std::move(callback).Run(false); + return; + } + + if (!widget_compositor_) { + blink_frame_widget_->BindWidgetCompositor( + widget_compositor_.BindNewPipeAndPassReceiver()); + } + + widget_compositor_->VisualStateRequest(base::BindOnce( + [](VisualStateCallback callback) { std::move(callback).Run(true); }, + mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), false))); +} + RenderProcessHost::Priority RenderWidgetHostImpl::GetPriority() { RenderProcessHost::Priority priority = { is_hidden_, @@ -2844,23 +2861,6 @@ return false; } -void RenderWidgetHostImpl::InsertVisualStateCallback( - VisualStateCallback callback) { - if (!blink_frame_widget_) { - std::move(callback).Run(false); - return; - } - - if (!widget_compositor_) { - blink_frame_widget_->BindWidgetCompositor( - widget_compositor_.BindNewPipeAndPassReceiver()); - } - - widget_compositor_->VisualStateRequest(base::BindOnce( - [](VisualStateCallback callback) { std::move(callback).Run(true); }, - mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), false))); -} - const mojo::AssociatedRemote<blink::mojom::FrameWidget>& RenderWidgetHostImpl::GetAssociatedFrameWidget() { return blink_frame_widget_;
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index aef17031..fba8cc5 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -258,6 +258,7 @@ void SetCursor(const ui::Cursor& cursor) override; void ShowContextMenuAtPoint(const gfx::Point& point, const ui::MenuSourceType source_type) override; + void InsertVisualStateCallback(VisualStateCallback callback) override; // RenderProcessHostImpl::PriorityClient implementation. RenderProcessHost::Priority GetPriority() override; @@ -778,14 +779,6 @@ // Add/ClearPendingUserActivation() for details. bool RemovePendingUserActivationIfAvailable(); - // Roundtrips through the renderer and compositor pipeline to ensure that any - // changes to the contents resulting from operations executed prior to this - // call are visible on screen. The call completes asynchronously by running - // the supplied |callback| with a value of true upon successful completion and - // false otherwise when the widget is destroyed. - using VisualStateCallback = base::OnceCallback<void(bool)>; - void InsertVisualStateCallback(VisualStateCallback callback); - const mojo::AssociatedRemote<blink::mojom::FrameWidget>& GetAssociatedFrameWidget();
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index 814cc90e..f98b7b8 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc
@@ -263,6 +263,23 @@ site_url_); } +class SiteInstanceImpl::DefaultSiteInstanceState { + public: + void AddSiteInfo(const SiteInfo& site_info) { + default_site_url_set_.insert(site_info.site_url()); + } + + bool ContainsSite(const GURL& site_url) { + return base::Contains(default_site_url_set_, site_url); + } + + private: + // Keeps track of the site URLs that have been mapped to the default + // SiteInstance. + // TODO(wjmaclean): Revise this to store SiteInfos instead of GURLs. + std::set<GURL> default_site_url_set_; +}; + SiteInstanceImpl::SiteInstanceImpl(BrowsingInstance* browsing_instance) : id_(next_site_instance_id_++), active_frame_count_(0), @@ -432,11 +449,17 @@ } bool SiteInstanceImpl::IsDefaultSiteInstance() const { - return browsing_instance_->IsDefaultSiteInstance(this); + return default_site_instance_state_ != nullptr; +} + +void SiteInstanceImpl::AddSiteInfoToDefault(const SiteInfo& site_info) { + DCHECK(IsDefaultSiteInstance()); + default_site_instance_state_->AddSiteInfo(site_info); } bool SiteInstanceImpl::IsSiteInDefaultSiteInstance(const GURL& site_url) const { - return browsing_instance_->IsSiteInDefaultSiteInstance(site_url); + DCHECK(IsDefaultSiteInstance()); + return default_site_instance_state_->ContainsSite(site_url); } void SiteInstanceImpl::MaybeSetBrowsingInstanceDefaultProcess() { @@ -609,6 +632,7 @@ TRACE_EVENT1("navigation", "SiteInstanceImpl::SetSiteInfoToDefault", "site id", id_); DCHECK(!has_site_); + default_site_instance_state_ = std::make_unique<DefaultSiteInstanceState>(); original_url_ = GetDefaultSiteURL(); SetSiteInfoInternal(SiteInfo::CreateForDefaultSiteInstance( browsing_instance_->coop_coep_cross_origin_isolated_info())); @@ -623,6 +647,12 @@ has_site_ = true; site_info_ = site_info; + // Now that we have a site, register it with the BrowsingInstance. This + // ensures that we won't create another SiteInstance for this site within + // the same BrowsingInstance, because all same-site pages within a + // BrowsingInstance can script each other. + browsing_instance_->RegisterSiteInstance(this); + if (site_info_.is_origin_keyed()) { // Track this origin's isolation in the current BrowsingInstance. This is // needed to consistently isolate future navigations to this origin in this @@ -634,12 +664,6 @@ browsing_instance_->isolation_context(), site_origin); } - // Now that we have a site, register it with the BrowsingInstance. This - // ensures that we won't create another SiteInstance for this site within - // the same BrowsingInstance, because all same-site pages within a - // BrowsingInstance can script each other. - browsing_instance_->RegisterSiteInstance(this); - // Update the process reuse policy based on the site. bool should_use_process_per_site = ShouldUseProcessPerSite(); if (should_use_process_per_site) @@ -659,8 +683,18 @@ void SiteInstanceImpl::ConvertToDefaultOrSetSite(const UrlInfo& url_info) { DCHECK(!has_site_); - if (browsing_instance_->TrySettingDefaultSiteInstance(this, url_info)) - return; + if (!browsing_instance_->HasDefaultSiteInstance()) { + const SiteInfo site_info = ComputeSiteInfo( + GetIsolationContext(), url_info, GetCoopCoepCrossOriginIsolatedInfo()); + if (CanBePlacedInDefaultSiteInstance(GetIsolationContext(), url_info.url, + site_info)) { + SetSiteInfoToDefault(); + AddSiteInfoToDefault(site_info); + + DCHECK(browsing_instance_->HasDefaultSiteInstance()); + return; + } + } SetSite(url_info); }
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h index d48247b16..3dc0f0c 100644 --- a/content/browser/site_instance_impl.h +++ b/content/browser/site_instance_impl.h
@@ -685,6 +685,10 @@ bool IsOriginalUrlSameSite(const UrlInfo& dest_url_info, bool should_compare_effective_urls); + // Add |site_info| to the set that tracks what sites have been allowed + // to be handled by this default SiteInstance. + void AddSiteInfoToDefault(const SiteInfo& site_info); + // Return whether both UrlInfos must share a process to preserve script // relationships. The decision is based on a variety of factors such as // the registered domain of the URLs (google.com, bbc.co.uk), the scheme @@ -783,6 +787,10 @@ base::ObserverList<Observer, true>::Unchecked observers_; + // Contains the state that is only required for default SiteInstances. + class DefaultSiteInstanceState; + std::unique_ptr<DefaultSiteInstanceState> default_site_instance_state_; + DISALLOW_COPY_AND_ASSIGN(SiteInstanceImpl); };
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index 5913443f7..933710f 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -329,11 +329,7 @@ // result. virtual void ActivateFindInPageResultForAccessibility(int request_id) = 0; - // Roundtrips through the renderer and compositor pipeline to ensure that any - // changes to the contents resulting from operations executed prior to this - // call are visible on screen. The call completes asynchronously by running - // the supplied |callback| with a value of true upon successful completion and - // false otherwise when the widget is destroyed. + // See RenderWidgetHost::InsertVisualStateCallback(). using VisualStateCallback = base::OnceCallback<void(bool)>; virtual void InsertVisualStateCallback(VisualStateCallback callback) = 0;
diff --git a/content/public/browser/render_widget_host.h b/content/public/browser/render_widget_host.h index dc8391f..c011ff1 100644 --- a/content/public/browser/render_widget_host.h +++ b/content/public/browser/render_widget_host.h
@@ -331,6 +331,15 @@ // Shows the context menu using the specified point as anchor point. virtual void ShowContextMenuAtPoint(const gfx::Point& point, const ui::MenuSourceType source_type) {} + + // Roundtrips through the renderer and compositor pipeline to ensure that any + // changes to the contents resulting from operations executed prior to this + // call are visible on screen. The call completes asynchronously (if it + // succeeds) by running the supplied |callback| with a value of true upon + // successful completion and false otherwise when the widget is destroyed. + // This can run synchronously on failure. + using VisualStateCallback = base::OnceCallback<void(bool)>; + virtual void InsertVisualStateCallback(VisualStateCallback callback) {} }; } // namespace content
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index cdf26a7..7d59da8 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1085,6 +1085,7 @@ "../browser/renderer_host/ancestor_throttle_browsertest.cc", "../browser/renderer_host/back_forward_cache_metrics_browsertest.cc", "../browser/renderer_host/blocked_scheme_navigation_browsertest.cc", + "../browser/renderer_host/cookie_browsertest.cc", "../browser/renderer_host/embedding_token_browsertest.cc", "../browser/renderer_host/frame_tree_browsertest.cc", "../browser/renderer_host/input/autoscroll_browsertest.cc", @@ -1115,7 +1116,6 @@ "../browser/renderer_host/render_document_host_user_data_browsertest.cc", "../browser/renderer_host/render_frame_host_impl_browsertest.cc", "../browser/renderer_host/render_frame_host_manager_browsertest.cc", - "../browser/renderer_host/render_frame_message_filter_browsertest.cc", "../browser/renderer_host/render_process_host_browsertest.cc", "../browser/renderer_host/render_view_host_browsertest.cc", "../browser/renderer_host/render_widget_host_browsertest.cc",
diff --git a/content/test/data/accessibility/aria/aria-hidden-expected-android.txt b/content/test/data/accessibility/aria/aria-hidden-expected-android.txt index 9ed30ba..0b6eed87 100644 --- a/content/test/data/accessibility/aria/aria-hidden-expected-android.txt +++ b/content/test/data/accessibility/aria/aria-hidden-expected-android.txt
@@ -2,4 +2,5 @@ ++android.view.View name='blockDisplay' ++android.view.View name='blockDisplay Hiddenfalse' ++android.view.View invisible -++android.view.View focusable invisible name='blockDisplay Hiddentruefocusable' \ No newline at end of file +++android.view.View focusable invisible name='blockDisplay Hiddentruefocusable' +++android.view.View role_description='heading 1' heading invisible name='noneDisplayParent Hiddenfalse'
diff --git a/content/test/data/accessibility/aria/aria-hidden-expected-auralinux.txt b/content/test/data/accessibility/aria/aria-hidden-expected-auralinux.txt index c9383e39..3ab2c2b 100644 --- a/content/test/data/accessibility/aria/aria-hidden-expected-auralinux.txt +++ b/content/test/data/accessibility/aria/aria-hidden-expected-auralinux.txt
@@ -5,3 +5,4 @@ ++++[static] name='blockDisplay Hiddenfalse' ++[section] hidden:true ++[section] name='blockDisplay Hiddentruefocusable' hidden:true +++[heading] name='noneDisplayParent Hiddenfalse' hidden:true
diff --git a/content/test/data/accessibility/aria/aria-hidden-expected-blink.txt b/content/test/data/accessibility/aria/aria-hidden-expected-blink.txt index e7cfe62..7f18ebd 100644 --- a/content/test/data/accessibility/aria/aria-hidden-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-hidden-expected-blink.txt
@@ -13,4 +13,6 @@ ++++++++++inlineTextBox name='blockDisplay Hiddenfalse' ++++++genericContainer invisible ++++++genericContainer invisible name='blockDisplay Hiddentruefocusable' isLineBreakingObject=true -++++++++staticText ignored invisible name='blockDisplay Hiddentruefocusable' \ No newline at end of file +++++++++staticText ignored invisible name='blockDisplay Hiddentruefocusable' +++++++genericContainer ignored invisible +++++++++heading invisible name='noneDisplayParent Hiddenfalse'
diff --git a/content/test/data/accessibility/aria/aria-hidden-expected-win.txt b/content/test/data/accessibility/aria/aria-hidden-expected-win.txt index d855002..f8eb94c9 100644 --- a/content/test/data/accessibility/aria/aria-hidden-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-hidden-expected-win.txt
@@ -4,4 +4,5 @@ ++IA2_ROLE_SECTION ++++ROLE_SYSTEM_STATICTEXT name='blockDisplay Hiddenfalse' ++IA2_ROLE_SECTION INVISIBLE hidden:true -++IA2_ROLE_SECTION name='blockDisplay Hiddentruefocusable' INVISIBLE FOCUSABLE hidden:true \ No newline at end of file +++IA2_ROLE_SECTION name='blockDisplay Hiddentruefocusable' INVISIBLE FOCUSABLE hidden:true +++IA2_ROLE_HEADING name='noneDisplayParent Hiddenfalse' INVISIBLE hidden:true
diff --git a/content/test/data/accessibility/aria/aria-hidden.html b/content/test/data/accessibility/aria/aria-hidden.html index 47a793a..034eb46 100644 --- a/content/test/data/accessibility/aria/aria-hidden.html +++ b/content/test/data/accessibility/aria/aria-hidden.html
@@ -14,6 +14,7 @@ #blockDisplayAriaHiddenFalse {display: block;} #noneDisplayAriaHiddenFalse {display: none;} #blockDisplayAriaHiddenTrueFocusable {display: block;} +#noneDisplayParent {display: none;} </style> </head> <body> @@ -24,5 +25,6 @@ <div id="blockDisplayAriaHiddenFalse" aria-hidden="false">blockDisplay Hiddenfalse</div> <div id="noneDisplayAriaHiddenFalse" aria-hidden="false">noneDisplay Hiddenfalse</div> <div id="blockDisplayAriaHiddenTrueFocusable" aria-hidden="true" tabindex="-1">blockDisplay Hiddentruefocusable</div> + <div id="noneDisplayParent"><h1 aria-hidden="false">noneDisplayParent Hiddenfalse</h1></div> </body> </html>
diff --git a/content/test/data/accessibility/aria/aria-level-expected-blink.txt b/content/test/data/accessibility/aria/aria-level-expected-blink.txt index c055890d..94dc803 100644 --- a/content/test/data/accessibility/aria/aria-level-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-level-expected-blink.txt
@@ -34,14 +34,15 @@ ++++++++++staticText name='Tree item at level 3' ++++++++++++inlineTextBox name='Tree item at level 3' ++++++treeGrid -++++++++row hierarchicalLevel=1 -++++++++++cell name='Cell at level 1' -++++++++++++staticText name='Cell at level 1' -++++++++++++++inlineTextBox name='Cell at level 1' -++++++++row hierarchicalLevel=2 -++++++++++cell name='Cell at level 2' -++++++++++++staticText name='Cell at level 2' -++++++++++++++inlineTextBox name='Cell at level 2' +++++++++rowGroup ignored +++++++++++row hierarchicalLevel=1 +++++++++++++cell name='Cell at level 1' +++++++++++++++staticText name='Cell at level 1' +++++++++++++++++inlineTextBox name='Cell at level 1' +++++++++++row hierarchicalLevel=2 +++++++++++++cell name='Cell at level 2' +++++++++++++++staticText name='Cell at level 2' +++++++++++++++++inlineTextBox name='Cell at level 2' ++++++listItem hierarchicalLevel=1 ++++++++staticText name='List item at level 1' ++++++++++inlineTextBox name='List item at level 1'
diff --git a/content/test/data/accessibility/aria/aria-owns-included-in-tree-expected-blink.txt b/content/test/data/accessibility/aria/aria-owns-included-in-tree-expected-blink.txt index 4176f605..996b8d8 100644 --- a/content/test/data/accessibility/aria/aria-owns-included-in-tree-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-owns-included-in-tree-expected-blink.txt
@@ -30,4 +30,5 @@ ++++++++++++slider horizontal value='50' valueForRange=50.00 minValueForRange=0.00 maxValueForRange=100.00 ++++++++++++++sliderThumb ++++++none ignored +++++++++genericContainer ignored ++++++genericContainer ignored invisible
diff --git a/content/test/data/accessibility/aria/aria-sort-html-table-expected-blink.txt b/content/test/data/accessibility/aria/aria-sort-html-table-expected-blink.txt index 45d0c28a..eebd4c1 100644 --- a/content/test/data/accessibility/aria/aria-sort-html-table-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-sort-html-table-expected-blink.txt
@@ -2,139 +2,151 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table name='Data table' -++++++++row -++++++++++columnHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++row -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++row -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++row +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++row +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' ++++++table name='Data table' -++++++++row -++++++++++columnHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++row -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++row -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++row +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++row +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' ++++++table name='Data table' -++++++++row -++++++++++columnHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++row -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++row -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++row +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++row +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' ++++++table name='Data table' -++++++++row -++++++++++columnHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++row -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' -++++++++row -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++row +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' +++++++++++row +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' ++++++table name='Data table' -++++++++row -++++++++++columnHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++row -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++row -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++row +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++row +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' ++++++table name='Data table' -++++++++row -++++++++++rowHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' +++++++++rowGroup ignored +++++++++++row +++++++++++++rowHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' ++++++table name='Data table' -++++++++row -++++++++++rowHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' +++++++++rowGroup ignored +++++++++++row +++++++++++++rowHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' ++++++table name='Data table' -++++++++row -++++++++++rowHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' +++++++++rowGroup ignored +++++++++++row +++++++++++++rowHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' ++++++table name='Data table' -++++++++row -++++++++++rowHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' +++++++++rowGroup ignored +++++++++++row +++++++++++++rowHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' ++++++table name='Data table' -++++++++row -++++++++++rowHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' +++++++++rowGroup ignored +++++++++++row +++++++++++++rowHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' ++++++table name='Data table' -++++++++row -++++++++++columnHeader name='Alphabet' -++++++++++++staticText name='Alphabet' -++++++++++++++inlineTextBox name='Alphabet' -++++++++row -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++row -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Alphabet' +++++++++++++++staticText name='Alphabet' +++++++++++++++++inlineTextBox name='Alphabet' +++++++++++row +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++row +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' ++++++none ignored -++++++++genericContainer -++++++++++staticText name='Alphabet' -++++++++++++inlineTextBox name='Alphabet' +++++++++genericContainer ignored +++++++++++genericContainer +++++++++++++staticText name='Alphabet' +++++++++++++++inlineTextBox name='Alphabet'
diff --git a/content/test/data/accessibility/aria/aria-treegrid-expected-blink.txt b/content/test/data/accessibility/aria/aria-treegrid-expected-blink.txt index b3bd846..4a93b74 100644 --- a/content/test/data/accessibility/aria/aria-treegrid-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-treegrid-expected-blink.txt
@@ -2,14 +2,15 @@ ++genericContainer ignored ++++genericContainer ignored ++++++treeGrid -++++++++row hierarchicalLevel=1 -++++++++++cell name='Cell at level 1' -++++++++++++staticText name='Cell at level 1' -++++++++++++++inlineTextBox name='Cell at level 1' -++++++++row hierarchicalLevel=2 -++++++++++cell name='Cell at level 2' -++++++++++++staticText name='Cell at level 2' -++++++++++++++inlineTextBox name='Cell at level 2' +++++++++rowGroup ignored +++++++++++row hierarchicalLevel=1 +++++++++++++cell name='Cell at level 1' +++++++++++++++staticText name='Cell at level 1' +++++++++++++++++inlineTextBox name='Cell at level 1' +++++++++++row hierarchicalLevel=2 +++++++++++++cell name='Cell at level 2' +++++++++++++++staticText name='Cell at level 2' +++++++++++++++++inlineTextBox name='Cell at level 2' ++++++treeGrid ++++++++rowGroup ++++++++++row hierarchicalLevel=1
diff --git a/content/test/data/accessibility/aria/role-change-expected-blink.txt b/content/test/data/accessibility/aria/role-change-expected-blink.txt index e4aa1c9..b8aa0dd 100644 --- a/content/test/data/accessibility/aria/role-change-expected-blink.txt +++ b/content/test/data/accessibility/aria/role-change-expected-blink.txt
@@ -15,7 +15,8 @@ ++++++++++++inlineTextBox name='Real ' ++++++++++++inlineTextBox name='data ' ++++++++++++inlineTextBox name='table' -++++++++row -++++++++++cell name='X' -++++++++++++staticText name='X' -++++++++++++++inlineTextBox name='X' +++++++++rowGroup ignored +++++++++++row +++++++++++++cell name='X' +++++++++++++++staticText name='X' +++++++++++++++++inlineTextBox name='X'
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt index c5e5841..e6d19d9 100644 --- a/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt +++ b/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt
@@ -2,36 +2,37 @@ ++genericContainer ignored ++++genericContainer ignored ++++++grid ariaColumnCount=5 ariaRowCount=4 tableRowCount=3 tableColumnCount=3 -++++++++row -++++++++++columnHeader name='Month' ariaCellColumnIndex=2 ariaCellRowIndex=2 -++++++++++++staticText name='Month' -++++++++++++++inlineTextBox name='Month' -++++++++++columnHeader name='Day' ariaCellColumnIndex=3 ariaCellRowIndex=2 -++++++++++++staticText name='Day' -++++++++++++++inlineTextBox name='Day' -++++++++++columnHeader name='Weather' ariaCellColumnIndex=5 ariaCellRowIndex=2 -++++++++++++staticText name='Weather' -++++++++++++++inlineTextBox name='Weather' -++++++++row -++++++++++cell name='January' ariaCellColumnIndex=2 ariaCellRowIndex=3 -++++++++++++staticText name='January' -++++++++++++++inlineTextBox name='January' -++++++++++cell name='01' ariaCellColumnIndex=3 ariaCellRowIndex=3 -++++++++++++staticText name='01' -++++++++++++++inlineTextBox name='01' -++++++++++cell name='Sunny' ariaCellColumnIndex=5 ariaCellRowIndex=3 -++++++++++++staticText name='Sunny' -++++++++++++++inlineTextBox name='Sunny' -++++++++row -++++++++++cell name='January' ariaCellColumnIndex=2 ariaCellRowIndex=4 -++++++++++++staticText name='January' -++++++++++++++inlineTextBox name='January' -++++++++++cell name='02' ariaCellColumnIndex=3 ariaCellRowIndex=4 -++++++++++++staticText name='02' -++++++++++++++inlineTextBox name='02' -++++++++++cell name='Rainy' ariaCellColumnIndex=5 ariaCellRowIndex=4 -++++++++++++staticText name='Rainy' -++++++++++++++inlineTextBox name='Rainy' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Month' ariaCellColumnIndex=2 ariaCellRowIndex=2 +++++++++++++++staticText name='Month' +++++++++++++++++inlineTextBox name='Month' +++++++++++++columnHeader name='Day' ariaCellColumnIndex=3 ariaCellRowIndex=2 +++++++++++++++staticText name='Day' +++++++++++++++++inlineTextBox name='Day' +++++++++++++columnHeader name='Weather' ariaCellColumnIndex=5 ariaCellRowIndex=2 +++++++++++++++staticText name='Weather' +++++++++++++++++inlineTextBox name='Weather' +++++++++++row +++++++++++++cell name='January' ariaCellColumnIndex=2 ariaCellRowIndex=3 +++++++++++++++staticText name='January' +++++++++++++++++inlineTextBox name='January' +++++++++++++cell name='01' ariaCellColumnIndex=3 ariaCellRowIndex=3 +++++++++++++++staticText name='01' +++++++++++++++++inlineTextBox name='01' +++++++++++++cell name='Sunny' ariaCellColumnIndex=5 ariaCellRowIndex=3 +++++++++++++++staticText name='Sunny' +++++++++++++++++inlineTextBox name='Sunny' +++++++++++row +++++++++++++cell name='January' ariaCellColumnIndex=2 ariaCellRowIndex=4 +++++++++++++++staticText name='January' +++++++++++++++++inlineTextBox name='January' +++++++++++++cell name='02' ariaCellColumnIndex=3 ariaCellRowIndex=4 +++++++++++++++staticText name='02' +++++++++++++++++inlineTextBox name='02' +++++++++++++cell name='Rainy' ariaCellColumnIndex=5 ariaCellRowIndex=4 +++++++++++++++staticText name='Rainy' +++++++++++++++++inlineTextBox name='Rainy' ++++++paragraph ++++++++staticText name='done' ++++++++++inlineTextBox name='done'
diff --git a/content/test/data/accessibility/html/caption-expected-blink.txt b/content/test/data/accessibility/html/caption-expected-blink.txt index 93fd483..6baf64e5 100644 --- a/content/test/data/accessibility/html/caption-expected-blink.txt +++ b/content/test/data/accessibility/html/caption-expected-blink.txt
@@ -6,24 +6,25 @@ ++++++++++staticText name='Browser and Engine' ++++++++++++inlineTextBox name='Browser and ' ++++++++++++inlineTextBox name='Engine' -++++++++row -++++++++++columnHeader name='Browser' -++++++++++++staticText name='Browser' -++++++++++++++inlineTextBox name='Browser' -++++++++++columnHeader name='Engine' -++++++++++++staticText name='Engine' -++++++++++++++inlineTextBox name='Engine' -++++++++row -++++++++++cell name='Chrome' -++++++++++++staticText name='Chrome' -++++++++++++++inlineTextBox name='Chrome' -++++++++++cell name='Blink' -++++++++++++staticText name='Blink' -++++++++++++++inlineTextBox name='Blink' -++++++++row -++++++++++cell name='Safari' -++++++++++++staticText name='Safari' -++++++++++++++inlineTextBox name='Safari' -++++++++++cell name='WebKit' -++++++++++++staticText name='WebKit' -++++++++++++++inlineTextBox name='WebKit' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Browser' +++++++++++++++staticText name='Browser' +++++++++++++++++inlineTextBox name='Browser' +++++++++++++columnHeader name='Engine' +++++++++++++++staticText name='Engine' +++++++++++++++++inlineTextBox name='Engine' +++++++++++row +++++++++++++cell name='Chrome' +++++++++++++++staticText name='Chrome' +++++++++++++++++inlineTextBox name='Chrome' +++++++++++++cell name='Blink' +++++++++++++++staticText name='Blink' +++++++++++++++++inlineTextBox name='Blink' +++++++++++row +++++++++++++cell name='Safari' +++++++++++++++staticText name='Safari' +++++++++++++++++inlineTextBox name='Safari' +++++++++++++cell name='WebKit' +++++++++++++++staticText name='WebKit' +++++++++++++++++inlineTextBox name='WebKit'
diff --git a/content/test/data/accessibility/html/col-expected-blink.txt b/content/test/data/accessibility/html/col-expected-blink.txt index c970851e..34d0f75 100644 --- a/content/test/data/accessibility/html/col-expected-blink.txt +++ b/content/test/data/accessibility/html/col-expected-blink.txt
@@ -2,17 +2,18 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++columnHeader name='Browser' -++++++++++++staticText name='Browser' -++++++++++++++inlineTextBox name='Browser' -++++++++++columnHeader name='Rendering Engine' -++++++++++++staticText name='Rendering Engine' -++++++++++++++inlineTextBox name='Rendering Engine' -++++++++row -++++++++++cell name='Chrome' -++++++++++++staticText name='Chrome' -++++++++++++++inlineTextBox name='Chrome' -++++++++++cell name='Blink' -++++++++++++staticText name='Blink' -++++++++++++++inlineTextBox name='Blink' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Browser' +++++++++++++++staticText name='Browser' +++++++++++++++++inlineTextBox name='Browser' +++++++++++++columnHeader name='Rendering Engine' +++++++++++++++staticText name='Rendering Engine' +++++++++++++++++inlineTextBox name='Rendering Engine' +++++++++++row +++++++++++++cell name='Chrome' +++++++++++++++staticText name='Chrome' +++++++++++++++++inlineTextBox name='Chrome' +++++++++++++cell name='Blink' +++++++++++++++staticText name='Blink' +++++++++++++++++inlineTextBox name='Blink'
diff --git a/content/test/data/accessibility/html/colgroup-expected-blink.txt b/content/test/data/accessibility/html/colgroup-expected-blink.txt index 60101251..94de0c2 100644 --- a/content/test/data/accessibility/html/colgroup-expected-blink.txt +++ b/content/test/data/accessibility/html/colgroup-expected-blink.txt
@@ -2,17 +2,18 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++columnHeader name='Single' -++++++++++++staticText name='Single' -++++++++++++++inlineTextBox name='Single' -++++++++++columnHeader name='Pair' -++++++++++++staticText name='Pair' -++++++++++++++inlineTextBox name='Pair' -++++++++row -++++++++++cell name='A' -++++++++++++staticText name='A' -++++++++++++++inlineTextBox name='A' -++++++++++cell name='AA' -++++++++++++staticText name='AA' -++++++++++++++inlineTextBox name='AA' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Single' +++++++++++++++staticText name='Single' +++++++++++++++++inlineTextBox name='Single' +++++++++++++columnHeader name='Pair' +++++++++++++++staticText name='Pair' +++++++++++++++++inlineTextBox name='Pair' +++++++++++row +++++++++++++cell name='A' +++++++++++++++staticText name='A' +++++++++++++++++inlineTextBox name='A' +++++++++++++cell name='AA' +++++++++++++++staticText name='AA' +++++++++++++++++inlineTextBox name='AA'
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-expected-blink.txt b/content/test/data/accessibility/html/contenteditable-descendants-expected-blink.txt index 7a5e55d9..ee12142b 100644 --- a/content/test/data/accessibility/html/contenteditable-descendants-expected-blink.txt +++ b/content/test/data/accessibility/html/contenteditable-descendants-expected-blink.txt
@@ -19,10 +19,11 @@ ++++++++++staticText editable richlyEditable name='.' ++++++++++++inlineTextBox name='.' ++++++++table editable richlyEditable -++++++++++row editable richlyEditable -++++++++++++cell editable richlyEditable name='Always expose editable tables as tables.' -++++++++++++++staticText editable richlyEditable name='Always expose editable tables as tables.' -++++++++++++++++inlineTextBox name='Always expose editable tables as tables.' +++++++++++rowGroup editable ignored richlyEditable +++++++++++++row editable richlyEditable +++++++++++++++cell editable richlyEditable name='Always expose editable tables as tables.' +++++++++++++++++staticText editable richlyEditable name='Always expose editable tables as tables.' +++++++++++++++++++inlineTextBox name='Always expose editable tables as tables.' ++++++++list editable richlyEditable ++++++++++listItem editable richlyEditable ++++++++++++listMarker editable richlyEditable name='1. '
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-blink.txt b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-blink.txt index ba4a362..f61c629 100644 --- a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-blink.txt +++ b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-blink.txt
@@ -19,10 +19,11 @@ ++++++++++staticText editable richlyEditable name='.' ++++++++++++inlineTextBox name='.' ++++++++table editable richlyEditable -++++++++++row editable richlyEditable -++++++++++++cell editable richlyEditable name='Always expose editable tables as tables.' -++++++++++++++staticText editable richlyEditable name='Always expose editable tables as tables.' -++++++++++++++++inlineTextBox name='Always expose editable tables as tables.' +++++++++++rowGroup editable ignored richlyEditable +++++++++++++row editable richlyEditable +++++++++++++++cell editable richlyEditable name='Always expose editable tables as tables.' +++++++++++++++++staticText editable richlyEditable name='Always expose editable tables as tables.' +++++++++++++++++++inlineTextBox name='Always expose editable tables as tables.' ++++++++list editable richlyEditable ++++++++++listItem editable richlyEditable ++++++++++++listMarker editable richlyEditable name='1. '
diff --git a/content/test/data/accessibility/html/input-radio-checkbox-label-expected-android.txt b/content/test/data/accessibility/html/input-radio-checkbox-label-expected-android.txt index 3f7e937..4efbac08 100644 --- a/content/test/data/accessibility/html/input-radio-checkbox-label-expected-android.txt +++ b/content/test/data/accessibility/html/input-radio-checkbox-label-expected-android.txt
@@ -4,7 +4,7 @@ ++++android.widget.CheckBox role_description='checkbox' checkable clickable focusable name='label ignored for checkbox' ++++android.view.View focusable name='label exposed for radio button ' ++++++android.widget.TextView name='label exposed for radio button ' -++++++android.widget.RadioButton role_description='radio button' checkable clickable focusable name='label exposed for radio button' item_index=1 row_index=1 +++++++android.widget.RadioButton role_description='radio button' checkable clickable focusable name='label exposed for radio button' ++++android.view.View focusable name='label exposed for checkbox ' ++++++android.widget.TextView name='label exposed for checkbox ' ++++++android.widget.CheckBox role_description='checkbox' checkable clickable focusable name='label exposed for checkbox' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-radio-expected-blink.txt b/content/test/data/accessibility/html/input-radio-expected-blink.txt index 81a7775..44887b1 100644 --- a/content/test/data/accessibility/html/input-radio-expected-blink.txt +++ b/content/test/data/accessibility/html/input-radio-expected-blink.txt
@@ -2,17 +2,17 @@ ++genericContainer ignored ++++genericContainer ignored ++++++form -++++++++radioButton inputType='radio' checkedState=false radioGroupIds=radioButton +++++++++radioButton inputType='radio' setSize=2 posInSet=1 checkedState=false radioGroupIds=radioButton ++++++++staticText name='Radio1' ++++++++++inlineTextBox name='Radio1' ++++++++lineBreak name='<newline>' ++++++++++inlineTextBox name='<newline>' -++++++++radioButton inputType='radio' checkedState=false radioGroupIds=radioButton +++++++++radioButton inputType='radio' setSize=2 posInSet=2 checkedState=false radioGroupIds=radioButton ++++++++staticText name='Radio2' ++++++++++inlineTextBox name='Radio2' ++++++form -++++++++radioButton inputType='radio' name='Radio3' checkedState=false radioGroupIds=radioButton,radioButton -++++++++radioButton inputType='radio' name='Radio4' checkedState=true radioGroupIds=radioButton,radioButton +++++++++radioButton inputType='radio' name='Radio3' setSize=2 posInSet=1 checkedState=false radioGroupIds=radioButton,radioButton +++++++++radioButton inputType='radio' name='Radio4' setSize=2 posInSet=2 checkedState=true radioGroupIds=radioButton,radioButton ++++++form -++++++++radioButton inputType='radio' name='Radio5' checkedState=false radioGroupIds=radioButton -++++++++radioButton inputType='radio' name='Radio6' checkedState=true radioGroupIds=radioButton +++++++++radioButton inputType='radio' name='Radio5' setSize=2 posInSet=1 checkedState=false radioGroupIds=radioButton +++++++++radioButton inputType='radio' name='Radio6' setSize=2 posInSet=2 checkedState=true radioGroupIds=radioButton
diff --git a/content/test/data/accessibility/html/input-radio-in-menu-expected-blink.txt b/content/test/data/accessibility/html/input-radio-in-menu-expected-blink.txt index 2a58854..696969a 100644 --- a/content/test/data/accessibility/html/input-radio-in-menu-expected-blink.txt +++ b/content/test/data/accessibility/html/input-radio-in-menu-expected-blink.txt
@@ -1,15 +1,15 @@ rootWebArea ++genericContainer ignored ++++genericContainer ignored -++++++menu -++++++++radioButton inputType='radio' checkedState=true +++++++menu setSize=0 +++++++++radioButton inputType='radio' setSize=3 posInSet=1 checkedState=true ++++++++staticText name='Radio0 ' ++++++++++inlineTextBox name='Radio0 ' -++++++++radioButton inputType='radio' checkedState=false +++++++++radioButton inputType='radio' setSize=3 posInSet=2 checkedState=false ++++++++staticText name='Radio1 ' ++++++++++inlineTextBox name='Radio1 ' -++++++++radioButton inputType='radio' name='Radio2' checkedState=false -++++++menu -++++++++radioButton inputType='radio' name='Radio3' checkedState=false -++++++++radioButton inputType='radio' checkedState=false -++++++++radioButton inputType='radio' checkedState=true \ No newline at end of file +++++++++radioButton inputType='radio' name='Radio2' setSize=3 posInSet=3 checkedState=false +++++++menu setSize=0 +++++++++radioButton inputType='radio' name='Radio3' setSize=3 posInSet=1 checkedState=false +++++++++radioButton inputType='radio' setSize=3 posInSet=2 checkedState=false +++++++++radioButton inputType='radio' setSize=3 posInSet=3 checkedState=true
diff --git a/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt b/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt index 37401fe..a52e128 100644 --- a/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt
@@ -8,4 +8,4 @@ ++Menu Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false ++++RadioButton Name='Radio3' SelectionItem.IsSelected=false ++++RadioButton SelectionItem.IsSelected=false -++++RadioButton SelectionItem.IsSelected=true +++++RadioButton SelectionItem.IsSelected=true \ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-radio-in-menu.html b/content/test/data/accessibility/html/input-radio-in-menu.html index 65f2f30..30e8620 100644 --- a/content/test/data/accessibility/html/input-radio-in-menu.html +++ b/content/test/data/accessibility/html/input-radio-in-menu.html
@@ -1,5 +1,7 @@ <!-- @BLINK-ALLOW:inputType=* +@BLINK-ALLOW:posInSet* +@BLINK-ALLOW:setSize* @WIN-ALLOW:CHECKED* @WIN-ALLOW:MIXED* @WIN-ALLOW:checkable*
diff --git a/content/test/data/accessibility/html/input-radio.html b/content/test/data/accessibility/html/input-radio.html index ea143ab..33eed6d5 100644 --- a/content/test/data/accessibility/html/input-radio.html +++ b/content/test/data/accessibility/html/input-radio.html
@@ -1,6 +1,8 @@ <!-- @BLINK-ALLOW:inputType=* @BLINK-ALLOW:radioGroupIds=* +@BLINK-ALLOW:setSize* +@BLINK-ALLOW:posInSet* @MAC-ALLOW:AXLinkedUIElements @MAC-DENY:AXLinkedUIElements=[] @WIN-ALLOW:MIXED*
diff --git a/content/test/data/accessibility/html/landmark-expected-blink.txt b/content/test/data/accessibility/html/landmark-expected-blink.txt index 54488edd..a9baf19 100644 --- a/content/test/data/accessibility/html/landmark-expected-blink.txt +++ b/content/test/data/accessibility/html/landmark-expected-blink.txt
@@ -80,9 +80,10 @@ ++++++++++++inlineTextBox name='This should NOT have banner role.' ++++++group ++++++++genericContainer ignored -++++++++++headerAsNonLandmark -++++++++++++staticText name='This should NOT have banner role.' -++++++++++++++inlineTextBox name='This should NOT have banner role.' +++++++++++genericContainer ignored +++++++++++++headerAsNonLandmark +++++++++++++++staticText name='This should NOT have banner role.' +++++++++++++++++inlineTextBox name='This should NOT have banner role.' ++++++main ++++++++headerAsNonLandmark ++++++++++staticText name='This should NOT have banner role.' @@ -129,9 +130,10 @@ ++++++none ignored ++++++++genericContainer ignored ++++++++++genericContainer ignored -++++++++++++headerAsNonLandmark -++++++++++++++staticText name='This should NOT have banner role.' -++++++++++++++++inlineTextBox name='This should NOT have banner role.' +++++++++++++genericContainer ignored +++++++++++++++headerAsNonLandmark +++++++++++++++++staticText name='This should NOT have banner role.' +++++++++++++++++++inlineTextBox name='This should NOT have banner role.' ++++++main ++++++++genericContainer ignored ++++++++++headerAsNonLandmark @@ -171,9 +173,10 @@ ++++++++++++inlineTextBox name='This should NOT have footer role.' ++++++none ignored ++++++++genericContainer ignored -++++++++++footerAsNonLandmark -++++++++++++staticText name='This should NOT have footer role.' -++++++++++++++inlineTextBox name='This should NOT have footer role.' +++++++++++genericContainer ignored +++++++++++++footerAsNonLandmark +++++++++++++++staticText name='This should NOT have footer role.' +++++++++++++++++inlineTextBox name='This should NOT have footer role.' ++++++main ++++++++footerAsNonLandmark ++++++++++staticText name='This should NOT have footer role.' @@ -220,9 +223,10 @@ ++++++group ++++++++genericContainer ignored ++++++++++genericContainer ignored -++++++++++++footerAsNonLandmark -++++++++++++++staticText name='This should NOT have footer role.' -++++++++++++++++inlineTextBox name='This should NOT have footer role.' +++++++++++++genericContainer ignored +++++++++++++++footerAsNonLandmark +++++++++++++++++staticText name='This should NOT have footer role.' +++++++++++++++++++inlineTextBox name='This should NOT have footer role.' ++++++main ++++++++genericContainer ignored ++++++++++footerAsNonLandmark
diff --git a/content/test/data/accessibility/html/table-headers-empty-first-cell-expected-blink.txt b/content/test/data/accessibility/html/table-headers-empty-first-cell-expected-blink.txt index 86a7a4e12..622b031 100644 --- a/content/test/data/accessibility/html/table-headers-empty-first-cell-expected-blink.txt +++ b/content/test/data/accessibility/html/table-headers-empty-first-cell-expected-blink.txt
@@ -5,96 +5,97 @@ ++++++++caption ++++++++++staticText name='Delivery slots:' ++++++++++++inlineTextBox name='Delivery slots:' -++++++++row -++++++++++cell -++++++++++columnHeader name='Monday' -++++++++++++staticText name='Monday' -++++++++++++++inlineTextBox name='Monday' -++++++++++columnHeader name='Tuesday' -++++++++++++staticText name='Tuesday' -++++++++++++++inlineTextBox name='Tuesday' -++++++++++columnHeader name='Wednesday' -++++++++++++staticText name='Wednesday' -++++++++++++++inlineTextBox name='Wednesday' -++++++++++columnHeader name='Thursday' -++++++++++++staticText name='Thursday' -++++++++++++++inlineTextBox name='Thursday' -++++++++++columnHeader name='Friday' -++++++++++++staticText name='Friday' -++++++++++++++inlineTextBox name='Friday' -++++++++row -++++++++++rowHeader name='09:00 - 11:00' -++++++++++++staticText name='09:00 - 11:00' -++++++++++++++inlineTextBox name='09:00 - 11:00' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++row -++++++++++rowHeader name='11:00 - 13:00' -++++++++++++staticText name='11:00 - 13:00' -++++++++++++++inlineTextBox name='11:00 - 13:00' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++row -++++++++++rowHeader name='13:00 - 15:00' -++++++++++++staticText name='13:00 - 15:00' -++++++++++++++inlineTextBox name='13:00 - 15:00' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++row -++++++++++rowHeader name='15:00 - 17:00' -++++++++++++staticText name='15:00 - 17:00' -++++++++++++++inlineTextBox name='15:00 - 17:00' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++++cell name='Closed' -++++++++++++staticText name='Closed' -++++++++++++++inlineTextBox name='Closed' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' -++++++++++cell name='Open' -++++++++++++staticText name='Open' -++++++++++++++inlineTextBox name='Open' +++++++++rowGroup ignored +++++++++++row +++++++++++++cell +++++++++++++columnHeader name='Monday' +++++++++++++++staticText name='Monday' +++++++++++++++++inlineTextBox name='Monday' +++++++++++++columnHeader name='Tuesday' +++++++++++++++staticText name='Tuesday' +++++++++++++++++inlineTextBox name='Tuesday' +++++++++++++columnHeader name='Wednesday' +++++++++++++++staticText name='Wednesday' +++++++++++++++++inlineTextBox name='Wednesday' +++++++++++++columnHeader name='Thursday' +++++++++++++++staticText name='Thursday' +++++++++++++++++inlineTextBox name='Thursday' +++++++++++++columnHeader name='Friday' +++++++++++++++staticText name='Friday' +++++++++++++++++inlineTextBox name='Friday' +++++++++++row +++++++++++++rowHeader name='09:00 - 11:00' +++++++++++++++staticText name='09:00 - 11:00' +++++++++++++++++inlineTextBox name='09:00 - 11:00' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++row +++++++++++++rowHeader name='11:00 - 13:00' +++++++++++++++staticText name='11:00 - 13:00' +++++++++++++++++inlineTextBox name='11:00 - 13:00' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++row +++++++++++++rowHeader name='13:00 - 15:00' +++++++++++++++staticText name='13:00 - 15:00' +++++++++++++++++inlineTextBox name='13:00 - 15:00' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++row +++++++++++++rowHeader name='15:00 - 17:00' +++++++++++++++staticText name='15:00 - 17:00' +++++++++++++++++inlineTextBox name='15:00 - 17:00' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++++cell name='Closed' +++++++++++++++staticText name='Closed' +++++++++++++++++inlineTextBox name='Closed' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open' +++++++++++++cell name='Open' +++++++++++++++staticText name='Open' +++++++++++++++++inlineTextBox name='Open'
diff --git a/content/test/data/accessibility/html/table-headers-on-all-sides-expected-blink.txt b/content/test/data/accessibility/html/table-headers-on-all-sides-expected-blink.txt index 6130cb75..a599226 100644 --- a/content/test/data/accessibility/html/table-headers-on-all-sides-expected-blink.txt +++ b/content/test/data/accessibility/html/table-headers-on-all-sides-expected-blink.txt
@@ -2,47 +2,48 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++cell -++++++++++columnHeader name='Red' -++++++++++++staticText name='Red' -++++++++++++++inlineTextBox name='Red' -++++++++++columnHeader name='Green' -++++++++++++staticText name='Green' -++++++++++++++inlineTextBox name='Green' -++++++++++cell -++++++++row -++++++++++rowHeader name='Fruit' -++++++++++++staticText name='Fruit' -++++++++++++++inlineTextBox name='Fruit' -++++++++++cell name='strawberry' -++++++++++++staticText name='strawberry' -++++++++++++++inlineTextBox name='strawberry' -++++++++++cell name='lime' -++++++++++++staticText name='lime' -++++++++++++++inlineTextBox name='lime' -++++++++++rowHeader name='Fruit' -++++++++++++staticText name='Fruit' -++++++++++++++inlineTextBox name='Fruit' -++++++++row -++++++++++rowHeader name='Veggies' -++++++++++++staticText name='Veggies' -++++++++++++++inlineTextBox name='Veggies' -++++++++++cell name='radish' -++++++++++++staticText name='radish' -++++++++++++++inlineTextBox name='radish' -++++++++++cell name='spinach' -++++++++++++staticText name='spinach' -++++++++++++++inlineTextBox name='spinach' -++++++++++rowHeader name='Veggies' -++++++++++++staticText name='Veggies' -++++++++++++++inlineTextBox name='Veggies' -++++++++row -++++++++++cell -++++++++++columnHeader name='Red' -++++++++++++staticText name='Red' -++++++++++++++inlineTextBox name='Red' -++++++++++columnHeader name='Green' -++++++++++++staticText name='Green' -++++++++++++++inlineTextBox name='Green' -++++++++++cell +++++++++rowGroup ignored +++++++++++row +++++++++++++cell +++++++++++++columnHeader name='Red' +++++++++++++++staticText name='Red' +++++++++++++++++inlineTextBox name='Red' +++++++++++++columnHeader name='Green' +++++++++++++++staticText name='Green' +++++++++++++++++inlineTextBox name='Green' +++++++++++++cell +++++++++++row +++++++++++++rowHeader name='Fruit' +++++++++++++++staticText name='Fruit' +++++++++++++++++inlineTextBox name='Fruit' +++++++++++++cell name='strawberry' +++++++++++++++staticText name='strawberry' +++++++++++++++++inlineTextBox name='strawberry' +++++++++++++cell name='lime' +++++++++++++++staticText name='lime' +++++++++++++++++inlineTextBox name='lime' +++++++++++++rowHeader name='Fruit' +++++++++++++++staticText name='Fruit' +++++++++++++++++inlineTextBox name='Fruit' +++++++++++row +++++++++++++rowHeader name='Veggies' +++++++++++++++staticText name='Veggies' +++++++++++++++++inlineTextBox name='Veggies' +++++++++++++cell name='radish' +++++++++++++++staticText name='radish' +++++++++++++++++inlineTextBox name='radish' +++++++++++++cell name='spinach' +++++++++++++++staticText name='spinach' +++++++++++++++++inlineTextBox name='spinach' +++++++++++++rowHeader name='Veggies' +++++++++++++++staticText name='Veggies' +++++++++++++++++inlineTextBox name='Veggies' +++++++++++row +++++++++++++cell +++++++++++++columnHeader name='Red' +++++++++++++++staticText name='Red' +++++++++++++++++inlineTextBox name='Red' +++++++++++++columnHeader name='Green' +++++++++++++++staticText name='Green' +++++++++++++++++inlineTextBox name='Green' +++++++++++++cell
diff --git a/content/test/data/accessibility/html/table-multiple-row-and-column-headers-expected-blink.txt b/content/test/data/accessibility/html/table-multiple-row-and-column-headers-expected-blink.txt index bd4c47b..f7153bb 100644 --- a/content/test/data/accessibility/html/table-multiple-row-and-column-headers-expected-blink.txt +++ b/content/test/data/accessibility/html/table-multiple-row-and-column-headers-expected-blink.txt
@@ -2,94 +2,95 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++cell -++++++++++columnHeader name='Mars' -++++++++++++staticText name='Mars' -++++++++++++++inlineTextBox name='Mars' -++++++++++columnHeader name='Venus' -++++++++++++staticText name='Venus' -++++++++++++++inlineTextBox name='Venus' -++++++++row -++++++++++columnHeader name='Produced' -++++++++++++staticText name='Produced' -++++++++++++++inlineTextBox name='Produced' -++++++++++columnHeader name='Sold' -++++++++++++staticText name='Sold' -++++++++++++++inlineTextBox name='Sold' -++++++++++columnHeader name='Produced' -++++++++++++staticText name='Produced' -++++++++++++++inlineTextBox name='Produced' -++++++++++columnHeader name='Sold' -++++++++++++staticText name='Sold' -++++++++++++++inlineTextBox name='Sold' -++++++++row -++++++++++rowHeader name='For Toddlers' -++++++++++++staticText name='For Toddlers' -++++++++++++++inlineTextBox name='For Toddlers' -++++++++++rowHeader name='Teddy Bears' -++++++++++++staticText name='Teddy Bears' -++++++++++++++inlineTextBox name='Teddy Bears' -++++++++++cell name='50,000' -++++++++++++staticText name='50,000' -++++++++++++++inlineTextBox name='50,000' -++++++++++cell name='30,000' -++++++++++++staticText name='30,000' -++++++++++++++inlineTextBox name='30,000' -++++++++++cell name='100,000' -++++++++++++staticText name='100,000' -++++++++++++++inlineTextBox name='100,000' -++++++++++cell name='80,000' -++++++++++++staticText name='80,000' -++++++++++++++inlineTextBox name='80,000' -++++++++row -++++++++++rowHeader name='Action Figures' -++++++++++++staticText name='Action Figures' -++++++++++++++inlineTextBox name='Action Figures' -++++++++++cell name='25,000' -++++++++++++staticText name='25,000' -++++++++++++++inlineTextBox name='25,000' -++++++++++cell name='15,000' -++++++++++++staticText name='15,000' -++++++++++++++inlineTextBox name='15,000' -++++++++++cell name='50,000' -++++++++++++staticText name='50,000' -++++++++++++++inlineTextBox name='50,000' -++++++++++cell name='40,000' -++++++++++++staticText name='40,000' -++++++++++++++inlineTextBox name='40,000' -++++++++row -++++++++++rowHeader name='For Teens' -++++++++++++staticText name='For Teens' -++++++++++++++inlineTextBox name='For Teens' -++++++++++rowHeader name='Board Games' -++++++++++++staticText name='Board Games' -++++++++++++++inlineTextBox name='Board Games' -++++++++++cell name='5,000' -++++++++++++staticText name='5,000' -++++++++++++++inlineTextBox name='5,000' -++++++++++cell name='2,000' -++++++++++++staticText name='2,000' -++++++++++++++inlineTextBox name='2,000' -++++++++++cell name='6,000' -++++++++++++staticText name='6,000' -++++++++++++++inlineTextBox name='6,000' -++++++++++cell name='4,000' -++++++++++++staticText name='4,000' -++++++++++++++inlineTextBox name='4,000' -++++++++row -++++++++++rowHeader name='Video Games' -++++++++++++staticText name='Video Games' -++++++++++++++inlineTextBox name='Video Games' -++++++++++cell name='10,000' -++++++++++++staticText name='10,000' -++++++++++++++inlineTextBox name='10,000' -++++++++++cell name='5,000' -++++++++++++staticText name='5,000' -++++++++++++++inlineTextBox name='5,000' -++++++++++cell name='12,000' -++++++++++++staticText name='12,000' -++++++++++++++inlineTextBox name='12,000' -++++++++++cell name='9,000' -++++++++++++staticText name='9,000' -++++++++++++++inlineTextBox name='9,000' +++++++++rowGroup ignored +++++++++++row +++++++++++++cell +++++++++++++columnHeader name='Mars' +++++++++++++++staticText name='Mars' +++++++++++++++++inlineTextBox name='Mars' +++++++++++++columnHeader name='Venus' +++++++++++++++staticText name='Venus' +++++++++++++++++inlineTextBox name='Venus' +++++++++++row +++++++++++++columnHeader name='Produced' +++++++++++++++staticText name='Produced' +++++++++++++++++inlineTextBox name='Produced' +++++++++++++columnHeader name='Sold' +++++++++++++++staticText name='Sold' +++++++++++++++++inlineTextBox name='Sold' +++++++++++++columnHeader name='Produced' +++++++++++++++staticText name='Produced' +++++++++++++++++inlineTextBox name='Produced' +++++++++++++columnHeader name='Sold' +++++++++++++++staticText name='Sold' +++++++++++++++++inlineTextBox name='Sold' +++++++++++row +++++++++++++rowHeader name='For Toddlers' +++++++++++++++staticText name='For Toddlers' +++++++++++++++++inlineTextBox name='For Toddlers' +++++++++++++rowHeader name='Teddy Bears' +++++++++++++++staticText name='Teddy Bears' +++++++++++++++++inlineTextBox name='Teddy Bears' +++++++++++++cell name='50,000' +++++++++++++++staticText name='50,000' +++++++++++++++++inlineTextBox name='50,000' +++++++++++++cell name='30,000' +++++++++++++++staticText name='30,000' +++++++++++++++++inlineTextBox name='30,000' +++++++++++++cell name='100,000' +++++++++++++++staticText name='100,000' +++++++++++++++++inlineTextBox name='100,000' +++++++++++++cell name='80,000' +++++++++++++++staticText name='80,000' +++++++++++++++++inlineTextBox name='80,000' +++++++++++row +++++++++++++rowHeader name='Action Figures' +++++++++++++++staticText name='Action Figures' +++++++++++++++++inlineTextBox name='Action Figures' +++++++++++++cell name='25,000' +++++++++++++++staticText name='25,000' +++++++++++++++++inlineTextBox name='25,000' +++++++++++++cell name='15,000' +++++++++++++++staticText name='15,000' +++++++++++++++++inlineTextBox name='15,000' +++++++++++++cell name='50,000' +++++++++++++++staticText name='50,000' +++++++++++++++++inlineTextBox name='50,000' +++++++++++++cell name='40,000' +++++++++++++++staticText name='40,000' +++++++++++++++++inlineTextBox name='40,000' +++++++++++row +++++++++++++rowHeader name='For Teens' +++++++++++++++staticText name='For Teens' +++++++++++++++++inlineTextBox name='For Teens' +++++++++++++rowHeader name='Board Games' +++++++++++++++staticText name='Board Games' +++++++++++++++++inlineTextBox name='Board Games' +++++++++++++cell name='5,000' +++++++++++++++staticText name='5,000' +++++++++++++++++inlineTextBox name='5,000' +++++++++++++cell name='2,000' +++++++++++++++staticText name='2,000' +++++++++++++++++inlineTextBox name='2,000' +++++++++++++cell name='6,000' +++++++++++++++staticText name='6,000' +++++++++++++++++inlineTextBox name='6,000' +++++++++++++cell name='4,000' +++++++++++++++staticText name='4,000' +++++++++++++++++inlineTextBox name='4,000' +++++++++++row +++++++++++++rowHeader name='Video Games' +++++++++++++++staticText name='Video Games' +++++++++++++++++inlineTextBox name='Video Games' +++++++++++++cell name='10,000' +++++++++++++++staticText name='10,000' +++++++++++++++++inlineTextBox name='10,000' +++++++++++++cell name='5,000' +++++++++++++++staticText name='5,000' +++++++++++++++++inlineTextBox name='5,000' +++++++++++++cell name='12,000' +++++++++++++++staticText name='12,000' +++++++++++++++++inlineTextBox name='12,000' +++++++++++++cell name='9,000' +++++++++++++++staticText name='9,000' +++++++++++++++++inlineTextBox name='9,000'
diff --git a/content/test/data/accessibility/html/table-presentation-expected-blink.txt b/content/test/data/accessibility/html/table-presentation-expected-blink.txt index 2a84820..308594c7 100644 --- a/content/test/data/accessibility/html/table-presentation-expected-blink.txt +++ b/content/test/data/accessibility/html/table-presentation-expected-blink.txt
@@ -2,15 +2,16 @@ ++genericContainer ignored ++++genericContainer ignored ++++++presentational ignored -++++++++genericContainer -++++++++++staticText name='1' -++++++++++++inlineTextBox name='1' -++++++++genericContainer -++++++++++staticText name='2' -++++++++++++inlineTextBox name='2' -++++++++genericContainer -++++++++++staticText name='4' -++++++++++++inlineTextBox name='4' -++++++++genericContainer -++++++++++staticText name='5' -++++++++++++inlineTextBox name='5' +++++++++genericContainer ignored +++++++++++genericContainer +++++++++++++staticText name='1' +++++++++++++++inlineTextBox name='1' +++++++++++genericContainer +++++++++++++staticText name='2' +++++++++++++++inlineTextBox name='2' +++++++++++genericContainer +++++++++++++staticText name='4' +++++++++++++++inlineTextBox name='4' +++++++++++genericContainer +++++++++++++staticText name='5' +++++++++++++++inlineTextBox name='5'
diff --git a/content/test/data/accessibility/html/table-simple-expected-blink.txt b/content/test/data/accessibility/html/table-simple-expected-blink.txt index 9f662c15..6f67135 100644 --- a/content/test/data/accessibility/html/table-simple-expected-blink.txt +++ b/content/test/data/accessibility/html/table-simple-expected-blink.txt
@@ -2,24 +2,25 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++columnHeader name='Pair' -++++++++++++staticText name='Pair' -++++++++++++++inlineTextBox name='Pair' -++++++++++columnHeader name='Single' -++++++++++++staticText name='Single' -++++++++++++++inlineTextBox name='Single' -++++++++row -++++++++++cell name='AB' -++++++++++++staticText name='AB' -++++++++++++++inlineTextBox name='AB' -++++++++++cell name='B' -++++++++++++staticText name='B' -++++++++++++++inlineTextBox name='B' -++++++++row -++++++++++cell name='CD' -++++++++++++staticText name='CD' -++++++++++++++inlineTextBox name='CD' -++++++++++cell name='D' -++++++++++++staticText name='D' -++++++++++++++inlineTextBox name='D' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Pair' +++++++++++++++staticText name='Pair' +++++++++++++++++inlineTextBox name='Pair' +++++++++++++columnHeader name='Single' +++++++++++++++staticText name='Single' +++++++++++++++++inlineTextBox name='Single' +++++++++++row +++++++++++++cell name='AB' +++++++++++++++staticText name='AB' +++++++++++++++++inlineTextBox name='AB' +++++++++++++cell name='B' +++++++++++++++staticText name='B' +++++++++++++++++inlineTextBox name='B' +++++++++++row +++++++++++++cell name='CD' +++++++++++++++staticText name='CD' +++++++++++++++++inlineTextBox name='CD' +++++++++++++cell name='D' +++++++++++++++staticText name='D' +++++++++++++++++inlineTextBox name='D'
diff --git a/content/test/data/accessibility/html/table-spans-expected-blink.txt b/content/test/data/accessibility/html/table-spans-expected-blink.txt index d698db9..6fc1542 100644 --- a/content/test/data/accessibility/html/table-spans-expected-blink.txt +++ b/content/test/data/accessibility/html/table-spans-expected-blink.txt
@@ -2,29 +2,31 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++cell name='AD' -++++++++++++staticText name='AD' -++++++++++++++inlineTextBox name='AD' -++++++++++cell name='BC' -++++++++++++staticText name='BC' -++++++++++++++inlineTextBox name='BC' -++++++++row -++++++++++cell name='EF' -++++++++++++staticText name='EF' -++++++++++++++inlineTextBox name='EF' +++++++++rowGroup ignored +++++++++++row +++++++++++++cell name='AD' +++++++++++++++staticText name='AD' +++++++++++++++++inlineTextBox name='AD' +++++++++++++cell name='BC' +++++++++++++++staticText name='BC' +++++++++++++++++inlineTextBox name='BC' +++++++++++row +++++++++++++cell name='EF' +++++++++++++++staticText name='EF' +++++++++++++++++inlineTextBox name='EF' ++++++table -++++++++row -++++++++++cell name='AD' -++++++++++++staticText name='AD' -++++++++++++++inlineTextBox name='AD' -++++++++++cell name='BC' -++++++++++++staticText name='BC' -++++++++++++++inlineTextBox name='BC' -++++++++row -++++++++++cell name='EF' -++++++++++++staticText name='EF' -++++++++++++++inlineTextBox name='EF' -++++++++++cell name='GH' -++++++++++++staticText name='GH' -++++++++++++++inlineTextBox name='GH' +++++++++rowGroup ignored +++++++++++row +++++++++++++cell name='AD' +++++++++++++++staticText name='AD' +++++++++++++++++inlineTextBox name='AD' +++++++++++++cell name='BC' +++++++++++++++staticText name='BC' +++++++++++++++++inlineTextBox name='BC' +++++++++++row +++++++++++++cell name='EF' +++++++++++++++staticText name='EF' +++++++++++++++++inlineTextBox name='EF' +++++++++++++cell name='GH' +++++++++++++++staticText name='GH' +++++++++++++++++inlineTextBox name='GH'
diff --git a/content/test/data/accessibility/html/table-th-colheader-expected-blink.txt b/content/test/data/accessibility/html/table-th-colheader-expected-blink.txt index 4e2783f..93d681bd 100644 --- a/content/test/data/accessibility/html/table-th-colheader-expected-blink.txt +++ b/content/test/data/accessibility/html/table-th-colheader-expected-blink.txt
@@ -2,17 +2,18 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++columnHeader name='Firstname' -++++++++++++staticText name='Firstname' -++++++++++++++inlineTextBox name='Firstname' -++++++++++columnHeader name='Lastname' -++++++++++++staticText name='Lastname' -++++++++++++++inlineTextBox name='Lastname' -++++++++row -++++++++++cell name='Jill' -++++++++++++staticText name='Jill' -++++++++++++++inlineTextBox name='Jill' -++++++++++cell name='Smith' -++++++++++++staticText name='Smith' -++++++++++++++inlineTextBox name='Smith' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Firstname' +++++++++++++++staticText name='Firstname' +++++++++++++++++inlineTextBox name='Firstname' +++++++++++++columnHeader name='Lastname' +++++++++++++++staticText name='Lastname' +++++++++++++++++inlineTextBox name='Lastname' +++++++++++row +++++++++++++cell name='Jill' +++++++++++++++staticText name='Jill' +++++++++++++++++inlineTextBox name='Jill' +++++++++++++cell name='Smith' +++++++++++++++staticText name='Smith' +++++++++++++++++inlineTextBox name='Smith'
diff --git a/content/test/data/accessibility/html/table-th-rowheader-expected-blink.txt b/content/test/data/accessibility/html/table-th-rowheader-expected-blink.txt index 7d4ca5e..fb1e6b8 100644 --- a/content/test/data/accessibility/html/table-th-rowheader-expected-blink.txt +++ b/content/test/data/accessibility/html/table-th-rowheader-expected-blink.txt
@@ -2,17 +2,18 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++rowHeader name='Firstname' -++++++++++++staticText name='Firstname' -++++++++++++++inlineTextBox name='Firstname' -++++++++++cell name='Jill' -++++++++++++staticText name='Jill' -++++++++++++++inlineTextBox name='Jill' -++++++++row -++++++++++rowHeader name='Lastname' -++++++++++++staticText name='Lastname' -++++++++++++++inlineTextBox name='Lastname' -++++++++++cell name='Smith' -++++++++++++staticText name='Smith' -++++++++++++++inlineTextBox name='Smith' +++++++++rowGroup ignored +++++++++++row +++++++++++++rowHeader name='Firstname' +++++++++++++++staticText name='Firstname' +++++++++++++++++inlineTextBox name='Firstname' +++++++++++++cell name='Jill' +++++++++++++++staticText name='Jill' +++++++++++++++++inlineTextBox name='Jill' +++++++++++row +++++++++++++rowHeader name='Lastname' +++++++++++++++staticText name='Lastname' +++++++++++++++++inlineTextBox name='Lastname' +++++++++++++cell name='Smith' +++++++++++++++staticText name='Smith' +++++++++++++++++inlineTextBox name='Smith'
diff --git a/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-blink.txt b/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-blink.txt index b0e694a..8966dba 100644 --- a/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-blink.txt +++ b/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-blink.txt
@@ -2,31 +2,34 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++columnHeader name='Sum' -++++++++++++staticText name='Sum' -++++++++++++++inlineTextBox name='Sum' -++++++++++columnHeader name='Subtraction' -++++++++++++staticText name='Subtraction' -++++++++++++++inlineTextBox name='Subtraction' -++++++++row -++++++++++cell name='10' -++++++++++++staticText name='10' -++++++++++++++inlineTextBox name='10' -++++++++++cell name='7' -++++++++++++staticText name='7' -++++++++++++++inlineTextBox name='7' -++++++++row -++++++++++cell name='2' -++++++++++++staticText name='2' -++++++++++++++inlineTextBox name='2' -++++++++++cell name='4' -++++++++++++staticText name='4' -++++++++++++++inlineTextBox name='4' -++++++++row -++++++++++cell name='12' -++++++++++++staticText name='12' -++++++++++++++inlineTextBox name='12' -++++++++++cell name='3' -++++++++++++staticText name='3' -++++++++++++++inlineTextBox name='3' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Sum' +++++++++++++++staticText name='Sum' +++++++++++++++++inlineTextBox name='Sum' +++++++++++++columnHeader name='Subtraction' +++++++++++++++staticText name='Subtraction' +++++++++++++++++inlineTextBox name='Subtraction' +++++++++rowGroup ignored +++++++++++row +++++++++++++cell name='10' +++++++++++++++staticText name='10' +++++++++++++++++inlineTextBox name='10' +++++++++++++cell name='7' +++++++++++++++staticText name='7' +++++++++++++++++inlineTextBox name='7' +++++++++++row +++++++++++++cell name='2' +++++++++++++++staticText name='2' +++++++++++++++++inlineTextBox name='2' +++++++++++++cell name='4' +++++++++++++++staticText name='4' +++++++++++++++++inlineTextBox name='4' +++++++++rowGroup ignored +++++++++++row +++++++++++++cell name='12' +++++++++++++++staticText name='12' +++++++++++++++++inlineTextBox name='12' +++++++++++++cell name='3' +++++++++++++++staticText name='3' +++++++++++++++++inlineTextBox name='3'
diff --git a/content/test/data/accessibility/regression/hidden-table-expected-blink.txt b/content/test/data/accessibility/regression/hidden-table-expected-blink.txt index 59d1cc2..0f1fef2 100644 --- a/content/test/data/accessibility/regression/hidden-table-expected-blink.txt +++ b/content/test/data/accessibility/regression/hidden-table-expected-blink.txt
@@ -2,13 +2,14 @@ ++genericContainer ignored ++++genericContainer ignored ++++++table -++++++++row -++++++++++columnHeader name='Header 1' -++++++++++++staticText name='Header 1' -++++++++++++++inlineTextBox name='Header 1' -++++++++++columnHeader name='Header 2' -++++++++++++staticText name='Header 2' -++++++++++++++inlineTextBox name='Header 2' +++++++++rowGroup ignored +++++++++++row +++++++++++++columnHeader name='Header 1' +++++++++++++++staticText name='Header 1' +++++++++++++++++inlineTextBox name='Header 1' +++++++++++++columnHeader name='Header 2' +++++++++++++++staticText name='Header 2' +++++++++++++++++inlineTextBox name='Header 2' ++++++genericContainer ++++++++staticText name='Done' ++++++++++inlineTextBox name='Done'
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test.py b/content/test/gpu/gpu_tests/gpu_integration_test.py index dec40fc..7039af0 100644 --- a/content/test/gpu/gpu_tests/gpu_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_integration_test.py
@@ -25,6 +25,8 @@ _SUPPORTED_WIN_INTEL_GPUS = [0x5912, 0x3e92] _SUPPORTED_WIN_INTEL_GPUS_WITH_YUY2_OVERLAYS = [0x5912, 0x3e92] _SUPPORTED_WIN_INTEL_GPUS_WITH_NV12_OVERLAYS = [0x5912, 0x3e92] +# Hardware overlays are disabled in 26.20.100.8141 per crbug.com/1079393#c105 +_UNSUPPORTED_WIN_INTEL_GPU_DRIVERS_WITH_NV12_OVERLAYS = ['5912-26.20.100.8141'] class GpuIntegrationTest( @@ -458,9 +460,12 @@ config['nv12_overlay_support'] = 'SOFTWARE' if gpu_vendor_id == 0x8086: assert gpu_device_id in _SUPPORTED_WIN_INTEL_GPUS + gpu_device_and_driver = ('%x-' + gpu.driver_version) % gpu_device_id if gpu_device_id in _SUPPORTED_WIN_INTEL_GPUS_WITH_YUY2_OVERLAYS: config['yuy2_overlay_support'] = 'SCALING' - if gpu_device_id in _SUPPORTED_WIN_INTEL_GPUS_WITH_NV12_OVERLAYS: + if (gpu_device_id in _SUPPORTED_WIN_INTEL_GPUS_WITH_NV12_OVERLAYS + and gpu_device_and_driver not in + _UNSUPPORTED_WIN_INTEL_GPU_DRIVERS_WITH_NV12_OVERLAYS): config['nv12_overlay_support'] = 'SCALING' return config
diff --git a/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt index 126eacfe0..0d839c0 100644 --- a/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt
@@ -59,10 +59,6 @@ # Incorrectly reporting SCALING instead of DIRECT on Win10 w/ UHD 630 GPUs. crbug.com/1079393 [ win intel-0x3e92 ] InfoCollection_direct_composition [ Failure ] -# Incorrectly reporting SOFTWARE instead of SCALING for nv12_overlay_support on -# Win10 w/ HD 630 GPUs and driver 26.20.100.8141 -crbug.com/1079393 [ win intel-0x5912 ] InfoCollection_direct_composition [ Failure ] - # NVIDIA bots need 456.38+ drivers to use SOFTWARE overlays. crbug.com/1113893 [ win nvidia ] InfoCollection_direct_composition [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt index e62a9b1..8d4debd 100644 --- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -156,10 +156,6 @@ crbug.com/1079393 [ win10 intel-0x5912 ] OverlayModeTraceTest_DirectComposition_Video_VP9_NV12 [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Underlay_Fullsize [ Failure ] crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_Fullsize [ Failure ] -crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_NV12 [ Failure ] -crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_MP4_VP_SCALING [ Failure ] -crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_VP9_NV12 [ Failure ] -crbug.com/1079393 [ win10 intel-0x5912 ] VideoPathTraceTest_DirectComposition_Video_VP9_VP_SCALING [ Failure ] # Fuchsia Flakes. crbug.com/1058255 [ fuchsia ] TraceTest_WebGLGreenTriangle_AA_Alpha [ Skip ]
diff --git a/device/fido/cros/authenticator.cc b/device/fido/cros/authenticator.cc index 5d674d3..3c2afb00 100644 --- a/device/fido/cros/authenticator.cc +++ b/device/fido/cros/authenticator.cc
@@ -39,7 +39,7 @@ namespace { -constexpr int kHasCredentialsTimeoutMs = 3000; +constexpr int kShortTimeoutMs = 3000; AuthenticatorSupportedOptions ChromeOSAuthenticatorOptions() { AuthenticatorSupportedOptions options; @@ -98,16 +98,22 @@ req.set_rp_id(request.rp.id); req.set_user_id( std::string(request.user.id.begin(), request.user.id.end())); + if (request.user.display_name.has_value()) + req.set_user_display_name(request.user.display_name.value()); req.set_resident_credential(request.resident_key_required); DCHECK(generate_request_id_callback_); - req.set_request_id(generate_request_id_callback_.Run()); + DCHECK_EQ(current_request_id_, 0u); + current_request_id_ = generate_request_id_callback_.Run(); + req.set_request_id(current_request_id_); dbus::MethodCall method_call(u2f::kU2FInterface, u2f::kU2FMakeCredential); dbus::MessageWriter writer(&method_call); writer.AppendProtoAsArrayOfBytes(req); + // Use infinite timeout because Cancel() will be called when the request + // times out. u2f_proxy->CallMethodWithErrorResponse( - &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE, base::BindOnce(&ChromeOSAuthenticator::OnMakeCredentialResp, weak_factory_.GetWeakPtr(), std::move(request), std::move(callback))); @@ -199,7 +205,9 @@ req.set_client_data_hash(std::string(request.client_data_hash.begin(), request.client_data_hash.end())); DCHECK(generate_request_id_callback_); - req.set_request_id(generate_request_id_callback_.Run()); + DCHECK_EQ(current_request_id_, 0u); + current_request_id_ = generate_request_id_callback_.Run(); + req.set_request_id(current_request_id_); for (const PublicKeyCredentialDescriptor& descriptor : request.allow_list) { const std::vector<uint8_t>& id = descriptor.id(); @@ -210,8 +218,10 @@ dbus::MessageWriter writer(&method_call); writer.AppendProtoAsArrayOfBytes(req); + // Use infinite timeout because Cancel() will be called when the request + // times out. u2f_proxy->CallMethodWithErrorResponse( - &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE, base::BindOnce(&ChromeOSAuthenticator::OnGetAssertionResp, weak_factory_.GetWeakPtr(), std::move(request), std::move(callback))); @@ -295,7 +305,7 @@ writer.AppendProtoAsArrayOfBytes(req); std::unique_ptr<dbus::Response> dbus_response = - u2f_proxy->CallMethodAndBlock(&method_call, kHasCredentialsTimeoutMs); + u2f_proxy->CallMethodAndBlock(&method_call, kShortTimeoutMs); if (!dbus_response) { FIDO_LOG(ERROR) << "HasCredentials dbus call had no response or timed out"; @@ -314,6 +324,55 @@ resp.credential_id().size() > 0; } +void ChromeOSAuthenticator::Cancel() { + if (current_request_id_ == 0u) + return; + + dbus::Bus::Options dbus_options; + dbus_options.bus_type = dbus::Bus::SYSTEM; + scoped_refptr<dbus::Bus> bus = new dbus::Bus(dbus_options); + dbus::ObjectProxy* u2f_proxy = bus->GetObjectProxy( + u2f::kU2FServiceName, dbus::ObjectPath(u2f::kU2FServicePath)); + + if (!u2f_proxy) { + FIDO_LOG(ERROR) << "Couldn't get u2f proxy, cannot cancel request"; + return; + } + + u2f::CancelWebAuthnFlowRequest req; + req.set_request_id(current_request_id_); + dbus::MethodCall method_call(u2f::kU2FInterface, u2f::kU2FCancelWebAuthnFlow); + dbus::MessageWriter writer(&method_call); + writer.AppendProtoAsArrayOfBytes(req); + + // This needs to be non-blocking since canceling the flow involves Ash. + u2f_proxy->CallMethod(&method_call, kShortTimeoutMs, + base::BindOnce(&ChromeOSAuthenticator::OnCancelResp, + weak_factory_.GetWeakPtr())); +} + +void ChromeOSAuthenticator::OnCancelResp(dbus::Response* dbus_response) { + if (!dbus_response) { + FIDO_LOG(ERROR) + << "CancelWebAuthnFlow dbus call had no response or timed out"; + return; + } + + dbus::MessageReader reader(dbus_response); + u2f::CancelWebAuthnFlowResponse resp; + if (!reader.PopArrayOfBytesAsProto(&resp)) { + FIDO_LOG(ERROR) << "Failed to parse reply for call to CancelWebAuthnFlow"; + return; + } + + if (!resp.canceled()) { + FIDO_LOG(ERROR) << "Failed to cancel WebAuthn request with id " + << current_request_id_; + } + + current_request_id_ = 0u; +} + bool ChromeOSAuthenticator::IsInPairingMode() const { return false; }
diff --git a/device/fido/cros/authenticator.h b/device/fido/cros/authenticator.h index d6fcee1..c016662 100644 --- a/device/fido/cros/authenticator.h +++ b/device/fido/cros/authenticator.h
@@ -39,7 +39,7 @@ CtapGetAssertionOptions options, GetAssertionCallback callback) override; void GetNextAssertion(GetAssertionCallback callback) override {} - void Cancel() override {} + void Cancel() override; std::string GetId() const override; base::string16 GetDisplayName() const override; const base::Optional<AuthenticatorSupportedOptions>& Options() const override; @@ -66,6 +66,11 @@ dbus::Response* dbus_response, dbus::ErrorResponse* error); + void OnCancelResp(dbus::Response* dbus_response); + + // Current request_id, used for cancelling the request. + uint32_t current_request_id_ = 0u; + // Callback to set request_id in the window property. base::RepeatingCallback<uint32_t()> generate_request_id_callback_; base::WeakPtrFactory<ChromeOSAuthenticator> weak_factory_;
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc index c0196018..b699bb4 100644 --- a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc +++ b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc
@@ -1706,8 +1706,6 @@ tree_id_to_tree_wrapper_map_.clear(); } -// http://crbug.com/784266 -// clang-format off void AutomationInternalCustomBindings::OnMessageReceived( const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(AutomationInternalCustomBindings, message) @@ -1716,7 +1714,7 @@ IPC_MESSAGE_HANDLER(ExtensionMsg_AccessibilityLocationChange, OnAccessibilityLocationChange) IPC_END_MESSAGE_MAP() -} // clang-format on +} AutomationAXTreeWrapper* AutomationInternalCustomBindings:: GetAutomationAXTreeWrapperFromTreeID(ui::AXTreeID tree_id) const {
diff --git a/headless/lib/headless_content_main_delegate.cc b/headless/lib/headless_content_main_delegate.cc index 7bac74b..1a71f0d 100644 --- a/headless/lib/headless_content_main_delegate.cc +++ b/headless/lib/headless_content_main_delegate.cc
@@ -369,9 +369,12 @@ #else if (command_line.HasSwitch(::switches::kEnableLogging)) InitLogging(command_line); + + // Initializing the crash reporter fails in multiple ways on Windows. See + // https://crbug.com/1147063 + InitCrashReporter(command_line); #endif // defined(OS_WIN) - InitCrashReporter(command_line); InitializeResourceBundle(command_line); // Even though InitializeResourceBundle() has indirectly done the locale
diff --git a/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc b/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc index 0c2800f..6571a6b 100644 --- a/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc +++ b/media/capture/video/chromeos/camera_hal_dispatcher_impl.cc
@@ -232,9 +232,8 @@ void CameraHalDispatcherImpl::RegisterClient( mojo::PendingRemote<cros::mojom::CameraHalClient> client) { - // RegisterClient can be called locally by ArcCameraBridge. Unretained - // reference is safe here because CameraHalDispatcherImpl owns - // |proxy_thread_|. + // RegisterClient can be called locally by ArcCameraBridge, so it's not + // necessarily called on |proxy_thread_|. // TODO(b/170075468): Reject this call once we've migrated all camera clients. auto temporary_token = base::UnguessableToken::Create(); @@ -249,6 +248,8 @@ const base::UnguessableToken& auth_token, RegisterClientWithTokenCallback callback) { base::UnguessableToken client_auth_token = auth_token; + // Unretained reference is safe here because CameraHalDispatcherImpl owns + // |proxy_thread_|. proxy_task_runner_->PostTask( FROM_HERE, base::BindOnce(
diff --git a/media/gpu/h265_decoder.cc b/media/gpu/h265_decoder.cc index adc5e39..73b652f4 100644 --- a/media/gpu/h265_decoder.cc +++ b/media/gpu/h265_decoder.cc
@@ -478,41 +478,57 @@ // Equation 8-5. int i, j, k; for (i = 0, j = 0, k = 0; i < curr_st_ref_pic_set.num_negative_pics; ++i) { - if (curr_st_ref_pic_set.used_by_curr_pic_s0[i]) { - poc_st_curr_before_[j++] = - curr_pic_->pic_order_cnt_val_ + curr_st_ref_pic_set.delta_poc_s0[i]; - } else { - poc_st_foll_[k++] = - curr_pic_->pic_order_cnt_val_ + curr_st_ref_pic_set.delta_poc_s0[i]; + base::CheckedNumeric<int> poc = curr_pic_->pic_order_cnt_val_; + poc += curr_st_ref_pic_set.delta_poc_s0[i]; + if (!poc.IsValid()) { + DVLOG(1) << "Invalid POC"; + return false; } + if (curr_st_ref_pic_set.used_by_curr_pic_s0[i]) + poc_st_curr_before_[j++] = poc.ValueOrDefault(0); + else + poc_st_foll_[k++] = poc.ValueOrDefault(0); } num_poc_st_curr_before_ = j; for (i = 0, j = 0; i < curr_st_ref_pic_set.num_positive_pics; ++i) { - if (curr_st_ref_pic_set.used_by_curr_pic_s1[i]) { - poc_st_curr_after_[j++] = - curr_pic_->pic_order_cnt_val_ + curr_st_ref_pic_set.delta_poc_s1[i]; - } else { - poc_st_foll_[k++] = - curr_pic_->pic_order_cnt_val_ + curr_st_ref_pic_set.delta_poc_s1[i]; + base::CheckedNumeric<int> poc = curr_pic_->pic_order_cnt_val_; + poc += curr_st_ref_pic_set.delta_poc_s1[i]; + if (!poc.IsValid()) { + DVLOG(1) << "Invalid POC"; + return false; } + if (curr_st_ref_pic_set.used_by_curr_pic_s1[i]) + poc_st_curr_after_[j++] = poc.ValueOrDefault(0); + else + poc_st_foll_[k++] = poc.ValueOrDefault(0); } num_poc_st_curr_after_ = j; num_poc_st_foll_ = k; for (i = 0, j = 0, k = 0; i < slice_hdr->num_long_term_sps + slice_hdr->num_long_term_pics; ++i) { - int poc_lt = slice_hdr->poc_lsb_lt[i]; + base::CheckedNumeric<int> poc_lt = slice_hdr->poc_lsb_lt[i]; if (slice_hdr->delta_poc_msb_present_flag[i]) { - poc_lt += - curr_pic_->pic_order_cnt_val_ - - (slice_hdr->delta_poc_msb_cycle_lt[i] * max_pic_order_cnt_lsb_) - - (curr_pic_->pic_order_cnt_val_ & (max_pic_order_cnt_lsb_ - 1)); + poc_lt += curr_pic_->pic_order_cnt_val_; + base::CheckedNumeric<int> poc_delta = + slice_hdr->delta_poc_msb_cycle_lt[i]; + poc_delta *= max_pic_order_cnt_lsb_; + if (!poc_delta.IsValid()) { + DVLOG(1) << "Invalid POC"; + return false; + } + poc_lt -= poc_delta.ValueOrDefault(0); + poc_lt -= curr_pic_->pic_order_cnt_val_ & (max_pic_order_cnt_lsb_ - 1); + } + if (!poc_lt.IsValid()) { + DVLOG(1) << "Invalid POC"; + return false; } if (slice_hdr->used_by_curr_pic_lt[i]) { - poc_lt_curr_[j] = poc_lt; + poc_lt_curr_[j] = poc_lt.ValueOrDefault(0); curr_delta_poc_msb_present_flag_[j++] = slice_hdr->delta_poc_msb_present_flag[i]; } else { - poc_lt_foll_[k] = poc_lt; + poc_lt_foll_[k] = poc_lt.ValueOrDefault(0); foll_delta_poc_msb_present_flag_[k++] = slice_hdr->delta_poc_msb_present_flag[i]; }
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn index 225173d2..37215e8e 100644 --- a/media/gpu/vaapi/BUILD.gn +++ b/media/gpu/vaapi/BUILD.gn
@@ -20,6 +20,9 @@ if (use_x11) { sigs += [ "va_x11.sigs" ] } + if (is_chromeos_ash) { + sigs += [ "va_prot.sigs" ] + } sigs += [ "va_drm.sigs" ] output_name = "va_stubs"
diff --git a/media/gpu/vaapi/DEPS b/media/gpu/vaapi/DEPS index 3fad129..25f64c72 100644 --- a/media/gpu/vaapi/DEPS +++ b/media/gpu/vaapi/DEPS
@@ -1,3 +1,7 @@ +include_rules = [ + "+third_party/libva_protected_content/va_protected_content.h", +] + specific_include_rules = { ".*_unittest\.cc": [ "+third_party/libwebp",
diff --git a/media/gpu/vaapi/OWNERS b/media/gpu/vaapi/OWNERS index 96c1ece..ba18e106 100644 --- a/media/gpu/vaapi/OWNERS +++ b/media/gpu/vaapi/OWNERS
@@ -8,3 +8,6 @@ # General VA-API decoding related stuff per-file *image_decoder*=andrescj@chromium.org + +# For protected-mode video decoding. +jkardatzke@google.com
diff --git a/media/gpu/vaapi/va_prot.sigs b/media/gpu/vaapi/va_prot.sigs new file mode 100644 index 0000000..afc7bf5 --- /dev/null +++ b/media/gpu/vaapi/va_prot.sigs
@@ -0,0 +1,12 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +//------------------------------------------------ +// Functions from libva protected content interface used in chromium code. +//------------------------------------------------ +VAStatus vaCreateProtectedSession(VADisplay dpy, VAConfigID config_id, VAProtectedSessionID *protected_session); +VAStatus vaDestroyProtectedSession(VADisplay dpy, VAProtectedSessionID protected_session); +VAStatus vaAttachProtectedSession(VADisplay dpy, VAContextID reserved, VAProtectedSessionID protected_session); +VAStatus vaDetachProtectedSession(VADisplay dpy, VAContextID reserved); +VAStatus vaProtectedSessionHwUpdate(VADisplay dpy, VAProtectedSessionID protected_session, VABufferID buf_id);
diff --git a/media/gpu/vaapi/vaapi_video_decoder.cc b/media/gpu/vaapi/vaapi_video_decoder.cc index 08fe795..34fcca48 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.cc +++ b/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -152,10 +152,21 @@ return; } - if (cdm_context || config.is_encrypted()) { - VLOGF(1) << "Vaapi decoder does not support encrypted stream"; + if (config.is_encrypted()) { +#if !BUILDFLAG(IS_CHROMEOS_ASH) std::move(init_cb).Run(StatusCode::kEncryptedContentUnsupported); return; +#else + if (!cdm_context || !cdm_context->GetChromeOsCdmContext()) { + LOG(ERROR) << "Cannot support encrypted stream w/out ChromeOsCdmContext"; + std::move(init_cb).Run(StatusCode::kDecoderMissingCdmForEncryptedContent); + return; + } + cdm_context_ = cdm_context; + cdm_event_cb_registration_ = cdm_context_->RegisterEventCB( + base::BindRepeating(&VaapiVideoDecoder::OnCdmContextEvent, + weak_this_factory_.GetWeakPtr())); +#endif } // We expect the decoder to have released all output buffers (by the client @@ -185,7 +196,12 @@ // Initialize VAAPI wrapper. const VideoCodecProfile profile = config.profile(); vaapi_wrapper_ = VaapiWrapper::CreateForVideoCodec( - VaapiWrapper::kDecode, profile, +#if BUILDFLAG(IS_CHROMEOS_ASH) + !cdm_context_ ? VaapiWrapper::kDecode : VaapiWrapper::kDecodeProtected, +#else + VaapiWrapper::kDecode, +#endif + profile, base::BindRepeating(&ReportVaapiErrorToUMA, "Media.VaapiVideoDecoder.VAAPIError")); UMA_HISTOGRAM_BOOLEAN("Media.VaapiVideoDecoder.VaapiWrapperCreationSuccess", @@ -218,6 +234,17 @@ std::move(init_cb).Run(OkStatus()); } +void VaapiVideoDecoder::OnCdmContextEvent(CdmContext::Event event) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (event != CdmContext::Event::kHasAdditionalUsableKey) + return; + + // Invoke the callback we'd get for a protected session update because this is + // the same thing, it's a trigger that there are new keys, so if we were + // waiting for a key we should fetch them again. + ProtectedSessionUpdate(true); +} + void VaapiVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -321,8 +348,8 @@ SetState(State::kError); break; case AcceleratedVideoDecoder::kTryAgain: - LOG(ERROR) << "Encrypted streams not supported"; - SetState(State::kError); + DVLOG(1) << "Decoder going into the waiting for protected state"; + SetState(State::kWaitingForProtected); break; } } @@ -477,11 +504,9 @@ CHECK(format); auto format_fourcc = Fourcc::FromVideoPixelFormat(*format); CHECK(format_fourcc); - // TODO(jkardatzke): Pass true for the last argument when we are in protected - // mode. if (!frame_pool_->Initialize( *format_fourcc, pic_size, visible_rect, natural_size, - decoder_->GetRequiredNumOfPictures(), /*use_protected=*/false)) { + decoder_->GetRequiredNumOfPictures(), !!cdm_context_)) { DLOG(WARNING) << "Failed Initialize()ing the frame pool."; SetState(State::kError); return; @@ -501,7 +526,12 @@ // When a profile is changed, we need to re-initialize VaapiWrapper. profile_ = decoder_->GetProfile(); auto new_vaapi_wrapper = VaapiWrapper::CreateForVideoCodec( - VaapiWrapper::kDecode, profile_, +#if BUILDFLAG(IS_CHROMEOS_ASH) + !cdm_context_ ? VaapiWrapper::kDecode : VaapiWrapper::kDecodeProtected, +#else + VaapiWrapper::kDecode, +#endif + profile_, base::BindRepeating(&ReportVaapiErrorToUMA, "Media.VaapiVideoDecoder.VAAPIError")); if (!new_vaapi_wrapper.get()) { @@ -557,6 +587,27 @@ } } +void VaapiVideoDecoder::ProtectedSessionUpdate(bool success) { + DVLOGF(4); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!success) { + LOG(ERROR) << "Terminating decoding after failed protected update"; + SetState(State::kError); + return; + } + + // If we were waiting for a protected update, retry the current decode task. + if (state_ != State::kWaitingForProtected) + return; + + DCHECK(current_decode_task_); + SetState(State::kDecoding); + decoder_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_)); +} + void VaapiVideoDecoder::Flush() { DVLOGF(2); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -702,6 +753,9 @@ DCHECK(state_ == State::kUninitialized || state_ == State::kDecoding || state_ == State::kResetting); break; + case State::kWaitingForProtected: + DCHECK(!!cdm_context_); + FALLTHROUGH; case State::kWaitingForOutput: DCHECK(current_decode_task_); DCHECK_EQ(state_, State::kDecoding);
diff --git a/media/gpu/vaapi/vaapi_video_decoder.h b/media/gpu/vaapi/vaapi_video_decoder.h index 65b7088..403588eb 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.h +++ b/media/gpu/vaapi/vaapi_video_decoder.h
@@ -22,6 +22,8 @@ #include "base/optional.h" #include "base/sequence_checker.h" #include "base/time/time.h" +#include "build/chromeos_buildflags.h" +#include "media/base/callback_registry.h" #include "media/base/cdm_context.h" #include "media/base/status.h" #include "media/base/video_codecs.h" @@ -88,14 +90,16 @@ }; enum class State { - kUninitialized, // not initialized yet or initialization failed. - kWaitingForInput, // waiting for input buffers. - kWaitingForOutput, // waiting for output buffers. - kDecoding, // decoding buffers. - kChangingResolution, // need to change resolution, waiting for pipeline to - // be flushed. - kResetting, // resetting decoder. - kError, // decoder encountered an error. + kUninitialized, // not initialized yet or initialization failed. + kWaitingForInput, // waiting for input buffers. + kWaitingForOutput, // waiting for output buffers. + kWaitingForProtected, // waiting on something related to protected content, + // either setup, full sample parsing or key loading. + kDecoding, // decoding buffers. + kChangingResolution, // need to change resolution, waiting for pipeline to + // be flushed. + kResetting, // resetting decoder. + kError, // decoder encountered an error. }; VaapiVideoDecoder( @@ -119,6 +123,9 @@ void ReleaseVideoFrame(VASurfaceID surface_id); // Callback for |frame_pool_| to notify of available resources. void NotifyFrameAvailable(); + // Callback from accelerator to indicate the protected state has been updated + // so we can proceed or fail. + void ProtectedSessionUpdate(bool success); // Flushes |decoder_|, blocking until all pending decode tasks have been // executed and all frames have been output. @@ -133,6 +140,9 @@ // Change the current |state_| to the specified |state|. void SetState(State state); + // Callback for the CDM to notify |this|. + void OnCdmContextEvent(CdmContext::Event event); + // The video decoder's state. State state_ = State::kUninitialized; @@ -174,6 +184,12 @@ // TODO(crbug.com/1040291): remove this keep-alive when using SharedImages. base::small_map<std::map<gfx::GpuMemoryBufferId, scoped_refptr<VASurface>>> allocated_va_surfaces_; +#if BUILDFLAG(IS_CHROMEOS_ASH) + // To keep the CdmContext event callback registered. + std::unique_ptr<CallbackRegistration> cdm_event_cb_registration_; +#endif + + CdmContext* cdm_context_ = nullptr; // Not owned. // Platform and codec specific video decoder. std::unique_ptr<AcceleratedVideoDecoder> decoder_;
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index 02dba73..f64daf1 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -50,6 +50,7 @@ #include "media/gpu/vaapi/va_stubs.h" #include "gpu/config/gpu_driver_bug_workarounds.h" +#include "third_party/libva_protected_content/va_protected_content.h" #include "third_party/libyuv/include/libyuv.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/buffer_types.h" @@ -75,6 +76,11 @@ #include "ui/ozone/public/surface_factory_ozone.h" #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include <va/va_prot.h> +using media_gpu_vaapi::kModuleVa_prot; +#endif + using media_gpu_vaapi::kModuleVa; using media_gpu_vaapi::kModuleVa_drm; #if defined(USE_X11) @@ -119,8 +125,14 @@ kVASyncSurface = 22, kVATerminate = 23, kVAUnmapBuffer = 24, + // Protected mode functions below. + kVACreateProtectedSession = 25, + kVADestroyProtectedSession = 26, + kVAAttachProtectedSession = 27, + kVADetachProtectedSession = 28, + kVAProtectedSessionHwUpdate = 29, // Anything else is captured in this last entry. - kOtherVAFunction = 25, + kOtherVAFunction = 30, kMaxValue = kOtherVAFunction, }; @@ -156,6 +168,11 @@ "vaSyncSurface", "vaTerminate", "vaUnmapBuffer", + "vaCreateProtectedSession", + "vaDestroyProtectedSession", + "vaAttachProtectedSession", + "vaDetachProtectedSession", + "vaProtectedSessionHwUpdate", "Other VA function"}; // Translates |function| into a human readable string for logging. @@ -398,9 +415,13 @@ } bool IsVAProfileSupported(VAProfile va_profile) { - // VAProfileJPEGBaseline is always recognized but is not a video codec per se. const auto& profiles = GetProfileCodecMap(); + // VAProfileJPEGBaseline and VAProfileProtected are always recognized but are + // not video codecs per se. return va_profile == VAProfileJPEGBaseline || +#if BUILDFLAG(IS_CHROMEOS_ASH) + va_profile == VAProfileProtected || +#endif std::find_if(profiles.begin(), profiles.end(), [va_profile](const auto& entry) { return entry.second == va_profile; @@ -717,12 +738,15 @@ va_entrypoints.resize(num_va_entrypoints); const std::vector<VAEntrypoint> kAllowedEntryPoints[] = { - {VAEntrypointVLD}, // kDecode. - {VAEntrypointEncSlice, VAEntrypointEncPicture, - VAEntrypointEncSliceLP}, // kEncode. - {VAEntrypointEncSlice, - VAEntrypointEncSliceLP}, // kEncodeConstantQuantizationParameter. - {VAEntrypointVideoProc} // kVideoProcess. + {VAEntrypointVLD}, // kDecode. +#if BUILDFLAG(IS_CHROMEOS_ASH) + {VAEntrypointVLD, VAEntrypointProtectedContent}, // kDecodeProtected. +#endif + {VAEntrypointEncSlice, VAEntrypointEncPicture, + VAEntrypointEncSliceLP}, // kEncode. + {VAEntrypointEncSlice, + VAEntrypointEncSliceLP}, // kEncodeConstantQuantizationParameter. + {VAEntrypointVideoProc} // kVideoProcess. }; static_assert(base::size(kAllowedEntryPoints) == VaapiWrapper::kCodecModeMax, ""); @@ -750,10 +774,32 @@ if (profile == VAProfileVP9Profile2 || profile == VAProfileVP9Profile3) { required_attribs->push_back( {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420_10BPP}); +#if BUILDFLAG(IS_CHROMEOS_ASH) + } else if (profile == VAProfileProtected) { + DCHECK_EQ(mode, VaapiWrapper::kDecodeProtected); + constexpr int kWidevineUsage = 0x1; + required_attribs->push_back( + {VAConfigAttribProtectedContentUsage, kWidevineUsage}); + required_attribs->push_back( + {VAConfigAttribProtectedContentCipherAlgorithm, VA_PC_CIPHER_AES}); + required_attribs->push_back( + {VAConfigAttribProtectedContentCipherBlockSize, VA_PC_BLOCK_SIZE_128}); + required_attribs->push_back( + {VAConfigAttribProtectedContentCipherMode, VA_PC_CIPHER_MODE_CTR}); + required_attribs->push_back({VAConfigAttribProtectedContentCipherSampleType, + VA_PC_SAMPLE_TYPE_FULLSAMPLE}); +#endif } else { required_attribs->push_back({VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}); } +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (mode == VaapiWrapper::kDecodeProtected && profile != VAProfileProtected) { + required_attribs->push_back( + {VAConfigAttribEncryption, VA_ENCRYPTION_TYPE_CTR_128}); + } +#endif + if (!IsModeEncoding(mode)) return true; @@ -920,9 +966,14 @@ GetSupportedVAProfiles(va_lock, va_display); constexpr VaapiWrapper::CodecMode kWrapperModes[] = { - VaapiWrapper::kDecode, VaapiWrapper::kEncode, - VaapiWrapper::kEncodeConstantQuantizationParameter, - VaapiWrapper::kVideoProcess}; + VaapiWrapper::kDecode, +#if BUILDFLAG(IS_CHROMEOS_ASH) + VaapiWrapper::kDecodeProtected, +#endif + VaapiWrapper::kEncode, + VaapiWrapper::kEncodeConstantQuantizationParameter, + VaapiWrapper::kVideoProcess + }; static_assert(base::size(kWrapperModes) == VaapiWrapper::kCodecModeMax, ""); for (VaapiWrapper::CodecMode mode : kWrapperModes) { @@ -990,6 +1041,15 @@ }, va_display, va_config_id)); +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Nothing further to query for protected profile. + if (va_profile == VAProfileProtected) { + profile_info->va_profile = va_profile; + profile_info->va_entrypoint = entrypoint; + return true; + } +#endif + // Calls vaQuerySurfaceAttributes twice. The first time is to get the number // of attributes to prepare the space and the second time is to get all // attributes. @@ -1275,6 +1335,17 @@ DVLOG(1) << "Unsupported va_profile: " << vaProfileStr(va_profile); return nullptr; } +#if BUILDFLAG(IS_CHROMEOS_ASH) + // In protected decode |mode| we need to ensure that |va_profile| is supported + // (which we verified above) and that VAProfileProtected is supported, which + // we check here. + if (mode == kDecodeProtected && + !VASupportedProfiles::Get().IsProfileSupported(mode, + VAProfileProtected)) { + LOG(ERROR) << "Protected content profile not supported"; + return nullptr; + } +#endif scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper(mode)); if (vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) { @@ -1568,6 +1639,12 @@ switch (mode) { case VaapiWrapper::kDecode: return VAEntrypointVLD; +#if BUILDFLAG(IS_CHROMEOS_ASH) + case VaapiWrapper::kDecodeProtected: + if (profile == VAProfileProtected) + return VAEntrypointProtectedContent; + return VAEntrypointVLD; +#endif case VaapiWrapper::kEncode: case VaapiWrapper::kEncodeConstantQuantizationParameter: if (profile == VAProfileJPEGBaseline) @@ -1651,6 +1728,110 @@ return nullptr; } +bool VaapiWrapper::CreateProtectedSession( + media::EncryptionScheme encryption, + bool full_sample, + const std::vector<uint8_t>& hw_config, + std::vector<uint8_t>* hw_identifier_out) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + DCHECK(hw_identifier_out); + if (mode_ != kDecodeProtected) { + LOG(ERROR) << "Cannot attached protected context if not in protected mode"; + return false; + } + if (encryption == media::EncryptionScheme::kUnencrypted) { + LOG(ERROR) << "Must specify encryption scheme for protected mode"; + return false; + } + const VAProfile va_profile = VAProfileProtected; + const VAEntrypoint entrypoint = GetDefaultVaEntryPoint(mode_, va_profile); + { + base::AutoLock auto_lock(*va_lock_); + std::vector<VAConfigAttrib> required_attribs; + if (!GetRequiredAttribs(va_lock_, va_display_, mode_, va_profile, + entrypoint, &required_attribs)) { + LOG(ERROR) << "Failed getting required attributes for protected mode"; + return false; + } + DCHECK(!required_attribs.empty()); + + // We need to adjust the attributes for encryption scheme and sample mode. + for (auto& attrib : required_attribs) { + if (attrib.type == VAConfigAttribProtectedContentCipherMode) { + attrib.value = (encryption == media::EncryptionScheme::kCbcs) + ? VA_PC_CIPHER_MODE_CBC + : VA_PC_CIPHER_MODE_CTR; + } else if (attrib.type == + VAConfigAttribProtectedContentCipherSampleType) { + attrib.value = full_sample ? VA_PC_SAMPLE_TYPE_FULLSAMPLE + : VA_PC_SAMPLE_TYPE_SUBSAMPLE; + } + } + + VAStatus va_res = vaCreateConfig( + va_display_, va_profile, entrypoint, &required_attribs[0], + required_attribs.size(), &va_protected_config_id_); + VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateConfig, false); + + va_res = vaCreateProtectedSession(va_display_, va_protected_config_id_, + &va_protected_session_id_); + VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateProtectedSession, + false); + } + // We have to hold the VABuffer outside of the lock because its destructor + // will acquire the lock when it goes out of scope. We also must do this after + // we create the protected session. + VAProtectedSessionHwUpdateBuffer hw_update_buf; + std::unique_ptr<ScopedVABuffer> hw_update = CreateVABuffer( + VAProtectedSessionHwUpdateBufferType, sizeof(hw_update_buf)); + { + base::AutoLock auto_lock(*va_lock_); + constexpr size_t kHwIdentifierMaxSize = 64; + memset(&hw_update_buf, 0, sizeof(hw_update_buf)); + hw_update_buf.input.data_size = hw_config.size(); + hw_update_buf.input.data = + static_cast<void*>(const_cast<uint8_t*>(hw_config.data())); + hw_update_buf.output.max_data_size = kHwIdentifierMaxSize; + hw_identifier_out->resize(kHwIdentifierMaxSize); + hw_update_buf.output.data = hw_identifier_out->data(); + if (!MapAndCopy_Locked( + hw_update->id(), + {hw_update->type(), hw_update->size(), &hw_update_buf})) { + LOG(ERROR) << "Failed mapping HwUpdate buf"; + return false; + } + + VAStatus va_res = vaProtectedSessionHwUpdate( + va_display_, va_protected_session_id_, hw_update->id()); + VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAProtectedSessionHwUpdate, + false); + + ScopedVABufferMapping mapping(va_lock_, va_display_, hw_update->id()); + if (!mapping.IsValid()) { + LOG(ERROR) << "Failed mapping returned HwUpdate buf"; + return false; + } + auto* hw_update_buf_out = + reinterpret_cast<VAProtectedSessionHwUpdateBuffer*>(mapping.data()); + if (!hw_update_buf_out->output.data_size) { + LOG(ERROR) << "Received empty HW identifier"; + return false; + } + hw_identifier_out->resize(hw_update_buf_out->output.data_size); + memcpy(hw_identifier_out->data(), hw_update_buf_out->output.data, + hw_update_buf_out->output.data_size); + + // If the decoding context is created, attach the protected session. + // Otherwise this is done in CreateContext when the decoding context is + // created. + return MaybeAttachProtectedSession_Locked(); + } +#else + NOTIMPLEMENTED() << "Protected content mode not supported"; + return false; +#endif +} + void VaapiWrapper::DestroyContextAndSurfaces( std::vector<VASurfaceID> va_surfaces) { DestroyContext(); @@ -1672,16 +1853,19 @@ // vpp, just passing 0x0. const int flag = mode_ != kVideoProcess ? VA_PROGRESSIVE : 0x0; const gfx::Size picture_size = mode_ != kVideoProcess ? size : gfx::Size(); - const VAStatus va_res = vaCreateContext( + VAStatus va_res = vaCreateContext( va_display_, va_config_id_, picture_size.width(), picture_size.height(), flag, empty_va_surfaces_ids_pointer, empty_va_surfaces_ids_size, &va_context_id_); VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVACreateContext); + if (va_res != VA_STATUS_SUCCESS) + return false; if (IsModeEncoding(mode_) && IsLowPowerIntelProcessor()) MaybeSetLowQualityEncoding_Locked(); - return va_res == VA_STATUS_SUCCESS; + // If we have a protected session already, attach it to this new context. + return MaybeAttachProtectedSession_Locked(); } scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap( @@ -2080,9 +2264,17 @@ TRACE_EVENT0("media,gpu", "VaapiWrapper::CreateVABuffer"); base::AutoLock auto_lock(*va_lock_); TRACE_EVENT0("media,gpu", "VaapiWrapper::CreateVABufferLocked"); +#if BUILDFLAG(IS_CHROMEOS_ASH) + VAContextID context_id = type == VAProtectedSessionHwUpdateBufferType + ? va_protected_session_id_ + : va_context_id_; +#else + VAContextID context_id = va_context_id_; +#endif - return ScopedVABuffer::Create(va_lock_, va_display_, va_context_id_, type, - size); + if (context_id == VA_INVALID_ID) + return nullptr; + return ScopedVABuffer::Create(va_lock_, va_display_, context_id, type, size); } uint64_t VaapiWrapper::GetEncodedChunkSize(VABufferID buffer_id, @@ -2287,6 +2479,9 @@ if (!features::IsUsingOzonePlatform()) paths[kModuleVa_x11].push_back(std::string("libva-x11.so.") + va_suffix); #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) + paths[kModuleVa_prot].push_back(std::string("libva.so.") + va_suffix); +#endif // InitializeStubs dlopen() VA-API libraries // libva.so @@ -2316,8 +2511,6 @@ : mode_(mode), va_lock_(VADisplayState::Get()->va_lock()), va_display_(NULL), - va_config_id_(VA_INVALID_ID), - va_context_id_(VA_INVALID_ID), va_profile_(VAProfileNone), va_entrypoint_(kVAEntrypointInvalid) {} @@ -2361,10 +2554,23 @@ void VaapiWrapper::Deinitialize() { { base::AutoLock auto_lock(*va_lock_); - if (va_config_id_ != VA_INVALID_ID) { - VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (va_protected_session_id_ != VA_INVALID_ID) { + VAStatus va_res = + vaDestroyProtectedSession(va_display_, va_protected_session_id_); + VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyProtectedSession); + va_res = vaDestroyConfig(va_display_, va_protected_config_id_); VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyConfig); } +#endif + if (va_config_id_ != VA_INVALID_ID) { + const VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); + VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyConfig); + } +#if BUILDFLAG(IS_CHROMEOS_ASH) + va_protected_session_id_ = VA_INVALID_ID; + va_protected_config_id_ = VA_INVALID_ID; +#endif va_config_id_ = VA_INVALID_ID; va_display_ = nullptr; } @@ -2392,6 +2598,13 @@ DVLOG(2) << "Destroying context"; if (va_context_id_ != VA_INVALID_ID) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (va_protected_session_id_ != VA_INVALID_ID) { + const VAStatus va_res = + vaDetachProtectedSession(va_display_, va_context_id_); + VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADetachProtectedSession); + } +#endif const VAStatus va_res = vaDestroyContext(va_display_, va_context_id_); VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyContext); } @@ -2617,4 +2830,21 @@ << enc_quality->quality_level; } +bool VaapiWrapper::MaybeAttachProtectedSession_Locked() { + va_lock_->AssertAcquired(); + if (va_context_id_ == VA_INVALID_ID) + return true; +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (va_protected_session_id_ == VA_INVALID_ID) + return true; + + VAStatus va_res = vaAttachProtectedSession(va_display_, va_context_id_, + va_protected_session_id_); + VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVAAttachProtectedSession); + return va_res == VA_STATUS_SUCCESS; +#else + return true; +#endif +} + } // namespace media
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h index 971f673..01ec582 100644 --- a/media/gpu/vaapi/vaapi_wrapper.h +++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -109,6 +109,17 @@ public: enum CodecMode { kDecode, +#if BUILDFLAG(IS_CHROMEOS_ASH) + // NOTE: A kDecodeProtected VaapiWrapper is created using the actual video + // profile and an extra VAProfileProtected, each with some special added + // VAConfigAttribs. Then when CreateProtectedSession() is called, it will + // then create a protected session using protected profile & entrypoint + // which gets attached to the decoding context (or attached when the + // decoding context is created or re-created). This then enables + // decrypt + decode support in the driver and encrypted frame data can then + // be submitted. + kDecodeProtected, // Decrypt + decode to protected surface. +#endif kEncode, // Encode with Constant Bitrate algorithm. kEncodeConstantQuantizationParameter, // Encode with Constant Quantization // Parameter algorithm. @@ -250,13 +261,29 @@ const gfx::Size& size, const base::Optional<gfx::Size>& visible_size = base::nullopt); + // Attempts to create a protected session that will be attached to the + // decoding context to enable encrypted video decoding. If it cannot be + // attached now, it will be attached when the decoding context is created or + // re-created. |encryption| should be the encryption scheme from the + // DecryptConfig, |full_sample| should be true if full sample (i.e. CENC v1) + // encryption is used. |hw_config| should have been obtained from the + // OEMCrypto implementation via the CdmFactoryDaemonProxy. |hw_identifier_out| + // is an output parameter which will return session specific information which + // can be passed through the ChromeOsCdmContext to retrieve encrypted key + // information. Returns true on success and false otherwise. + bool CreateProtectedSession(media::EncryptionScheme encryption, + bool full_sample, + const std::vector<uint8_t>& hw_config, + std::vector<uint8_t>* hw_identifier_out); + // Releases the |va_surfaces| and destroys |va_context_id_|. void DestroyContextAndSurfaces(std::vector<VASurfaceID> va_surfaces); // Creates a VAContextID of |size| (unless it's a Vpp context in which case // |size| is ignored and 0x0 is used instead). The client is responsible for // releasing said context via DestroyContext() or DestroyContextAndSurfaces(), - // or it will be released on dtor. + // or it will be released on dtor. If a valid |va_protected_session_id_| + // exists, it will be attached to the newly created |va_context_id_| as well. virtual bool CreateContext(const gfx::Size& size) WARN_UNUSED_RESULT; // Destroys the context identified by |va_context_id_|. @@ -476,6 +503,10 @@ // consumption and maximum speed. void MaybeSetLowQualityEncoding_Locked() EXCLUSIVE_LOCKS_REQUIRED(va_lock_); + // If a protected session is active, attaches it to the decoding context. + bool MaybeAttachProtectedSession_Locked() + EXCLUSIVE_LOCKS_REQUIRED(va_lock_) WARN_UNUSED_RESULT; + const CodecMode mode_; // Pointer to VADisplayState's member |va_lock_|. Guaranteed to be valid for @@ -485,10 +516,10 @@ // VA handles. // All valid after successful Initialize() and until Deinitialize(). VADisplay va_display_ GUARDED_BY(va_lock_); - VAConfigID va_config_id_; + VAConfigID va_config_id_{VA_INVALID_ID}; // Created in CreateContext() or CreateContextAndSurfaces() and valid until // DestroyContext() or DestroyContextAndSurfaces(). - VAContextID va_context_id_; + VAContextID va_context_id_{VA_INVALID_ID}; // Profile and entrypoint configured for the corresponding |va_context_id_|. VAProfile va_profile_; @@ -502,6 +533,12 @@ // and reused afterwards. std::unique_ptr<ScopedVABuffer> va_buffer_for_vpp_; +#if BUILDFLAG(IS_CHROMEOS_ASH) + // For protected decode mode. + VAConfigID va_protected_config_id_{VA_INVALID_ID}; + VAProtectedSessionID va_protected_session_id_{VA_INVALID_ID}; +#endif + // Called to report codec errors to UMA. Errors to clients are reported via // return values from public methods. ReportErrorToUMACB report_error_to_uma_cb_;
diff --git a/remoting/BUILD.gn b/remoting/BUILD.gn index ceb99d97..d539206 100644 --- a/remoting/BUILD.gn +++ b/remoting/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//remoting/build/config/remoting_build.gni") group("remoting_all") { @@ -40,7 +41,7 @@ "//remoting/host", ] - if (!is_chromeos && !is_android) { + if (!is_chromeos_ash && !is_android) { deps += [ "//remoting/host:remoting_native_messaging_manifests", "//remoting/host:remoting_start_host", @@ -52,11 +53,11 @@ } } - if (is_win || (!is_chromeos && !is_android && !is_ios)) { + if (is_win || (!is_chromeos_ash && !is_android && !is_ios)) { deps += [ "//remoting/host:remoting_native_messaging_host" ] } - if (is_linux && !is_chromeos) { + if (is_linux || is_chromeos_lacros) { deps += [ "//remoting/host/linux:remoting_dev_me2me_host", "//remoting/host/linux:remoting_user_session", @@ -176,7 +177,8 @@ ] } - if (!is_chromeos) { + # TODO(crbug.com/1052397): Change to !is_chromeos once lacros-chrome is switched to target_os=chromeos. + if (!is_chromeos_ash) { deps += [ "//remoting/client/display:unit_tests" ] } }
diff --git a/remoting/base/BUILD.gn b/remoting/base/BUILD.gn index 12e15e3..b2561a05c 100644 --- a/remoting/base/BUILD.gn +++ b/remoting/base/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//third_party/protobuf/proto_library.gni") proto_library("protobuf_http_client_messages_proto") { @@ -90,6 +91,7 @@ deps = [ ":protobuf_http_client_messages_proto", "//base/third_party/dynamic_annotations", + "//build:chromeos_buildflags", "//google_apis", "//remoting/proto/remoting/v1:directory_proto", "//remoting/proto/remoting/v1:telemetry_messages", @@ -233,7 +235,7 @@ "//third_party/webrtc_overrides:webrtc_component", ] - if (is_win || is_mac || is_chromeos) { + if (is_win || is_mac || is_chromeos_ash) { deps += [ "//third_party/breakpad:client" ] }
diff --git a/remoting/base/chromoting_event.cc b/remoting/base/chromoting_event.cc index 2836fa8..6d162ae 100644 --- a/remoting/base/chromoting_event.cc +++ b/remoting/base/chromoting_event.cc
@@ -7,6 +7,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringize_macros.h" #include "base/system/sys_info.h" +#include "build/chromeos_buildflags.h" #include "remoting/base/name_value_map.h" namespace remoting { @@ -190,7 +191,7 @@ SetString(kWebAppVersionKey, STRINGIZE(VERSION)); #if defined(OS_LINUX) || defined(OS_CHROMEOS) Os os = Os::CHROMOTING_LINUX; -#elif defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_CHROMEOS_ASH) Os os = Os::CHROMOTING_CHROMEOS; #elif defined(OS_IOS) Os os = Os::CHROMOTING_IOS;
diff --git a/remoting/client/BUILD.gn b/remoting/client/BUILD.gn index 4f4d76b6a..47cf90f 100644 --- a/remoting/client/BUILD.gn +++ b/remoting/client/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") + static_library("client") { sources = [ "chromoting_client.cc", @@ -66,7 +68,7 @@ libs = [] - if (!is_chromeos) { + if (!is_chromeos_ash) { # GestureInterpreter depends on //remoting/client/display, which currently # doesn't build on CrOS. crbug.com/869578 sources += [
diff --git a/remoting/client/ui/BUILD.gn b/remoting/client/ui/BUILD.gn index 7362f64..82cb2fc 100644 --- a/remoting/client/ui/BUILD.gn +++ b/remoting/client/ui/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") + source_set("ui") { sources = [ "fling_animation.cc", @@ -20,7 +22,7 @@ "//third_party/webrtc_overrides:webrtc_component", ] - if (!is_chromeos) { + if (!is_chromeos_ash) { deps += [ "//remoting/client/display" ] } }
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn index c44741d..2b2a652 100644 --- a/remoting/host/BUILD.gn +++ b/remoting/host/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//build/config/python.gni") import("//build/util/process_version.gni") import("//remoting/build/config/remoting_build.gni") @@ -24,7 +25,7 @@ deps += [ ":remoting_host_branded" ] } - if (!is_chromeos && !is_android && !is_ios) { + if (!is_chromeos_ash && !is_android && !is_ios) { deps += [ "//remoting/host:remoting_native_messaging_host", "//remoting/host:remoting_native_messaging_manifests", @@ -269,6 +270,7 @@ ":base", "//base:i18n", "//build:branding_buildflags", + "//build:chromeos_buildflags", "//components/policy/core/common", "//crypto", "//google_apis", @@ -309,13 +311,13 @@ deps += [ "//components/policy:generated" ] } - if (is_linux && !is_chromeos) { + if (is_linux || is_chromeos_lacros) { sources += [ "desktop_resizer_linux.cc" ] public_deps += [ "//remoting/host/linux" ] libs += [ "pam" ] } - if (use_x11 && (!is_chromeos || !use_ozone)) { + if (use_x11 && (!is_chromeos_ash || !use_ozone)) { sources += [ "clipboard_x11.cc", "desktop_resizer_x11.cc", @@ -327,12 +329,12 @@ "//ui/events/platform/x11", "//ui/gfx/x", ] - if (is_linux) { + if (is_linux || is_chromeos_lacros) { deps += [ "//build/config/linux/gtk" ] } } - if (use_ozone && !is_chromeos) { + if (use_ozone && !is_chromeos_ash) { sources += [ "desktop_resizer_ozone.cc", "desktop_resizer_ozone.h", @@ -347,7 +349,7 @@ ] } - if (is_linux && !is_chromeos) { + if (is_linux || is_chromeos_lacros) { sources += [ "audio_capturer_linux.cc", "audio_capturer_linux.h", @@ -359,7 +361,7 @@ ] } - if (is_chromeos) { + if (is_chromeos_ash) { sources += [ "audio_capturer_chromeos.cc", "continue_window_chromeos.cc", @@ -531,7 +533,7 @@ "zombie_host_detector_unittest.cc", ] - if (use_ozone || is_chromeos) { + if (use_ozone || is_chromeos_ash) { sources -= [ "input_monitor/local_input_monitor_unittest.cc" ] } @@ -541,6 +543,7 @@ ":common", ":test_support", "//build:branding_buildflags", + "//build:chromeos_buildflags", "//remoting/host/file_transfer:unit_tests", "//remoting/host/it2me:common", "//remoting/host/native_messaging", @@ -557,11 +560,11 @@ sources += [ "pairing_registry_delegate_linux_unittest.cc" ] } - if (is_linux && !is_chromeos) { + if (is_linux || is_chromeos_lacros) { deps += [ "//remoting/host/linux:unit_tests" ] } - if (is_chromeos) { + if (is_chromeos_ash) { deps += [ "//remoting/host/chromeos:unit_tests", "//remoting/host/linux", # for AudioPipeReader @@ -761,10 +764,10 @@ deps += [ "//components/policy:generated" ] } - if (is_linux) { + if (is_linux || is_chromeos_lacros) { deps += [ "//build/config/linux/gtk" ] } - if ((is_linux && !is_chromeos) || is_mac) { + if (is_linux || is_chromeos_lacros || is_mac) { libs = [ "pam" ] } @@ -824,7 +827,8 @@ } } } - if (is_chrome_branded && enable_me2me_host && is_linux && !is_chromeos) { + if (is_chrome_branded && enable_me2me_host && + (is_linux || is_chromeos_lacros)) { group("remoting_me2me_host_archive") { deps = [ "//remoting/host/installer/linux:remoting_me2me_host_archive" ] }
diff --git a/remoting/host/chromeos/BUILD.gn b/remoting/host/chromeos/BUILD.gn index 963db80..54d28ce7 100644 --- a/remoting/host/chromeos/BUILD.gn +++ b/remoting/host/chromeos/BUILD.gn
@@ -22,6 +22,7 @@ public_deps = [ "//ash", + "//build:chromeos_buildflags", "//cc", "//gpu/command_buffer/common", "//ppapi/host",
diff --git a/remoting/host/chromeos/aura_desktop_capturer.cc b/remoting/host/chromeos/aura_desktop_capturer.cc index 7b937b3..c2239b8 100644 --- a/remoting/host/chromeos/aura_desktop_capturer.cc +++ b/remoting/host/chromeos/aura_desktop_capturer.cc
@@ -7,13 +7,14 @@ #include <utility> #include "base/bind.h" +#include "build/chromeos_buildflags.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" #include "remoting/host/chromeos/skia_bitmap_desktop_frame.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/shell.h" #endif @@ -25,7 +26,7 @@ AuraDesktopCapturer::~AuraDesktopCapturer() = default; void AuraDesktopCapturer::Start(webrtc::DesktopCapturer::Callback* callback) { -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) if (ash::Shell::HasInstance()) { // TODO(kelvinp): Use ash::Shell::GetAllRootWindows() when multiple monitor // support is implemented.
diff --git a/remoting/host/chromoting_host_context.cc b/remoting/host/chromoting_host_context.cc index 156d7d32..7f0f6e28 100644 --- a/remoting/host/chromoting_host_context.cc +++ b/remoting/host/chromoting_host_context.cc
@@ -11,6 +11,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "remoting/base/auto_thread.h" #include "remoting/base/url_request_context_getter.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -150,7 +151,7 @@ base::MakeRefCounted<URLRequestContextGetter>(network_task_runner))); } -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) // static std::unique_ptr<ChromotingHostContext> ChromotingHostContext::CreateForChromeOS( @@ -182,6 +183,6 @@ AutoThread::Create("ChromotingEncodeThread", file_auto_task_runner), base::MakeRefCounted<URLRequestContextGetter>(io_auto_task_runner))); } -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } // namespace remoting
diff --git a/remoting/host/chromoting_host_context.h b/remoting/host/chromoting_host_context.h index e860c339..901f59af 100644 --- a/remoting/host/chromoting_host_context.h +++ b/remoting/host/chromoting_host_context.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" namespace base { class SingleThreadTaskRunner; @@ -39,7 +40,7 @@ static std::unique_ptr<ChromotingHostContext> Create( scoped_refptr<AutoThreadTaskRunner> ui_task_runner); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) // Attaches task runners to the relevant browser threads for the chromoting // host. Must be called on the UI thread of the browser process. // remoting::UrlRequestContextGetter returns ContainerURLRequestContext under @@ -53,7 +54,7 @@ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, scoped_refptr<base::SingleThreadTaskRunner> file_task_runner); -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) ~ChromotingHostContext();
diff --git a/remoting/host/desktop_capturer_proxy.cc b/remoting/host/desktop_capturer_proxy.cc index cc446146..3265907b 100644 --- a/remoting/host/desktop_capturer_proxy.cc +++ b/remoting/host/desktop_capturer_proxy.cc
@@ -16,6 +16,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "remoting/host/client_session_control.h" #include "remoting/proto/control.pb.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" @@ -24,7 +25,7 @@ #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) #include "remoting/host/chromeos/aura_desktop_capturer.h" #endif @@ -75,12 +76,12 @@ DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!capturer_); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) capturer_ = std::make_unique<webrtc::DesktopCapturerDifferWrapper>( std::make_unique<AuraDesktopCapturer>()); -#else // !defined(OS_CHROMEOS) +#else // !BUILDFLAG(IS_CHROMEOS_ASH) capturer_ = webrtc::DesktopCapturer::CreateScreenCapturer(options); -#endif // !defined(OS_CHROMEOS) +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) if (!capturer_) LOG(ERROR) << "Failed to initialize screen capturer."; }
diff --git a/remoting/host/file_transfer/BUILD.gn b/remoting/host/file_transfer/BUILD.gn index 1733248..f385d32e 100644 --- a/remoting/host/file_transfer/BUILD.gn +++ b/remoting/host/file_transfer/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//remoting/build/config/remoting_build.gni") source_set("file_transfer") { @@ -39,12 +40,12 @@ sources += [ "get_desktop_directory.cc" ] } - if (is_linux) { + if (is_linux || is_chromeos_lacros) { sources += [ "file_chooser_linux.cc" ] deps += [ "//build/config/linux/gtk" ] } - if (is_chromeos) { + if (is_chromeos_ash) { sources += [ "file_chooser_chromeos.cc" ] } }
diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc index 647277ec..cf17cb2 100644 --- a/remoting/host/heartbeat_sender.cc +++ b/remoting/host/heartbeat_sender.cc
@@ -16,6 +16,7 @@ #include "base/system/sys_info.h" #include "base/time/time.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "net/base/network_interfaces.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "remoting/base/constants.h" @@ -385,7 +386,9 @@ heartbeat->set_is_initial_heartbeat(!initial_heartbeat_sent_); // Only set the hostname if the user's email is @google.com and they are using // a Linux OS. -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch +// of lacros-chrome is complete. +#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) if (is_googler_) { heartbeat->set_hostname(net::GetHostName()); }
diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 4c236bf..b418a2e 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc
@@ -18,6 +18,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "remoting/base/fake_oauth_token_getter.h" #include "remoting/base/protobuf_http_status.h" #include "remoting/signaling/fake_signal_strategy.h" @@ -73,7 +74,9 @@ ASSERT_TRUE(request->has_host_cpu_type()); ASSERT_EQ(expected_is_initial_heartbeat, request->is_initial_heartbeat()); bool is_linux = false; -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch +// of lacros-chrome is complete. +#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) is_linux = true; #endif if (is_googler && is_linux) {
diff --git a/remoting/host/host_details.cc b/remoting/host/host_details.cc index ad0f711..9e9cdff 100644 --- a/remoting/host/host_details.cc +++ b/remoting/host/host_details.cc
@@ -6,6 +6,7 @@ #include "base/system/sys_info.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #if defined(OS_LINUX) || defined(OS_CHROMEOS) #include "base/linux_util.h" @@ -20,9 +21,9 @@ return "Windows"; #elif defined(OS_APPLE) return "Mac"; -#elif defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_CHROMEOS_ASH) return "ChromeOS"; -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) return "Linux"; #elif defined(OS_ANDROID) return "Android";
diff --git a/remoting/host/input_injector_x11.cc b/remoting/host/input_injector_x11.cc index aefe86bd..5706d35 100644 --- a/remoting/host/input_injector_x11.cc +++ b/remoting/host/input_injector_x11.cc
@@ -19,6 +19,7 @@ #include "base/strings/utf_string_conversion_utils.h" #include "base/time/time.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "remoting/base/logging.h" #include "remoting/host/clipboard.h" #include "remoting/host/linux/unicode_to_keysym.h" @@ -35,7 +36,7 @@ #include "ui/gfx/x/xproto.h" #include "ui/gfx/x/xtest.h" -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) #include "remoting/host/chromeos/point_transformer.h" #endif @@ -174,7 +175,7 @@ int pointer_button_map_[kNumPointerButtons]; -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) PointTransformer point_transformer_; #endif @@ -457,7 +458,7 @@ // apps which assume MotionNotify implies movement. See crbug.com/138075. bool inject_motion = true; webrtc::DesktopVector new_mouse_position(event.x(), event.y()); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) // Interim hack to handle display rotation on Chrome OS. // TODO(kelvin): Remove this when Chrome OS has completely migrated to // Ozone (crbug.com/439287).
diff --git a/remoting/host/input_monitor/BUILD.gn b/remoting/host/input_monitor/BUILD.gn index ffd195a..bf91265 100644 --- a/remoting/host/input_monitor/BUILD.gn +++ b/remoting/host/input_monitor/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//remoting/build/config/remoting_build.gni") source_set("input_monitor") { @@ -33,7 +34,7 @@ deps += [ "//third_party/google_toolbox_for_mac" ] } - if (use_x11 && (!is_chromeos || use_ozone)) { + if (use_x11 && (!is_chromeos_ash || use_ozone)) { sources += [ "local_hotkey_input_monitor_x11.cc", "local_keyboard_input_monitor_x11.cc", @@ -51,7 +52,7 @@ ] } - if (is_chromeos) { + if (is_chromeos_ash) { sources += [ "local_hotkey_input_monitor_chromeos.cc", "local_keyboard_input_monitor_chromeos.cc",
diff --git a/remoting/host/it2me/BUILD.gn b/remoting/host/it2me/BUILD.gn index bf3679c..e266c021 100644 --- a/remoting/host/it2me/BUILD.gn +++ b/remoting/host/it2me/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//build/config/features.gni") import("//build/config/ui.gni") import("//remoting/remoting_locales.gni") @@ -27,11 +28,11 @@ "it2me_native_messaging_host.h", ] - if (is_linux && !is_chromeos) { + if (is_linux || is_chromeos_lacros) { sources += [ "it2me_confirmation_dialog_linux.cc" ] } - if (is_chromeos) { + if (is_chromeos_ash) { sources += [ "it2me_confirmation_dialog_chromeos.cc" ] } @@ -50,6 +51,7 @@ deps = [ "//base:i18n", + "//build:chromeos_buildflags", "//mojo/core/embedder", "//net", "//remoting/base", @@ -58,7 +60,7 @@ "//remoting/resources", "//remoting/signaling", ] - if (is_linux) { + if (is_linux || is_chromeos_lacros) { deps += [ "//build/config/linux/gtk", @@ -70,7 +72,7 @@ } } -if (is_chromeos) { +if (is_chromeos_ash) { source_set("chrome_os_host") { sources = [ "it2me_native_messaging_host_chromeos.cc", @@ -88,7 +90,7 @@ } } -if (!is_chromeos && enable_remoting_host) { +if (!is_chromeos_ash && enable_remoting_host) { if (is_win) { executable("remote_assistance_host") { configs += [ "//build/config/compiler:wexit_time_destructors" ] @@ -234,7 +236,7 @@ } } - if (is_linux) { + if (is_linux || is_chromeos_lacros) { deps += [ "//build/config/linux/gtk" ] } }
diff --git a/remoting/host/it2me/it2me_host.cc b/remoting/host/it2me/it2me_host.cc index f390ef4..47dc547 100644 --- a/remoting/host/it2me/it2me_host.cc +++ b/remoting/host/it2me/it2me_host.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" +#include "build/chromeos_buildflags.h" #include "components/policy/policy_constants.h" #include "net/url_request/url_request_context_getter.h" #include "remoting/base/auto_thread.h" @@ -68,7 +69,7 @@ } void It2MeHost::set_enable_dialogs(bool enable) { -#if defined(OS_CHROMEOS) || !defined(NDEBUG) +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) enable_dialogs_ = enable; #else NOTREACHED() << "It2MeHost::set_enable_dialogs is only supported on ChromeOS"; @@ -76,7 +77,7 @@ } void It2MeHost::set_enable_notifications(bool enable) { -#if defined(OS_CHROMEOS) || !defined(NDEBUG) +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) enable_notifications_ = enable; #else NOTREACHED() << "It2MeHost::set_enable_notifications is only supported on " @@ -85,7 +86,7 @@ } void It2MeHost::set_terminate_upon_input(bool terminate_upon_input) { -#if defined(OS_CHROMEOS) || !defined(NDEBUG) +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) terminate_upon_input_ = terminate_upon_input; #else NOTREACHED()
diff --git a/remoting/host/it2me/it2me_host_unittest.cc b/remoting/host/it2me/it2me_host_unittest.cc index 3928b81d..b440fa9d 100644 --- a/remoting/host/it2me/it2me_host_unittest.cc +++ b/remoting/host/it2me/it2me_host_unittest.cc
@@ -17,6 +17,7 @@ #include "base/run_loop.h" #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" +#include "build/chromeos_buildflags.h" #include "components/policy/policy_constants.h" #include "net/base/network_change_notifier.h" #include "remoting/base/auto_thread_task_runner.h" @@ -738,7 +739,7 @@ ASSERT_EQ(It2MeHostState::kDisconnected, last_host_state_); } -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(It2MeHostTest, ConnectRespectsSuppressDialogsParameter) { StartHost(false); EXPECT_FALSE(dialog_factory_->dialog_created());
diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc index 91a5a32b..34e50ef 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.cc +++ b/remoting/host/it2me/it2me_native_messaging_host.cc
@@ -20,6 +20,7 @@ #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "components/policy/policy_constants.h" #include "net/base/url_util.h" #include "net/socket/client_socket_factory.h" @@ -175,11 +176,11 @@ void It2MeNativeMessagingHost::Start(Client* client) { DCHECK(task_runner()->BelongsToCurrentThread()); client_ = client; -#if !defined(OS_CHROMEOS) +#if !BUILDFLAG(IS_CHROMEOS_ASH) log_message_handler_ = std::make_unique<LogMessageHandler>( base::BindRepeating(&It2MeNativeMessagingHost::SendMessageToClient, base::Unretained(this))); -#endif // !defined(OS_CHROMEOS) +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) } void It2MeNativeMessagingHost::SendMessageToClient( @@ -336,7 +337,7 @@ // Create the It2Me host and start connecting. Note that disabling dialogs is // only supported on ChromeOS. it2me_host_ = factory_->CreateIt2MeHost(); -#if defined(OS_CHROMEOS) || !defined(NDEBUG) +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) it2me_host_->set_enable_dialogs(!suppress_user_dialogs); it2me_host_->set_enable_notifications(!suppress_notifications); it2me_host_->set_terminate_upon_input(terminate_upon_input);
diff --git a/remoting/host/it2me/it2me_native_messaging_host.h b/remoting/host/it2me/it2me_native_messaging_host.h index 85ccfce..8890419 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.h +++ b/remoting/host/it2me/it2me_native_messaging_host.h
@@ -12,12 +12,13 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "extensions/browser/api/messaging/native_message_host.h" #include "remoting/host/it2me/it2me_host.h" #include "remoting/protocol/errors.h" #include "remoting/signaling/delegating_signal_strategy.h" -#if !defined(OS_CHROMEOS) +#if !BUILDFLAG(IS_CHROMEOS_ASH) #include "remoting/host/native_messaging/log_message_handler.h" #endif @@ -72,7 +73,7 @@ static std::string HostStateToString(It2MeHostState host_state); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) // Creates native messaging host on ChromeOS. Must be called on the UI thread // of the browser process. static std::unique_ptr<extensions::NativeMessageHost> CreateForChromeOS( @@ -80,7 +81,7 @@ scoped_refptr<base::SingleThreadTaskRunner> io_runnner, scoped_refptr<base::SingleThreadTaskRunner> ui_runnner, policy::PolicyService* policy_service); -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) private: // These "Process.." methods handle specific request types. The |response| @@ -135,7 +136,7 @@ std::unique_ptr<It2MeHostFactory> factory_; scoped_refptr<It2MeHost> it2me_host_; -#if !defined(OS_CHROMEOS) +#if !BUILDFLAG(IS_CHROMEOS_ASH) // Don't install a log message handler on ChromeOS because we run in the // browser process and don't want to intercept all its log messages. std::unique_ptr<LogMessageHandler> log_message_handler_;
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc index b2794da..f66c33c 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -23,6 +23,7 @@ #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" +#include "build/chromeos_buildflags.h" #include "components/policy/core/common/fake_async_policy_loader.h" #include "components/policy/core/common/mock_policy_service.h" #include "components/policy/policy_constants.h" @@ -658,7 +659,7 @@ connect_message.SetBoolean("suppressUserDialogs", true); WriteMessageToInputPipe(connect_message); VerifyConnectResponses(next_id); -#if defined(OS_CHROMEOS) || !defined(NDEBUG) +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) EXPECT_FALSE(factory_raw_ptr_->host->enable_dialogs()); #else EXPECT_TRUE(factory_raw_ptr_->host->enable_dialogs()); @@ -675,7 +676,7 @@ connect_message.SetBoolean("suppressNotifications", true); WriteMessageToInputPipe(connect_message); VerifyConnectResponses(next_id); -#if defined(OS_CHROMEOS) || !defined(NDEBUG) +#if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG) EXPECT_FALSE(factory_raw_ptr_->host->enable_notifications()); #else EXPECT_TRUE(factory_raw_ptr_->host->enable_notifications());
diff --git a/remoting/host/linux/BUILD.gn b/remoting/host/linux/BUILD.gn index 95d6e764..4d29838 100644 --- a/remoting/host/linux/BUILD.gn +++ b/remoting/host/linux/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/c++/c++.gni") +import("//build/config/chromeos/ui_mode.gni") import("//remoting/build/config/remoting_build.gni") group("all_tests") { @@ -79,7 +80,7 @@ if (use_x11) { deps += [ ":x11" ] } - if (is_linux) { + if (is_linux || is_chromeos_lacros) { deps += [ "//build/config/linux/gtk" ] } } @@ -114,6 +115,7 @@ deps = [ "//base", + "//build:chromeos_buildflags", "//net", "//remoting/base:breakpad", "//remoting/host",
diff --git a/remoting/host/mouse_cursor_monitor_proxy.cc b/remoting/host/mouse_cursor_monitor_proxy.cc index 176fe7d..dbcd691 100644 --- a/remoting/host/mouse_cursor_monitor_proxy.cc +++ b/remoting/host/mouse_cursor_monitor_proxy.cc
@@ -10,12 +10,13 @@ #include "base/macros.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "build/chromeos_buildflags.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h" #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h" -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) #include "remoting/host/chromeos/mouse_cursor_monitor_aura.h" #endif @@ -63,12 +64,12 @@ const webrtc::DesktopCaptureOptions& options) { DCHECK(thread_checker_.CalledOnValidThread()); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) mouse_cursor_monitor_.reset(new MouseCursorMonitorAura()); -#else // defined(OS_CHROMEOS) +#else // BUILDFLAG(IS_CHROMEOS_ASH) mouse_cursor_monitor_.reset(webrtc::MouseCursorMonitor::CreateForScreen( options, webrtc::kFullDesktopScreenId)); -#endif // defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) if (!mouse_cursor_monitor_) LOG(ERROR) << "Failed to initialize MouseCursorMonitor."; }
diff --git a/remoting/host/policy_watcher.cc b/remoting/host/policy_watcher.cc index e0e7116..550f0b0 100644 --- a/remoting/host/policy_watcher.cc +++ b/remoting/host/policy_watcher.cc
@@ -18,6 +18,7 @@ #include "base/single_thread_task_runner.h" #include "base/values.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "components/policy/core/common/async_policy_loader.h" #include "components/policy/core/common/async_policy_provider.h" #include "components/policy/core/common/policy_namespace.h" @@ -181,7 +182,7 @@ result->SetString(key::kRemoteAccessHostUdpPortRange, ""); result->SetBoolean(key::kRemoteAccessHostAllowUiAccessForRemoteAssistance, false); -#if !defined(OS_CHROMEOS) +#if !BUILDFLAG(IS_CHROMEOS_ASH) result->SetBoolean(key::kRemoteAccessHostAllowFileTransfer, true); result->SetBoolean(key::kRemoteAccessHostEnableUserInterface, true); #endif @@ -421,7 +422,7 @@ return base::WrapUnique(new PolicyWatcher( owned_policy_service.get(), std::move(owned_policy_service), nullptr, CreateSchemaRegistry())); -#elif defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_CHROMEOS_ASH) NOTREACHED() << "CreateWithPolicyService() should be used on ChromeOS."; return nullptr; #else
diff --git a/remoting/host/policy_watcher_unittest.cc b/remoting/host/policy_watcher_unittest.cc index 1b7e726e2..2138117f 100644 --- a/remoting/host/policy_watcher_unittest.cc +++ b/remoting/host/policy_watcher_unittest.cc
@@ -15,6 +15,7 @@ #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "components/policy/core/common/fake_async_policy_loader.h" #include "components/policy/policy_constants.h" #include "testing/gmock/include/gmock/gmock.h" @@ -318,7 +319,7 @@ dict.SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true); dict.SetBoolean(key::kRemoteAccessHostAllowUiAccessForRemoteAssistance, false); -#if !defined(OS_CHROMEOS) +#if !BUILDFLAG(IS_CHROMEOS_ASH) dict.SetBoolean(key::kRemoteAccessHostAllowFileTransfer, true); dict.SetBoolean(key::kRemoteAccessHostEnableUserInterface, true); #endif @@ -531,7 +532,7 @@ "RemoteAccessHostdomain", "RemoteAccessHostPolicyForFutureVersion")); -#if !defined(OS_CHROMEOS) +#if !BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(PolicyWatcherTest, PairingFalseThenTrue) { testing::InSequence sequence; EXPECT_CALL(mock_policy_callback_, @@ -561,7 +562,7 @@ SetPolicies(gnubby_auth_false_); SetPolicies(gnubby_auth_true_); } -#endif // !defined(OS_CHROMEOS) +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(PolicyWatcherTest, RemoteAssistanceUiAccess) { testing::InSequence sequence; @@ -598,7 +599,7 @@ SetPolicies(relay_true_); } -#if !defined(OS_CHROMEOS) +#if !BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(PolicyWatcherTest, Curtain) { testing::InSequence sequence; EXPECT_CALL(mock_policy_callback_, @@ -665,7 +666,7 @@ SetPolicies(third_party_auth_partial_); SetPolicies(third_party_auth_full_); } -#endif // !defined(OS_CHROMEOS) +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(PolicyWatcherTest, UdpPortRange) { testing::InSequence sequence; @@ -698,7 +699,7 @@ // RemoteAccessHostMatchUsername is marked in policy_templates.json as not // supported on Windows and therefore is (by design) excluded from the schema. expected_schema.erase(key::kRemoteAccessHostMatchUsername); -#elif defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_CHROMEOS_ASH) // Me2Me Policies are not supported on ChromeOS. expected_schema.erase(key::kRemoteAccessHostAllowGnubbyAuth); expected_schema.erase(key::kRemoteAccessHostAllowClientPairing);
diff --git a/remoting/host/server_log_entry_host_unittest.cc b/remoting/host/server_log_entry_host_unittest.cc index 08611ec..553e665 100644 --- a/remoting/host/server_log_entry_host_unittest.cc +++ b/remoting/host/server_log_entry_host_unittest.cc
@@ -8,6 +8,7 @@ #include "base/strings/stringize_macros.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "remoting/signaling/server_log_entry.h" #include "remoting/signaling/server_log_entry_unittest.h" #include "testing/gtest/include/gtest/gtest.h" @@ -50,10 +51,10 @@ #elif defined(OS_APPLE) key_value_pairs["os-name"] = "Mac"; keys.insert("os-version"); -#elif defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_CHROMEOS_ASH) key_value_pairs["os-name"] = "ChromeOS"; keys.insert("os-version"); -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) key_value_pairs["os-name"] = "Linux"; keys.insert("os-version"); #endif
diff --git a/remoting/host/setup/me2me_native_messaging_host_main.cc b/remoting/host/setup/me2me_native_messaging_host_main.cc index 2d1d537..29887ad0 100644 --- a/remoting/host/setup/me2me_native_messaging_host_main.cc +++ b/remoting/host/setup/me2me_native_messaging_host_main.cc
@@ -20,6 +20,7 @@ #include "base/task/thread_pool/thread_pool_instance.h" #include "base/threading/thread.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "mojo/core/embedder/embedder.h" #include "net/url_request/url_fetcher.h" #include "remoting/base/auto_thread_task_runner.h" @@ -48,9 +49,9 @@ #include "remoting/host/pairing_registry_delegate_win.h" #endif // defined(OS_WIN) -#if defined(USE_GLIB) && !defined(OS_CHROMEOS) +#if defined(USE_GLIB) && !BUILDFLAG(IS_CHROMEOS_ASH) #include <glib-object.h> -#endif // defined(USE_GLIB) && !defined(OS_CHROMEOS) +#endif // defined(USE_GLIB) && !BUILDFLAG(IS_CHROMEOS_ASH) using remoting::protocol::PairingRegistry; @@ -72,14 +73,14 @@ base::mac::ScopedNSAutoreleasePool pool; #endif // defined(OS_APPLE) -#if defined(USE_GLIB) && !defined(OS_CHROMEOS) +#if defined(USE_GLIB) && !BUILDFLAG(IS_CHROMEOS_ASH) // g_type_init will be deprecated in 2.36. 2.35 is the development // version for 2.36, hence do not call g_type_init starting 2.35. // http://developer.gnome.org/gobject/unstable/gobject-Type-Information.html#g-type-init #if !GLIB_CHECK_VERSION(2, 35, 0) g_type_init(); #endif -#endif // defined(USE_GLIB) && !defined(OS_CHROMEOS) +#endif // defined(USE_GLIB) && !BUILDFLAG(IS_CHROMEOS_ASH) // Required to find the ICU data file, used by some file_util routines. base::i18n::InitializeICU();
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn index 7f96607..0dbbeafc 100644 --- a/remoting/protocol/BUILD.gn +++ b/remoting/protocol/BUILD.gn
@@ -223,6 +223,7 @@ ] deps = [ "//base", + "//build:chromeos_buildflags", "//crypto", "//jingle:jingle_glue", "//net",
diff --git a/remoting/protocol/remoting_ice_config_request.cc b/remoting/protocol/remoting_ice_config_request.cc index d19760e..cf92b70 100644 --- a/remoting/protocol/remoting_ice_config_request.cc +++ b/remoting/protocol/remoting_ice_config_request.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "google_apis/google_api_keys.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "remoting/base/protobuf_http_request.h" @@ -75,7 +76,7 @@ request_config->path = kGetIceConfigPath; request_config->request_message = std::make_unique<apis::v1::GetIceConfigRequest>(); -#if defined(OS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) // Use the default Chrome API key for ChromeOS as the only host instance // which runs there is used for the ChromeOS Enterprise Kiosk mode // scenario. If we decide to implement a remote access host for ChromeOS,
diff --git a/remoting/remoting_locales.gni b/remoting/remoting_locales.gni index 0f69255..ace77b0 100644 --- a/remoting/remoting_locales.gni +++ b/remoting/remoting_locales.gni
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") + resources_locale_dir = "$root_gen_dir/remoting/resources/_locales" # See also remoting_locales_with_underscores below. @@ -93,7 +95,7 @@ # TODO(yuweih): Our build script doesn't seem to work with en-US and Chrome # on iOS doesn't seem to have en-US.lproj. Add is_ios back if we do need to # work with en-US. -if (is_chromeos) { +if (is_chromeos_ash) { remoting_locales += [ "en-US" ] remoting_locales_with_underscores += [ "en_US" ] }
diff --git a/remoting/remoting_options.gni b/remoting/remoting_options.gni index b7e9fa6..d6b730d 100644 --- a/remoting/remoting_options.gni +++ b/remoting/remoting_options.gni
@@ -3,11 +3,15 @@ # found in the LICENSE file. import("//build/config/chrome_build.gni") +import("//build/config/chromeos/ui_mode.gni") import("//build/config/ui.gni") enable_remoting_host = - is_win || (is_chromeos || (is_linux && use_x11)) || is_mac -enable_me2me_host = is_win || (is_linux && !is_chromeos && use_x11) || is_mac + is_win || (is_chromeos_ash || (is_linux && use_x11)) || is_mac + +# TODO(crbug.com/1052397): Remove is_chromeos_lacros once the target_os switch is completed. +enable_me2me_host = + is_win || ((is_linux || is_chromeos_lacros) && use_x11) || is_mac # Enable the multi-process host on Windows by default. if (is_win) {
diff --git a/remoting/signaling/BUILD.gn b/remoting/signaling/BUILD.gn index 7d122a8b..f24a8a53 100644 --- a/remoting/signaling/BUILD.gn +++ b/remoting/signaling/BUILD.gn
@@ -58,6 +58,7 @@ deps = [ "//base", + "//build:chromeos_buildflags", "//crypto", "//google_apis", "//jingle:webrtc_glue",
diff --git a/remoting/signaling/ftl_host_device_id_provider.cc b/remoting/signaling/ftl_host_device_id_provider.cc index bc9c695..db4d6b1 100644 --- a/remoting/signaling/ftl_host_device_id_provider.cc +++ b/remoting/signaling/ftl_host_device_id_provider.cc
@@ -5,6 +5,7 @@ #include "remoting/signaling/ftl_host_device_id_provider.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" namespace remoting { @@ -14,9 +15,9 @@ constexpr char kDeviceIdPrefix[] = "crd-win-host-"; #elif defined(OS_APPLE) constexpr char kDeviceIdPrefix[] = "crd-mac-host-"; -#elif defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_CHROMEOS_ASH) constexpr char kDeviceIdPrefix[] = "crd-cros-host-"; -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) constexpr char kDeviceIdPrefix[] = "crd-linux-host-"; #else constexpr char kDeviceIdPrefix[] = "crd-unknown-host-";
diff --git a/remoting/test/BUILD.gn b/remoting/test/BUILD.gn index 019a97e..b068917 100644 --- a/remoting/test/BUILD.gn +++ b/remoting/test/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//remoting/remoting_options.gni") static_library("test_support") { @@ -72,7 +73,7 @@ ] } -if (enable_remoting_host && !is_android && !is_chromeos) { +if (enable_remoting_host && !is_android && !is_chromeos_ash) { static_library("fake_connection_event_logger") { testonly = true @@ -136,7 +137,7 @@ deps = [ ":it2me_standalone_host" ] - if (is_linux) { + if (is_linux || is_chromeos_lacros) { deps += [ "//build/config/linux/gtk" ] }
diff --git a/sandbox/policy/mac/BUILD.gn b/sandbox/policy/mac/BUILD.gn index bded685..840c9b1 100644 --- a/sandbox/policy/mac/BUILD.gn +++ b/sandbox/policy/mac/BUILD.gn
@@ -4,8 +4,7 @@ import("//build/config/python.gni") -# TODO(crbug.com/1112471): Get this to run cleanly under Python 3. -python2_action_foreach("package_sb_files") { +action_foreach("package_sb_files") { script = "package_sb_file.py" sources = [ "audio.sb",
diff --git a/sandbox/policy/mac/package_sb_file.py b/sandbox/policy/mac/package_sb_file.py index 934fd226..f5048b7e 100755 --- a/sandbox/policy/mac/package_sb_file.py +++ b/sandbox/policy/mac/package_sb_file.py
@@ -3,6 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function + import os import sys @@ -37,14 +39,14 @@ output_h_file = output_directory + '/' + input_basename + '.h' output_cc_file = output_directory + '/' + input_basename + '.cc' try: - with open(input_filename, 'rb') as infile: - with open(output_h_file, 'wb') as outfile: + with open(input_filename, 'r') as infile: + with open(output_h_file, 'w') as outfile: outfile.write(header) outfile.write(h_include) outfile.write(namespace) outfile.write(h_definition % module_name) outfile.write(namespace_end) - with open(output_cc_file, 'wb') as outfile: + with open(output_cc_file, 'w') as outfile: outfile.write(header) outfile.write(cc_include % module_name) outfile.write(namespace) @@ -56,7 +58,7 @@ outfile.write(cc_definition_end) outfile.write(namespace_end) except IOError: - print >> sys.stderr, 'Failed to process %s' % input_filename + print('Failed to process %s' % input_filename, file=sys.stderr) return 1 return 0
diff --git a/services/device/geolocation/BUILD.gn b/services/device/geolocation/BUILD.gn index 4246b61..98fcffc 100644 --- a/services/device/geolocation/BUILD.gn +++ b/services/device/geolocation/BUILD.gn
@@ -39,6 +39,7 @@ "public_ip_address_geolocator.h", "public_ip_address_location_notifier.cc", "public_ip_address_location_notifier.h", + "system_location_provider.h", "wifi_data.cc", "wifi_data.h", "wifi_data_provider.cc",
diff --git a/services/device/geolocation/core_location_provider.h b/services/device/geolocation/core_location_provider.h index 2967619..20c53ab8 100644 --- a/services/device/geolocation/core_location_provider.h +++ b/services/device/geolocation/core_location_provider.h
@@ -8,6 +8,7 @@ #import <CoreLocation/CoreLocation.h> #include "base/mac/scoped_nsobject.h" +#include "services/device/geolocation/system_location_provider.h" #include "services/device/public/cpp/geolocation/location_provider.h" #include "services/device/public/mojom/geoposition.mojom.h" @@ -16,7 +17,7 @@ namespace device { // Location provider for macOS using the platform's Core Location API. -class CoreLocationProvider : public LocationProvider { +class CoreLocationProvider : public SystemLocationProvider { public: CoreLocationProvider(); ~CoreLocationProvider() override; @@ -29,16 +30,23 @@ const mojom::Geoposition& GetPosition() override; void OnPermissionGranted() override; + // SystemLocationProvider implementation + void SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) override; + void SystemLocationPermissionGranted(); void SystemLocationPermissionDenied(); void DidUpdatePosition(CLLocation* location); void SetManagerForTesting(CLLocationManager* location_manager); + void StopUsing(); private: base::scoped_nsobject<CLLocationManager> location_manager_; base::scoped_nsobject<LocationDelegate> delegate_; mojom::Geoposition last_position_; LocationProviderUpdateCallback callback_; + ShouldUseCallback should_use_callback_; + bool is_being_used_ = false; bool has_permission_ = false; bool provider_start_attemped_ = false; base::WeakPtrFactory<CoreLocationProvider> weak_ptr_factory_{this};
diff --git a/services/device/geolocation/core_location_provider.mm b/services/device/geolocation/core_location_provider.mm index 87b590f..a991d9f 100644 --- a/services/device/geolocation/core_location_provider.mm +++ b/services/device/geolocation/core_location_provider.mm
@@ -15,6 +15,8 @@ didUpdateLocations:(NSArray*)locations; - (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status; +- (void)locationManager:(CLLocationManager*)manager + didFailWithError:(NSError*)error; @end @@ -46,6 +48,17 @@ } - (void)locationManager:(CLLocationManager*)manager + didFailWithError:(NSError*)error { + [error localizedDescription]; + if ([error code] == kCLErrorLocationUnknown) { + // Fallback to network provider because Core Location is not able to + // determine location. This is likely due to wifi adapter being turned off. + if (provider_) + provider_->StopUsing(); + } +} + +- (void)locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray*)locations { if (provider_) provider_->DidUpdatePosition([locations lastObject]); @@ -102,6 +115,11 @@ // Nothing to do here. } +void CoreLocationProvider::SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) { + should_use_callback_ = callback; +} + void CoreLocationProvider::SystemLocationPermissionGranted() { has_permission_ = true; if (provider_start_attemped_) { @@ -114,7 +132,17 @@ has_permission_ = false; } +void CoreLocationProvider::StopUsing() { + if (should_use_callback_) + should_use_callback_.Run(/*should_use=*/false); + is_being_used_ = false; +} + void CoreLocationProvider::DidUpdatePosition(CLLocation* location) { + if (!is_being_used_ && should_use_callback_) { + should_use_callback_.Run(/*should_use=*/true); + is_being_used_ = true; + } // The error values in CLLocation correlate exactly to our error values. last_position_.latitude = location.coordinate.latitude; last_position_.longitude = location.coordinate.longitude; @@ -125,7 +153,6 @@ last_position_.altitude_accuracy = location.verticalAccuracy; last_position_.speed = location.speed; last_position_.heading = location.course; - callback_.Run(this, last_position_); }
diff --git a/services/device/geolocation/core_location_provider_unittest.mm b/services/device/geolocation/core_location_provider_unittest.mm index 43218df..c0720fe7 100644 --- a/services/device/geolocation/core_location_provider_unittest.mm +++ b/services/device/geolocation/core_location_provider_unittest.mm
@@ -25,6 +25,7 @@ // Utility functions. - (void)fakeUpdatePosition:(CLLocation*)test_location; - (void)fakeUpdatePermission:(CLAuthorizationStatus)status; +- (void)fakeTurnOffWifi; @end @implementation FakeCLLocationManager @@ -56,6 +57,16 @@ [_delegate locationManager:(id)self didChangeAuthorizationStatus:status]; } +- (void)fakeTurnOffWifi { + [_delegate locationManager:(id)self + didFailWithError:[NSError errorWithDomain:NSURLErrorDomain + code:kCLErrorLocationUnknown + userInfo:@{ + @"Error reason" : + @"Test wifi turning off" + }]]; +} + @end namespace device { @@ -64,6 +75,8 @@ public: std::unique_ptr<CoreLocationProvider> provider_; + void ShouldUseCallback(bool should_use) { should_use_tracker_ = should_use; } + protected: CoreLocationProviderTest() {} @@ -75,6 +88,8 @@ bool IsUpdating() { return [fake_location_manager_ updating]; } + bool ShouldUse() { return should_use_tracker_; } + // updates the position synchronously void FakeUpdatePosition(CLLocation* location) { [fake_location_manager_ fakeUpdatePosition:location]; @@ -87,6 +102,7 @@ base::test::TaskEnvironment task_environment_; const LocationProvider::LocationProviderUpdateCallback callback_; FakeCLLocationManager* fake_location_manager_; + bool should_use_tracker_ = false; }; TEST_F(CoreLocationProviderTest, CreateDestroy) { @@ -193,4 +209,32 @@ provider_.reset(); } +TEST_F(CoreLocationProviderTest, ShouldUseCallbackTest) { + InitializeProvider(); + + provider_->StartProvider(/*high_accuracy=*/true); + provider_->SetShouldUseSystemProviderCallback(base::BindRepeating( + &CoreLocationProviderTest::ShouldUseCallback, base::Unretained(this))); + + CLLocationCoordinate2D coors; + coors.latitude = 147.147; + coors.longitude = 101.101; + CLLocation* test_mac_location = + [[CLLocation alloc] initWithCoordinate:coors + altitude:417.417 + horizontalAccuracy:10.5 + verticalAccuracy:15.5 + timestamp:[NSDate date]]; + + provider_->SetUpdateCallback( + base::BindLambdaForTesting([&](const LocationProvider* provider, + const mojom::Geoposition& position) {})); + EXPECT_FALSE(ShouldUse()); + FakeUpdatePosition(test_mac_location); + EXPECT_TRUE(ShouldUse()); + + [fake_location_manager_ fakeTurnOffWifi]; + EXPECT_FALSE(ShouldUse()); +} + } // namespace device
diff --git a/services/device/geolocation/fake_location_provider.cc b/services/device/geolocation/fake_location_provider.cc index 59dc9f5..53f555c 100644 --- a/services/device/geolocation/fake_location_provider.cc +++ b/services/device/geolocation/fake_location_provider.cc
@@ -21,7 +21,10 @@ FakeLocationProvider::FakeLocationProvider() : provider_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} -FakeLocationProvider::~FakeLocationProvider() = default; +FakeLocationProvider::~FakeLocationProvider() { + if (destructor_callback_) + destructor_callback_.Run(); +} void FakeLocationProvider::HandlePositionChanged( const mojom::Geoposition& position) { @@ -59,4 +62,18 @@ is_permission_granted_ = true; } +void FakeLocationProvider::SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) { + should_use_system_provider_callback_ = callback; +} + +void FakeLocationProvider::CallShouldUseSystemProvider(bool should_use) { + should_use_system_provider_callback_.Run(should_use); +} + +void FakeLocationProvider::SetProviderDestroyedCallback( + const base::RepeatingClosure& callback) { + destructor_callback_ = callback; +} + } // namespace device
diff --git a/services/device/geolocation/fake_location_provider.h b/services/device/geolocation/fake_location_provider.h index 54d7c5a7d..0aa5ebe 100644 --- a/services/device/geolocation/fake_location_provider.h +++ b/services/device/geolocation/fake_location_provider.h
@@ -10,13 +10,14 @@ #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" +#include "services/device/geolocation/system_location_provider.h" #include "services/device/public/cpp/geolocation/location_provider.h" #include "services/device/public/mojom/geoposition.mojom.h" namespace device { // Fake implementation of a location provider for testing. -class FakeLocationProvider : public LocationProvider { +class FakeLocationProvider : public SystemLocationProvider { public: enum State { STOPPED, LOW_ACCURACY, HIGH_ACCURACY } state_ = STOPPED; @@ -37,12 +38,22 @@ const mojom::Geoposition& GetPosition() override; void OnPermissionGranted() override; + // SystemLocationProvider implementation + void SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) override; + + void CallShouldUseSystemProvider(bool should_use); + + void SetProviderDestroyedCallback(const base::RepeatingClosure& callback); + scoped_refptr<base::SingleThreadTaskRunner> provider_task_runner_; private: bool is_permission_granted_ = false; mojom::Geoposition position_; LocationProviderUpdateCallback callback_; + ShouldUseCallback should_use_system_provider_callback_; + base::RepeatingClosure destructor_callback_; DISALLOW_COPY_AND_ASSIGN(FakeLocationProvider); };
diff --git a/services/device/geolocation/location_arbitrator.cc b/services/device/geolocation/location_arbitrator.cc index 17147d94..c3128cb 100644 --- a/services/device/geolocation/location_arbitrator.cc +++ b/services/device/geolocation/location_arbitrator.cc
@@ -46,24 +46,46 @@ return is_permission_granted_; } +void LocationArbitrator::ShouldUseSystemProvider(bool should_use) { + force_ignore_system_location_ = !should_use; + if (!should_use && !network_location_provider_) { + network_location_provider_ = + NewNetworkLocationProvider(url_loader_factory_, api_key_); + RegisterProvider(network_location_provider_.get()); + } + + if (should_use && network_location_provider_) + network_location_provider_.reset(); + + DoStartProviders(); +} + void LocationArbitrator::OnPermissionGranted() { is_permission_granted_ = true; - for (const auto& provider : providers_) - provider->OnPermissionGranted(); + +#if defined(OS_MAC) + // On macOS we always want to keep the |system_location_provider_| in the most + // up to date state because it is the preferred provider if it is returning + // position data. + if (system_location_provider_ && force_ignore_system_location_) + system_location_provider_->OnPermissionGranted(); +#endif + auto* current_provider = GetProvider(); + if (current_provider) + current_provider->OnPermissionGranted(); } void LocationArbitrator::StartProvider(bool enable_high_accuracy) { is_running_ = true; enable_high_accuracy_ = enable_high_accuracy; - if (providers_.empty()) { + if (!HasProvider()) RegisterProviders(); - } DoStartProviders(); } void LocationArbitrator::DoStartProviders() { - if (providers_.empty()) { + if (!HasProvider()) { // If no providers are available, we report an error to avoid // callers waiting indefinitely for a reply. mojom::Geoposition position; @@ -71,9 +93,16 @@ arbitrator_update_callback_.Run(this, position); return; } - for (const auto& provider : providers_) { - provider->StartProvider(enable_high_accuracy_); - } + // On macOS we always want to start the |system_location_provider_| even if it + // is currently being ignored because we want to switch to it if it starts + // producing valid data. +#if defined(OS_MAC) + if (system_location_provider_ && force_ignore_system_location_) + system_location_provider_->StartProvider(enable_high_accuracy_); +#endif + auto* current_provider = GetProvider(); + if (current_provider) + current_provider->StartProvider(enable_high_accuracy_); } void LocationArbitrator::StopProvider() { @@ -83,38 +112,51 @@ position_provider_ = nullptr; position_ = mojom::Geoposition(); - providers_.clear(); + custom_location_provider_.reset(); + if (system_location_provider_) + system_location_provider_->StopProvider(); + network_location_provider_.reset(); is_running_ = false; } -void LocationArbitrator::RegisterProvider( - std::unique_ptr<LocationProvider> provider) { +void LocationArbitrator::RegisterProvider(LocationProvider* provider) { if (!provider) return; + // Using base::Unretained is safe here because the |provider| is owned by + // this and therefore will be destroyed before this is. provider->SetUpdateCallback(base::BindRepeating( &LocationArbitrator::OnLocationUpdate, base::Unretained(this))); if (is_permission_granted_) provider->OnPermissionGranted(); - providers_.push_back(std::move(provider)); } void LocationArbitrator::RegisterProviders() { if (custom_location_provider_getter_) { auto custom_provider = custom_location_provider_getter_.Run(); if (custom_provider) { - RegisterProvider(std::move(custom_provider)); + RegisterProvider(custom_provider.get()); + custom_location_provider_ = std::move(custom_provider); return; } } auto system_provider = NewSystemLocationProvider(); if (system_provider) { - RegisterProvider(std::move(system_provider)); - return; + RegisterProvider(system_provider.get()); + system_location_provider_ = std::move(system_provider); + // Using base::Unretained is safe here because the + // |system_location_provider_| is owned by this and therefore will be + // destroyed before this is. + system_location_provider_->SetShouldUseSystemProviderCallback( + base::BindRepeating(&LocationArbitrator::ShouldUseSystemProvider, + base::Unretained(this))); } - if (url_loader_factory_) - RegisterProvider(NewNetworkLocationProvider(url_loader_factory_, api_key_)); + if (url_loader_factory_) { + network_location_provider_ = + NewNetworkLocationProvider(url_loader_factory_, api_key_); + RegisterProvider(network_location_provider_.get()); + } } void LocationArbitrator::OnLocationUpdate( @@ -154,7 +196,7 @@ #endif } -std::unique_ptr<LocationProvider> +std::unique_ptr<SystemLocationProvider> LocationArbitrator::NewSystemLocationProvider() { #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_FUCHSIA) return nullptr; @@ -194,4 +236,23 @@ return false; } +bool LocationArbitrator::HasProvider() { + return custom_location_provider_ || + (system_location_provider_ && !force_ignore_system_location_) || + network_location_provider_; +} + +LocationProvider* LocationArbitrator::GetProvider() { + if (custom_location_provider_) + return custom_location_provider_.get(); + + if (system_location_provider_ && !force_ignore_system_location_) + return system_location_provider_.get(); + + if (network_location_provider_) + return network_location_provider_.get(); + + return nullptr; +} + } // namespace device
diff --git a/services/device/geolocation/location_arbitrator.h b/services/device/geolocation/location_arbitrator.h index ceb79ce1..028062e 100644 --- a/services/device/geolocation/location_arbitrator.h +++ b/services/device/geolocation/location_arbitrator.h
@@ -18,6 +18,7 @@ #include "services/device/geolocation/geolocation_provider_impl.h" #include "services/device/geolocation/network_location_provider.h" #include "services/device/geolocation/position_cache.h" +#include "services/device/geolocation/system_location_provider.h" #include "services/device/public/cpp/geolocation/location_provider.h" #include "services/device/public/mojom/geoposition.mojom.h" #include "url/gurl.h" @@ -49,6 +50,7 @@ static GURL DefaultNetworkProviderURL(); bool HasPermissionBeenGrantedForTest() const; + void ShouldUseSystemProvider(bool should_use); // LocationProvider implementation. void SetUpdateCallback( @@ -64,7 +66,7 @@ virtual std::unique_ptr<LocationProvider> NewNetworkLocationProvider( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, const std::string& api_key); - virtual std::unique_ptr<LocationProvider> NewSystemLocationProvider(); + virtual std::unique_ptr<SystemLocationProvider> NewSystemLocationProvider(); virtual base::Time GetTimeNow() const; private: @@ -72,7 +74,7 @@ // Provider will either be added to |providers_| or // deleted on error (e.g. it fails to start). - void RegisterProvider(std::unique_ptr<LocationProvider> provider); + void RegisterProvider(LocationProvider* provider); void RegisterProviders(); // Tells all registered providers to start. @@ -92,13 +94,19 @@ const mojom::Geoposition& new_position, bool from_same_provider) const; + bool HasProvider(); + LocationProvider* GetProvider(); + const CustomLocationProviderCallback custom_location_provider_getter_; const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; const std::string api_key_; LocationProvider::LocationProviderUpdateCallback arbitrator_update_callback_; - std::vector<std::unique_ptr<LocationProvider>> providers_; + std::unique_ptr<LocationProvider> custom_location_provider_; + std::unique_ptr<LocationProvider> network_location_provider_; + std::unique_ptr<SystemLocationProvider> system_location_provider_; + bool force_ignore_system_location_ = true; bool enable_high_accuracy_; // The provider which supplied the current |position_| const LocationProvider* position_provider_; @@ -116,7 +124,7 @@ // Factory functions for the various types of location provider to abstract // over the platform-dependent implementations. -std::unique_ptr<LocationProvider> NewSystemLocationProvider(); +std::unique_ptr<SystemLocationProvider> NewSystemLocationProvider(); } // namespace device
diff --git a/services/device/geolocation/location_arbitrator_unittest.cc b/services/device/geolocation/location_arbitrator_unittest.cc index 200f4334..5b58edb 100644 --- a/services/device/geolocation/location_arbitrator_unittest.cc +++ b/services/device/geolocation/location_arbitrator_unittest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/test/task_environment.h" +#include "build/build_config.h" #include "services/device/geolocation/fake_location_provider.h" #include "services/device/geolocation/fake_position_cache.h" #include "services/device/public/cpp/geolocation/geoposition.h" @@ -102,10 +103,14 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, const std::string& api_key) override { network_location_provider_ = new FakeLocationProvider; + network_location_provider_->SetProviderDestroyedCallback( + base::BindRepeating( + &TestingLocationArbitrator::FakeLocationProviderDestructorCallback, + base::Unretained(this))); return base::WrapUnique(network_location_provider_); } - std::unique_ptr<LocationProvider> NewSystemLocationProvider() override { + std::unique_ptr<SystemLocationProvider> NewSystemLocationProvider() override { if (!should_use_system_location_provider_) { return nullptr; } @@ -114,6 +119,10 @@ return base::WrapUnique(system_location_provider_); } + void FakeLocationProviderDestructorCallback() { + network_location_provider_ = nullptr; + } + FakeLocationProvider* network_location_provider_ = nullptr; FakeLocationProvider* system_location_provider_ = nullptr; bool should_use_system_location_provider_; @@ -239,27 +248,31 @@ EXPECT_FALSE(system_location_provider()); arbitrator_->StartProvider(false); - EXPECT_FALSE(network_location_provider()); - ASSERT_TRUE(system_location_provider()); - EXPECT_EQ(FakeLocationProvider::LOW_ACCURACY, - system_location_provider()->state_); + auto* location_provider = network_location_provider(); + EXPECT_TRUE(location_provider); + +#if defined(OS_MAC) + location_provider = system_location_provider(); + EXPECT_TRUE(location_provider); +#endif + EXPECT_EQ(FakeLocationProvider::LOW_ACCURACY, location_provider->state_); EXPECT_FALSE(ValidateGeoposition(observer_->last_position())); EXPECT_EQ(mojom::Geoposition::ErrorCode::NONE, observer_->last_position().error_code); - SetReferencePosition(system_location_provider()); + SetReferencePosition(location_provider); EXPECT_TRUE(ValidateGeoposition(observer_->last_position()) || observer_->last_position().error_code != mojom::Geoposition::ErrorCode::NONE); - EXPECT_EQ(system_location_provider()->GetPosition().latitude, + EXPECT_EQ(location_provider->GetPosition().latitude, observer_->last_position().latitude); - EXPECT_FALSE(system_location_provider()->is_permission_granted()); + EXPECT_FALSE(location_provider->is_permission_granted()); EXPECT_FALSE(arbitrator_->HasPermissionBeenGrantedForTest()); arbitrator_->OnPermissionGranted(); EXPECT_TRUE(arbitrator_->HasPermissionBeenGrantedForTest()); - EXPECT_TRUE(system_location_provider()->is_permission_granted()); + EXPECT_TRUE(location_provider->is_permission_granted()); } // Tests basic operation (single position fix) with no network location @@ -349,4 +362,48 @@ CheckLastPositionInfo(3, 139, 150); } +#if defined(OS_MAC) +TEST_F(GeolocationLocationArbitratorTest, NetworkProviderFallback) { + InitializeArbitrator( + base::BindRepeating(&GetCustomLocationProviderForTest, nullptr), + url_loader_factory_, /*should_use_system_location_provider=*/true); + ASSERT_TRUE(arbitrator_); + + arbitrator_->StartProvider(false); + + EXPECT_EQ(network_location_provider()->state(), + FakeLocationProvider::State::LOW_ACCURACY); + EXPECT_EQ(system_location_provider()->state(), + FakeLocationProvider::State::LOW_ACCURACY); + + system_location_provider()->CallShouldUseSystemProvider(/*should_use=*/true); + + EXPECT_FALSE(network_location_provider()); + EXPECT_EQ(system_location_provider()->state(), + FakeLocationProvider::State::LOW_ACCURACY); + + arbitrator_->StopProvider(); + arbitrator_->StartProvider(/*high_accuracy=*/false); + + EXPECT_FALSE(network_location_provider()); + EXPECT_EQ(system_location_provider()->state(), + FakeLocationProvider::State::LOW_ACCURACY); + + system_location_provider()->CallShouldUseSystemProvider(/*should_use=*/false); + + EXPECT_EQ(network_location_provider()->state(), + FakeLocationProvider::State::LOW_ACCURACY); + EXPECT_EQ(system_location_provider()->state(), + FakeLocationProvider::State::LOW_ACCURACY); + + arbitrator_->StopProvider(); + arbitrator_->StartProvider(/*high_accuracy=*/false); + + EXPECT_EQ(network_location_provider()->state(), + FakeLocationProvider::State::LOW_ACCURACY); + EXPECT_EQ(system_location_provider()->state(), + FakeLocationProvider::State::LOW_ACCURACY); +} +#endif + } // namespace device
diff --git a/services/device/geolocation/location_provider_android.cc b/services/device/geolocation/location_provider_android.cc index 9d198e1..baa7780 100644 --- a/services/device/geolocation/location_provider_android.cc +++ b/services/device/geolocation/location_provider_android.cc
@@ -57,8 +57,14 @@ // Nothing to do here. } +void LocationProviderAndroid::SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) { + // Androids's location provider should always be used. + callback.Run(/*should_use=*/true); +} + // static -std::unique_ptr<LocationProvider> NewSystemLocationProvider() { +std::unique_ptr<SystemLocationProvider> NewSystemLocationProvider() { return base::WrapUnique(new LocationProviderAndroid); }
diff --git a/services/device/geolocation/location_provider_android.h b/services/device/geolocation/location_provider_android.h index 426c1f3..2559e5a 100644 --- a/services/device/geolocation/location_provider_android.h +++ b/services/device/geolocation/location_provider_android.h
@@ -8,13 +8,14 @@ #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" +#include "services/device/geolocation/system_location_provider.h" #include "services/device/public/cpp/geolocation/location_provider.h" #include "services/device/public/mojom/geoposition.mojom.h" namespace device { // Location provider for Android using the platform provider over JNI. -class LocationProviderAndroid : public LocationProvider { +class LocationProviderAndroid : public SystemLocationProvider { public: LocationProviderAndroid(); ~LocationProviderAndroid() override; @@ -30,6 +31,10 @@ const mojom::Geoposition& GetPosition() override; void OnPermissionGranted() override; + // SystemLocationProvider implementation. + void SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) override; + private: base::ThreadChecker thread_checker_;
diff --git a/services/device/geolocation/system_location_provider.h b/services/device/geolocation/system_location_provider.h new file mode 100644 index 0000000..480ef520 --- /dev/null +++ b/services/device/geolocation/system_location_provider.h
@@ -0,0 +1,31 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_DEVICE_GEOLOCATION_SYSTEM_LOCATION_PROVIDER_H_ +#define SERVICES_DEVICE_GEOLOCATION_SYSTEM_LOCATION_PROVIDER_H_ + +#include "services/device/public/cpp/geolocation/location_provider.h" + +namespace device { + +class SystemLocationProvider : public LocationProvider { + public: + using ShouldUseCallback = base::RepeatingCallback<void(bool)>; + + // SystemLocationProviders are sometimes flaky (so far this is only used for + // macOS). Therefore the LocationArbitrator will default to using the + // NetworkLocationProvider until the SystemLocationProvider determines it is + // working properly. At this time the provided callback should be called with + // |should_use|=true. If at any time the SystemLocationProvider stops working + // this callback should again be used with |should_use|=false to notify the + // LocationArbitrator that it can no longer rely on the + // SystemLocationProvider. For example the macOS SystemLocationProvider no + // longer works when the WiFi adapter is turned off. + virtual void SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) {} +}; + +} // namespace device + +#endif // SERVICES_DEVICE_GEOLOCATION_SYSTEM_LOCATION_PROVIDER_H_ \ No newline at end of file
diff --git a/services/device/geolocation/wifi_data_provider_mac.mm b/services/device/geolocation/wifi_data_provider_mac.mm index 5764adf..9f879ed 100644 --- a/services/device/geolocation/wifi_data_provider_mac.mm +++ b/services/device/geolocation/wifi_data_provider_mac.mm
@@ -14,6 +14,7 @@ #include "base/strings/sys_string_conversions.h" #include "services/device/geolocation/wifi_data_provider_common.h" #include "services/device/geolocation/wifi_data_provider_manager.h" +#include "services/device/public/cpp/device_features.h" namespace device { @@ -101,6 +102,12 @@ std::unique_ptr<WifiDataProviderMac::WlanApiInterface> WifiDataProviderMac::CreateWlanApi() { + // With the Core Location backend enabled the NetworkLocationProvider is only + // needed when WiFi is turned off in order to provide a fallback location + // using the device IP address. Disable the WlanApi so avoid collecting more + // data than is necessary. + if (base::FeatureList::IsEnabled(features::kMacCoreLocationBackend)) + return nullptr; return std::make_unique<CoreWlanApi>(); }
diff --git a/services/device/geolocation/win/location_provider_winrt.cc b/services/device/geolocation/win/location_provider_winrt.cc index ef8e1817..6dac74cf 100644 --- a/services/device/geolocation/win/location_provider_winrt.cc +++ b/services/device/geolocation/win/location_provider_winrt.cc
@@ -456,8 +456,14 @@ return hr; } +void LocationProviderWinrt::SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) { + // WinRT's location provider should always be used if available. + callback.Run(/*should_use=*/true); +} + // static -std::unique_ptr<LocationProvider> NewSystemLocationProvider() { +std::unique_ptr<SystemLocationProvider> NewSystemLocationProvider() { if (!base::FeatureList::IsEnabled( features::kWinrtGeolocationImplementation) || !IsWinRTSupported() || !IsSystemLocationSettingEnabled()) {
diff --git a/services/device/geolocation/win/location_provider_winrt.h b/services/device/geolocation/win/location_provider_winrt.h index 8fda5177..00f4a79 100644 --- a/services/device/geolocation/win/location_provider_winrt.h +++ b/services/device/geolocation/win/location_provider_winrt.h
@@ -9,13 +9,14 @@ #include <wrl/client.h> #include "base/threading/thread_checker.h" +#include "services/device/geolocation/system_location_provider.h" #include "services/device/public/cpp/geolocation/location_provider.h" #include "services/device/public/mojom/geoposition.mojom.h" namespace device { // Location provider for Windows 8/10 using the WinRT platform apis -class LocationProviderWinrt : public LocationProvider { +class LocationProviderWinrt : public SystemLocationProvider { public: LocationProviderWinrt(); ~LocationProviderWinrt() override; @@ -28,6 +29,10 @@ const mojom::Geoposition& GetPosition() override; void OnPermissionGranted() override; + // SystemLocationProvider implementation + void SetShouldUseSystemProviderCallback( + const ShouldUseCallback& callback) override; + protected: virtual HRESULT GetGeolocator( ABI::Windows::Devices::Geolocation::IGeolocator** geo_locator);
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 29719c4de..b75f91d 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2703,6 +2703,27 @@ ] } ], + "EnablePasswordGenerationForClearTextFields": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnablePasswordGenerationForClearTextFields" + ] + } + ] + } + ], "EnableSafetyTipUI": [ { "platforms": [
diff --git a/third_party/.gitignore b/third_party/.gitignore index fb2896b..3630fb0 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -69,20 +69,24 @@ /devtools-frontend/src /directxsdk /dom_distiller_js/dist +/eigen/src /elfutils/src /emoji-segmenter/src /espresso/lib/ /expat/src /eyesfree/src +/farmhash/src /ffmpeg /flac /flatbuffers/src /fontconfig/src +/fp16/src /freetype-testing/src /freetype/src /fuchsia-sdk/images /fuchsia-sdk/images-internal /fuchsia-sdk/sdk +/gemmlowp/src /gles2_conform /glfw/src /glslang/src @@ -162,6 +166,7 @@ /nacl_sdk_binaries/ /nasm /nearby/src +/neon_2_sse/src /netty-tcnative/src /netty4/src /node/linux @@ -202,6 +207,7 @@ /requests/src /robolectric/lib/ /robolectric/robolectric +/ruy/src /scan-build/src /scons-2.0.1 /securemessage/src @@ -222,6 +228,7 @@ /syzygy /syzygy/binaries /text-fragments-polyfill/src +/tflite/src /tint/src /tsan/ /turbine/src
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 9e9131da..f56622c 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3058,6 +3058,7 @@ kMediaStreamTrackProcessor = 3729, kAddEventListenerWithAbortSignal = 3730, kXRSessionRequestLightProbe = 3731, + kBeforematchRevealedHiddenMatchable = 3732, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index dbdf05c..7c021ad4 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -111,8 +111,6 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.h", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_parser_init.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_parser_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_quad_init.cc", @@ -237,6 +235,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_overscroll_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_transition_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_transition_event_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_parse_from_string_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_parse_from_string_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_measure_options.cc", @@ -305,8 +305,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_set_inner_html_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_submit_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_submit_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_format_update_event_init.cc", @@ -410,6 +410,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_playback_direction.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_premultiply_alpha.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_premultiply_alpha.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_reader_mode.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_reader_mode.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_referrer_policy.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_referrer_policy.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_refresh_policy.cc",
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 795ed909..f251688c 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -639,6 +639,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_rp_entity.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_user_entity.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_user_entity.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_details.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_details.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_permission_descriptor.cc", @@ -647,6 +649,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_change_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_query_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_query_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_registration_options.cc", @@ -799,12 +803,12 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_metadata.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track_writer_parameters.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track_writer_parameters.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_geometry_change_event_init.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_geometry_change_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_watch_advertisements_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_watch_advertisements_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wave_shaper_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wave_shaper_options.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_id_request_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_id_request_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_close_info.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_close_info.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_attributes.cc", @@ -827,6 +831,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_source_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_sources_change_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_sources_change_event_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_light_probe_init.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_light_probe_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_ray_direction_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_ray_direction_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space_event_init.cc", @@ -837,6 +843,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_tracked_image_init.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_tracked_image_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_transient_input_hit_test_options_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_transient_input_hit_test_options_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_webgl_layer_init.cc", @@ -1062,6 +1070,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presenter_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_type.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_type.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_state.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_state.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_type.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_encryption_key_name.cc", @@ -1172,6 +1182,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_orientation.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space_type.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space_type.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reflection_format.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reflection_format.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_mode.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_mode.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_target_ray_mode.cc",
diff --git a/third_party/blink/renderer/bindings/modules/v8/BUILD.gn b/third_party/blink/renderer/bindings/modules/v8/BUILD.gn index 28cfe12..5a69c4c 100644 --- a/third_party/blink/renderer/bindings/modules/v8/BUILD.gn +++ b/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
@@ -97,29 +97,27 @@ ] } -idl_compiler("generate_bindings_modules_v8_interfaces") { - if (use_blink_v8_binding_new_idl_interface) { - modules_interface_idl_files = - filter_exclude(modules_idl_files, [ "*_callback.idl" ]) +if (!use_blink_v8_binding_new_idl_callback_interface || + !use_blink_v8_binding_new_idl_dictionary || + !use_blink_v8_binding_new_idl_interface) { + idl_compiler("generate_bindings_modules_v8_interfaces") { + sources = [] + if (!use_blink_v8_binding_new_idl_callback_interface) { + sources += filter_include(modules_idl_files, [ "*_callback.idl" ]) + } + if (!use_blink_v8_binding_new_idl_dictionary) { + sources += modules_dictionary_idl_files + } + if (!use_blink_v8_binding_new_idl_interface) { + sources += filter_exclude(modules_idl_files, [ "*_callback.idl" ]) + } + output_dir = bindings_modules_v8_output_dir + output_name_suffix = "" + target_component = "modules" } - if (use_blink_v8_binding_new_idl_callback_interface) { - modules_callback_interface_idl_files = - filter_include(modules_idl_files, [ "*_callback.idl" ]) +} else { + group("generate_bindings_modules_v8_interfaces") { } - - sources = modules_definition_idl_files - if (use_blink_v8_binding_new_idl_callback_interface) { - sources -= modules_callback_interface_idl_files - } - if (use_blink_v8_binding_new_idl_dictionary) { - sources -= modules_dictionary_idl_files - } - if (use_blink_v8_binding_new_idl_interface) { - sources -= modules_interface_idl_files - } - output_dir = bindings_modules_v8_output_dir - output_name_suffix = "" - target_component = "modules" } idl_impl("bindings_modules_impl_generated") { @@ -229,8 +227,13 @@ blink_modules_sources("bindings_modules_impl") { # ":generate_bindings_modules_v8_partial_interfaces_for_testing" is not # included here. - sources = get_target_outputs(":generate_bindings_modules_v8_interfaces") + - get_target_outputs(":bindings_modules_impl_generated") + sources = get_target_outputs(":bindings_modules_impl_generated") + + if (!use_blink_v8_binding_new_idl_callback_interface || + !use_blink_v8_binding_new_idl_dictionary || + !use_blink_v8_binding_new_idl_interface) { + sources += get_target_outputs(":generate_bindings_modules_v8_interfaces") + } if (!use_blink_v8_binding_new_idl_interface) { sources += get_target_outputs(":generate_bindings_modules_v8_partial_interfaces") +
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h index b7651d5..4202efe 100644 --- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h +++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -76,7 +76,6 @@ virtual void ListboxSelectedChildrenChanged(HTMLSelectElement*) = 0; virtual void ListboxActiveIndexChanged(HTMLSelectElement*) = 0; virtual void LocationChanged(const LayoutObject*) = 0; - virtual void RadiobuttonRemovedFromGroup(HTMLInputElement*) = 0; virtual void ImageLoaded(const LayoutObject*) = 0; virtual void Remove(AccessibleNode*) = 0;
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc index 8a17f85..f105ba2 100644 --- a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc +++ b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
@@ -7,6 +7,7 @@ #include <memory> #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h"
diff --git a/third_party/blink/renderer/core/animation/timing.cc b/third_party/blink/renderer/core/animation/timing.cc index 5a6d394..8d57548 100644 --- a/third_party/blink/renderer/core/animation/timing.cc +++ b/third_party/blink/renderer/core/animation/timing.cc
@@ -121,7 +121,7 @@ computed_timing->setLocalTime( CSSNumberish::FromDouble(calculated_timing.local_time.value() * 1000)); } else { - computed_timing->setLocalTimeToNull(); + computed_timing->setLocalTime(CSSNumberish()); } if (calculated_timing.is_in_effect) {
diff --git a/third_party/blink/renderer/core/animation/timing_input_test.cc b/third_party/blink/renderer/core/animation/timing_input_test.cc index f5b7c8f7..9883457 100644 --- a/third_party/blink/renderer/core/animation/timing_input_test.cc +++ b/third_party/blink/renderer/core/animation/timing_input_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/animation/timing_input.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_animation_options.h" #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.cc b/third_party/blink/renderer/core/editing/finder/text_finder.cc index cc3572cb..d127e04 100644 --- a/third_party/blink/renderer/core/editing/finder/text_finder.cc +++ b/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -907,6 +907,8 @@ } if (context->was_match_hidden) { + UseCounter::Count(GetFrame()->GetDocument(), + WebFeature::kBeforematchRevealedHiddenMatchable); GetFrame() ->GetDocument() ->MarkHasFindInPageBeforematchExpandedHiddenMatchable();
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder_test.cc b/third_party/blink/renderer/core/editing/finder/text_finder_test.cc index 55339c6..9fea2ca 100644 --- a/third_party/blink/renderer/core/editing/finder/text_finder_test.cc +++ b/third_party/blink/renderer/core/editing/finder/text_finder_test.cc
@@ -848,6 +848,75 @@ EXPECT_EQ(entries.size(), 0u); } +TEST_F(TextFinderSimTest, BeforeMatchExpandedHiddenMatchableUseCounter) { + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + .hidden { + content-visibility: hidden-matchable; + } + </style> + + <div id=hiddenid class=hidden>hidden</div> + + <script> + hiddenid.addEventListener('beforematch', () => { + requestAnimationFrame(() => { + hiddenid.classList.remove('hidden'); + }, 0); + }); + </script> + )HTML"); + Compositor().BeginFrame(); + + auto forced_activatable_locks = GetDocument() + .GetDisplayLockDocumentState() + .GetScopedForceActivatableLocks(); + GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kFindInPage); + GetTextFinder().Find(/*identifier=*/0, WebString(String("hidden")), + *mojom::blink::FindOptions::New(), + /*wrap_within_frame=*/false); + + Compositor().BeginFrame(); + Compositor().BeginFrame(); + + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kBeforematchRevealedHiddenMatchable)); +} + +TEST_F(TextFinderSimTest, + BeforeMatchExpandedHiddenMatchableUseCounterNoHandler) { + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + .hidden { + content-visibility: hidden-matchable; + } + </style> + + <div id=hiddenid class=hidden>hidden</div> + )HTML"); + Compositor().BeginFrame(); + + auto forced_activatable_locks = GetDocument() + .GetDisplayLockDocumentState() + .GetScopedForceActivatableLocks(); + GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kFindInPage); + GetTextFinder().Find(/*identifier=*/0, WebString(String("hidden")), + *mojom::blink::FindOptions::New(), + /*wrap_within_frame=*/false); + + Compositor().BeginFrame(); + Compositor().BeginFrame(); + + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kBeforematchRevealedHiddenMatchable)); +} + TEST_F(TextFinderTest, FindTextAcrossCommentNode) { GetDocument().body()->setInnerHTML( "<span>abc</span><!--comment--><span>def</span>");
diff --git a/third_party/blink/renderer/core/events/hash_change_event.h b/third_party/blink/renderer/core/events/hash_change_event.h index c84d59b8..1e91467a 100644 --- a/third_party/blink/renderer/core/events/hash_change_event.h +++ b/third_party/blink/renderer/core/events/hash_change_event.h
@@ -24,6 +24,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_hash_change_event_init.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/event_interface_names.h" +#include "third_party/blink/renderer/core/event_type_names.h" namespace blink {
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 188463df..ce88fac5 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2827,16 +2827,11 @@ web_widget_->AckPendingWindowRect(); } -void WebViewImpl::SetWindowRect(const gfx::Rect& bounds) { +void WebViewImpl::SendWindowRectToMainFrameHost( + const gfx::Rect& bounds, + base::OnceClosure ack_callback) { DCHECK(local_main_frame_host_remote_); - DCHECK(web_widget_); - web_widget_->SetPendingWindowRect(bounds); - local_main_frame_host_remote_->SetWindowRect( - bounds, WTF::Bind(&WebViewImpl::DidSetWindowRect, WTF::Unretained(this))); -} - -void WebViewImpl::DidSetWindowRect() { - web_widget_->AckPendingWindowRect(); + local_main_frame_host_remote_->SetWindowRect(bounds, std::move(ack_callback)); } void WebViewImpl::UpdateTargetURL(const WebURL& url,
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index dcddd3d..00b634a8 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -492,7 +492,10 @@ const gfx::Rect& rect, bool opened_by_user_gesture); - void SetWindowRect(const gfx::Rect& bounds); + // Send the window rect to the browser and call `ack_callback` when the + // browser has processed it. + void SendWindowRectToMainFrameHost(const gfx::Rect& bounds, + base::OnceClosure ack_callback); // TODO(crbug.com/1149992): This is called from the associated widget and this // code should eventually move out of WebView into somewhere else. @@ -629,10 +632,6 @@ // Corresponds to a Show method call. void DidShowCreatedWindow(); - // Callback when the window rect has been adjusted by the browser. - // Corresponds to a SetWindowRect method call. - void DidSetWindowRect(); - // Can be null (e.g. unittests, shared workers, etc). WebViewClient* web_view_client_; Persistent<ChromeClient> chrome_client_;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 2be99468..8c54148 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2742,17 +2742,26 @@ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) { frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPrePaint); - if (frame_view.CanThrottleRendering()) { - // This frame can be throttled but not throttled, meaning we are not in an - // AllowThrottlingScope. Now this frame may contain dirty paint flags, and - // we need to propagate the flags into the ancestor chain so that - // PrePaintTreeWalk can reach this frame. - frame_view.SetNeedsPaintPropertyUpdate(); - // We may record more pre-composited layers under the frame. - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - frame_view.SetPaintArtifactCompositorNeedsUpdate(); - if (auto* owner = frame_view.GetLayoutEmbeddedContent()) - owner->SetShouldCheckForPaintInvalidation(); + if (frame_view.pre_paint_skipped_while_throttled_ || + frame_view.lifecycle_updates_throttled_) { + // We skipped pre-paint for this frame while it was throttled, or we + // have never run pre-paint for this frame. Either way, we're + // unthrottled now, so we must propagate our dirty bits into our + // parent frame so that pre-paint reaches into this frame. + if (LayoutView* layout_view = frame_view.GetLayoutView()) { + if (auto* owner = frame_view.GetFrame().OwnerLayoutObject()) { + if (layout_view->NeedsPaintPropertyUpdate() || + layout_view->DescendantNeedsPaintPropertyUpdate()) { + owner->SetDescendantNeedsPaintPropertyUpdate(); + // We may record more pre-composited layers under the frame. + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + frame_view.SetPaintArtifactCompositorNeedsUpdate(); + } + if (layout_view->ShouldCheckForPaintInvalidation()) + owner->SetShouldCheckForPaintInvalidation(); + } + } + frame_view.pre_paint_skipped_while_throttled_ = false; } }); @@ -4313,10 +4322,6 @@ return; } RenderThrottlingStatusChanged(); - // We need to invalidate unconditionally, so if it didn't happen during - // RenderThrottlingStatusChanged, do it now. - if (CanThrottleRendering()) - InvalidateForThrottlingChange(); // Immediately propagate changes to children. UpdateRenderThrottlingStatus(IsHiddenForThrottling(), IsSubtreeThrottled(), true); @@ -4355,7 +4360,12 @@ SetPaintArtifactCompositorNeedsUpdate(); if (!CanThrottleRendering()) { - InvalidateForThrottlingChange(); + // Start ticking animation frames again if necessary. + if (GetPage()) + GetPage()->Animator().ScheduleVisualUpdate(frame_.Get()); + // Ensure we'll recompute viewport intersection for the frame subtree during + // the scheduled visual update. + SetIntersectionObservationState(kRequired); } else if (GetFrame().IsLocalRoot()) { // By this point, every frame in the local frame tree has become throttled, // so painting the tree should just clear the previous painted output. @@ -4374,26 +4384,6 @@ #endif } -void LocalFrameView::InvalidateForThrottlingChange() { - // Start ticking animation frames again if necessary. - if (GetPage()) - GetPage()->Animator().ScheduleVisualUpdate(frame_.Get()); - // Force a full repaint of this frame to ensure we are not left with a - // partially painted version of this frame's contents if we skipped - // painting them while the frame was throttled. - LayoutView* layout_view = GetLayoutView(); - if (layout_view) { - layout_view->InvalidatePaintForViewAndDescendants(); - // Also need to update all paint properties that might be skipped while - // the frame was throttled. - layout_view->AddSubtreePaintPropertyUpdateReason( - SubtreePaintPropertyUpdateReason::kPreviouslySkipped); - } - // Ensure we'll recompute viewport intersection for the frame subtree during - // the scheduled visual update. - SetIntersectionObservationState(kRequired); -} - void LocalFrameView::SetNeedsForcedCompositingUpdate() { needs_forced_compositing_update_ = true; if (LocalFrameView* parent = ParentFrameView())
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index 79bbb25..042b887 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -618,6 +618,10 @@ bool subtree_throttled, bool recurse = false) override; + void SetPrePaintSkippedWhileThrottled() { + pre_paint_skipped_while_throttled_ = true; + } + void BeginLifecycleUpdates(); // Records a timestamp in PaintTiming when the frame is first not @@ -907,8 +911,6 @@ DoublePoint ConvertFromContainingEmbeddedContentView( const DoublePoint&) const; - void InvalidateForThrottlingChange(); - void UpdateGeometriesIfNeeded(); bool WasViewportResized(); void SendResizeEventIfNeeded(); @@ -1138,6 +1140,8 @@ HeapHashSet<WeakMember<HTMLVideoElement>> fullscreen_video_elements_; + bool pre_paint_skipped_while_throttled_ = false; + std::unique_ptr<OverlayInterstitialAdDetector> overlay_interstitial_ad_detector_;
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc index b1d84d3f..76cb295 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
@@ -1302,6 +1302,18 @@ main_data().synchronous_resize_mode_for_testing = enable; } +void WebFrameWidgetBase::SetDeviceColorSpaceForTesting( + const gfx::ColorSpace& color_space) { + DCHECK(ForMainFrame()); + // We are changing the device color space from the renderer, so allocate a + // new viz::LocalSurfaceId to avoid surface invariants violations in tests. + widget_base_->LayerTreeHost()->RequestNewLocalSurfaceId(); + + blink::ScreenInfo info = widget_base_->GetScreenInfo(); + info.display_color_spaces = gfx::DisplayColorSpaces(color_space); + widget_base_->UpdateScreenInfo(info); +} + // TODO(665924): Remove direct dispatches of mouse events from // PointerLockController, instead passing them through EventHandler. void WebFrameWidgetBase::PointerLockMouseEvent( @@ -3480,4 +3492,50 @@ plugin->ImeFinishComposingTextForPlugin(keep_selection); } +void WebFrameWidgetBase::SetWindowRect(const gfx::Rect& window_rect) { + DCHECK(ForMainFrame()); + if (SynchronousResizeModeForTestingEnabled()) { + // This is a web-test-only path. At one point, it was planned to be + // removed. See https://crbug.com/309760. + SetWindowRectSynchronously(window_rect); + return; + } + + SetPendingWindowRect(window_rect); + View()->SendWindowRectToMainFrameHost( + window_rect, WTF::Bind(&WebFrameWidgetBase::AckPendingWindowRect, + WrapWeakPersistent(this))); +} + +void WebFrameWidgetBase::SetWindowRectSynchronouslyForTesting( + const gfx::Rect& new_window_rect) { + DCHECK(ForMainFrame()); + SetWindowRectSynchronously(new_window_rect); +} + +void WebFrameWidgetBase::SetWindowRectSynchronously( + const gfx::Rect& new_window_rect) { + // This method is only call in tests, and it applies the |new_window_rect| to + // all three of: + // a) widget size (in |size_|) + // b) blink viewport (in |visible_viewport_size_|) + // c) compositor viewport (in cc::LayerTreeHost) + // Normally the browser controls these three things independently, but this is + // used in tests to control the size from the renderer. + + // We are resizing the window from the renderer, so allocate a new + // viz::LocalSurfaceId to avoid surface invariants violations in tests. + widget_base_->LayerTreeHost()->RequestNewLocalSurfaceId(); + + gfx::Rect compositor_viewport_pixel_rect(gfx::ScaleToCeiledSize( + new_window_rect.size(), + widget_base_->GetScreenInfo().device_scale_factor)); + widget_base_->UpdateSurfaceAndScreenInfo( + widget_base_->local_surface_id_from_parent(), + compositor_viewport_pixel_rect, widget_base_->GetScreenInfo()); + + Resize(new_window_rect.size()); + widget_base_->SetScreenRects(new_window_rect, new_window_rect); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.h b/third_party/blink/renderer/core/frame/web_frame_widget_base.h index 57e855f..9105317 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_base.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.h
@@ -581,10 +581,16 @@ // still need the resize to happen in a synchronous fashion. void UseSynchronousResizeModeForTesting(bool enable); + // Sets the device color space for testing. + void SetDeviceColorSpaceForTesting(const gfx::ColorSpace& color_space); + // Converts from DIPs to Blink coordinate space (ie. Viewport/Physical // pixels). gfx::Size DIPsToCeiledBlinkSpace(const gfx::Size& size); + void SetWindowRect(const gfx::Rect& window_rect); + void SetWindowRectSynchronouslyForTesting(const gfx::Rect& new_window_rect); + void SetToolTipText(const String& tooltip_text, TextDirection dir); void ShowVirtualKeyboardOnElementFocus(); @@ -785,6 +791,8 @@ void ForEachRemoteFrameControlledByWidget( const base::RepeatingCallback<void(RemoteFrame*)>& callback); + void SetWindowRectSynchronously(const gfx::Rect& new_window_rect); + static bool ignore_input_events_; WebWidgetClient* client_;
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc index 9ab6b59..47d8837 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -100,16 +100,6 @@ return HasFocus(); } -void WebViewFrameWidget::SetWindowRect(const gfx::Rect& window_rect) { - if (SynchronousResizeModeForTestingEnabled()) { - // This is a web-test-only path. At one point, it was planned to be - // removed. See https://crbug.com/309760. - SetWindowRectSynchronously(window_rect); - return; - } - View()->SetWindowRect(window_rect); -} - bool WebViewFrameWidget::ScrollFocusedEditableElementIntoView() { return web_view_->ScrollFocusedEditableElementIntoView(); } @@ -298,47 +288,6 @@ return event_result; } -void WebViewFrameWidget::SetDeviceColorSpaceForTesting( - const gfx::ColorSpace& color_space) { - // We are changing the device color space from the renderer, so allocate a - // new viz::LocalSurfaceId to avoid surface invariants violations in tests. - widget_base_->LayerTreeHost()->RequestNewLocalSurfaceId(); - - blink::ScreenInfo info = widget_base_->GetScreenInfo(); - info.display_color_spaces = gfx::DisplayColorSpaces(color_space); - widget_base_->UpdateScreenInfo(info); -} - -void WebViewFrameWidget::SetWindowRectSynchronouslyForTesting( - const gfx::Rect& new_window_rect) { - SetWindowRectSynchronously(new_window_rect); -} - -void WebViewFrameWidget::SetWindowRectSynchronously( - const gfx::Rect& new_window_rect) { - // This method is only call in tests, and it applies the |new_window_rect| to - // all three of: - // a) widget size (in |size_|) - // b) blink viewport (in |visible_viewport_size_|) - // c) compositor viewport (in cc::LayerTreeHost) - // Normally the browser controls these three things independently, but this is - // used in tests to control the size from the renderer. - - // We are resizing the window from the renderer, so allocate a new - // viz::LocalSurfaceId to avoid surface invariants violations in tests. - widget_base_->LayerTreeHost()->RequestNewLocalSurfaceId(); - - gfx::Rect compositor_viewport_pixel_rect(gfx::ScaleToCeiledSize( - new_window_rect.size(), - widget_base_->GetScreenInfo().device_scale_factor)); - widget_base_->UpdateSurfaceAndScreenInfo( - widget_base_->local_surface_id_from_parent(), - compositor_viewport_pixel_rect, widget_base_->GetScreenInfo()); - - Resize(new_window_rect.size()); - widget_base_->SetScreenRects(new_window_rect, new_window_rect); -} - void WebViewFrameWidget::ApplyVisualPropertiesSizing( const VisualProperties& visual_properties) { if (size_ !=
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.h b/third_party/blink/renderer/core/frame/web_view_frame_widget.h index 00f9992..5071f91 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.h +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.h
@@ -78,16 +78,10 @@ // WidgetBaseClient overrides: void FocusChanged(bool enabled) override; - void SetDeviceColorSpaceForTesting(const gfx::ColorSpace& color_space); - void SetWindowRect(const gfx::Rect& window_rect); - void SetWindowRectSynchronouslyForTesting(const gfx::Rect& new_window_rect); - private: // PageWidgetEventHandler overrides: WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override; - void SetWindowRectSynchronously(const gfx::Rect& new_window_rect); - scoped_refptr<WebViewImpl> web_view_; // This stores the last hidden page popup. If a GestureTap attempts to open
diff --git a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc index 1cdacdcb..2a4bbe5 100644 --- a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc +++ b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
@@ -163,14 +163,6 @@ // valid only if the group was invalid. button->SetNeedsValidityCheck(); } - - // Send notification to update AX attributes for AXObjects which radiobutton - // group has. - if (!members_.IsEmpty()) { - HTMLInputElement* input = members_.begin()->key; - if (AXObjectCache* cache = input->GetDocument().ExistingAXObjectCache()) - cache->RadiobuttonRemovedFromGroup(input); - } } void RadioButtonGroup::SetNeedsValidityCheckForAllButtons() {
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css index da6f733a..5b8d5fc 100644 --- a/third_party/blink/renderer/core/html/resources/html.css +++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -424,7 +424,7 @@ } input { - -webkit-appearance: textfield; /* AutoAppearanceFor() should match to this. */ + appearance: auto; padding: 1px; background-color: -internal-light-dark(white, black); border: 2px inset; @@ -433,7 +433,7 @@ } input[type="search" i] { - -webkit-appearance: searchfield; /* AutoAppearanceFor() should match to this. */ + appearance: auto; box-sizing: border-box; } @@ -500,7 +500,7 @@ } textarea { - -webkit-appearance: textarea; /* AutoAppearanceFor() should match to this. */ + appearance: auto; background-color: -internal-light-dark(white, black); border: 1px solid; column-count: initial !important; @@ -633,7 +633,7 @@ } input[type="range" i] { - -webkit-appearance: slider-horizontal; /* AutoAppearanceFor() should match to this. */ + appearance: auto; /* AutoAppearanceFor() should match to this. */ padding: initial; border: initial; margin: 2px;
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc index 3345d6a0..366f86b22 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -70,7 +70,7 @@ maybe_sticky_ancestor = maybe_sticky_ancestor->IsLayoutInline() ? maybe_sticky_ancestor->Container() - : To<LayoutBox>(maybe_sticky_ancestor)->LocationContainer(); + : To<LayoutBox>(maybe_sticky_ancestor)->StickyContainer(); } return nullptr; } @@ -942,6 +942,10 @@ return offset; } +LayoutBlock* LayoutBoxModelObject::StickyContainer() const { + return ContainingBlock(); +} + void LayoutBoxModelObject::UpdateStickyPositionConstraints() const { NOT_DESTROYED(); DCHECK(StyleRef().HasStickyConstrainedPosition()); @@ -950,13 +954,13 @@ StickyPositionScrollingConstraints constraints; PhysicalOffset skipped_containers_offset; - LayoutBlock* containing_block = ContainingBlock(); + LayoutBlock* sticky_container = StickyContainer(); // The location container for boxes is not always the containing block. LayoutObject* location_container = IsLayoutInline() ? Container() : To<LayoutBox>(this)->LocationContainer(); // Skip anonymous containing blocks. - while (containing_block->IsAnonymous()) { - containing_block = containing_block->ContainingBlock(); + while (sticky_container->IsAnonymous()) { + sticky_container = sticky_container->ContainingBlock(); } // The sticky position constraint rects should be independent of the current @@ -966,29 +970,29 @@ MapCoordinatesFlags flags = kIgnoreTransforms | kIgnoreScrollOffset | kIgnoreStickyOffset; skipped_containers_offset = location_container->LocalToAncestorPoint( - PhysicalOffset(), containing_block, flags); + PhysicalOffset(), sticky_container, flags); auto& scroll_ancestor = To<LayoutBox>(Layer()->AncestorScrollContainerLayer()->GetLayoutObject()); LayoutUnit max_container_width = - IsA<LayoutView>(containing_block) - ? containing_block->LogicalWidth() - : containing_block->ContainingBlockLogicalWidthForContent(); + IsA<LayoutView>(sticky_container) + ? sticky_container->LogicalWidth() + : sticky_container->ContainingBlockLogicalWidthForContent(); // Sticky positioned element ignore any override logical width on the // containing block, as they don't call containingBlockLogicalWidthForContent. // It's unclear whether this is totally fine. // Compute the container-relative area within which the sticky element is // allowed to move. - LayoutUnit max_width = containing_block->AvailableLogicalWidth(); + LayoutUnit max_width = sticky_container->AvailableLogicalWidth(); // Map the containing block to the inner corner of the scroll ancestor without // transforms. PhysicalRect scroll_container_relative_padding_box_rect( - containing_block->LayoutOverflowRect()); - if (containing_block != &scroll_ancestor) { - PhysicalRect local_rect = containing_block->PhysicalPaddingBoxRect(); + sticky_container->LayoutOverflowRect()); + if (sticky_container != &scroll_ancestor) { + PhysicalRect local_rect = sticky_container->PhysicalPaddingBoxRect(); scroll_container_relative_padding_box_rect = - containing_block->LocalToAncestorRect(local_rect, &scroll_ancestor, + sticky_container->LocalToAncestorRect(local_rect, &scroll_ancestor, flags); } @@ -1007,16 +1011,16 @@ // It is an open issue whether the margin should collapse. // See https://www.w3.org/TR/css-position-3/#sticky-pos scroll_container_relative_containing_block_rect.ContractEdges( - MinimumValueForLength(containing_block->StyleRef().PaddingTop(), + MinimumValueForLength(sticky_container->StyleRef().PaddingTop(), max_container_width) + MinimumValueForLength(StyleRef().MarginTop(), max_width), - MinimumValueForLength(containing_block->StyleRef().PaddingRight(), + MinimumValueForLength(sticky_container->StyleRef().PaddingRight(), max_container_width) + MinimumValueForLength(StyleRef().MarginRight(), max_width), - MinimumValueForLength(containing_block->StyleRef().PaddingBottom(), + MinimumValueForLength(sticky_container->StyleRef().PaddingBottom(), max_container_width) + MinimumValueForLength(StyleRef().MarginBottom(), max_width), - MinimumValueForLength(containing_block->StyleRef().PaddingLeft(), + MinimumValueForLength(sticky_container->StyleRef().PaddingLeft(), max_container_width) + MinimumValueForLength(StyleRef().MarginLeft(), max_width)); @@ -1028,7 +1032,7 @@ sticky_box_rect = To<LayoutInline>(this)->PhysicalLinesBoundingBox(); } else { sticky_box_rect = - containing_block->FlipForWritingMode(To<LayoutBox>(this)->FrameRect()); + sticky_container->FlipForWritingMode(To<LayoutBox>(this)->FrameRect()); } PhysicalOffset sticky_location = sticky_box_rect.offset + skipped_containers_offset; @@ -1038,8 +1042,8 @@ // within the scroll ancestor if the container is not our scroll ancestor. If // the container is our scroll ancestor, we also need to remove the border // box because we want the position from within the scroller border. - PhysicalOffset container_border_offset(containing_block->BorderLeft(), - containing_block->BorderTop()); + PhysicalOffset container_border_offset(sticky_container->BorderLeft(), + sticky_container->BorderTop()); sticky_location -= container_border_offset; constraints.scroll_container_relative_sticky_box_rect = PhysicalRect( scroll_container_relative_padding_box_rect.offset + sticky_location, @@ -1052,12 +1056,12 @@ // The respective search ranges are [container, containingBlock) and // [containingBlock, scrollAncestor). constraints.nearest_sticky_layer_shifting_sticky_box = - FindFirstStickyBetween(location_container, containing_block); + FindFirstStickyBetween(location_container, sticky_container); // We cannot use |scrollAncestor| here as it disregards the root // ancestorOverflowLayer(), which we should include. constraints.nearest_sticky_layer_shifting_containing_block = FindFirstStickyBetween( - containing_block, + sticky_container, &Layer()->AncestorScrollContainerLayer()->GetLayoutObject()); // We skip the right or top sticky offset if there is not enough space to
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.h b/third_party/blink/renderer/core/layout/layout_box_model_object.h index 8621cda..01aaea4 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.h +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -150,6 +150,7 @@ void UpdateStickyPositionConstraints() const; PhysicalOffset StickyPositionOffset() const; bool IsSlowRepaintConstrainedObject() const; + virtual LayoutBlock* StickyContainer() const; PhysicalOffset OffsetForInFlowPosition() const;
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 38689c84..daed77a 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -3615,7 +3615,13 @@ GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired); bitfields_.SetNeedsPaintPropertyUpdate(true); - for (auto* ancestor = ParentCrossingFrames(); + if (auto* ancestor = ParentCrossingFrames()) + ancestor->SetDescendantNeedsPaintPropertyUpdate(); +} + +void LayoutObject::SetDescendantNeedsPaintPropertyUpdate() { + NOT_DESTROYED(); + for (auto* ancestor = this; ancestor && !ancestor->DescendantNeedsPaintPropertyUpdate(); ancestor = ancestor->ParentCrossingFrames()) { ancestor->bitfields_.SetDescendantNeedsPaintPropertyUpdate(true);
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 16b60d0..65eef32 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -3139,6 +3139,7 @@ // descendant needing a paint property update too. void SetNeedsPaintPropertyUpdate(); void SetNeedsPaintPropertyUpdatePreservingCachedRects(); + void SetDescendantNeedsPaintPropertyUpdate(); bool NeedsPaintPropertyUpdate() const { NOT_DESTROYED(); return bitfields_.NeedsPaintPropertyUpdate();
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc index fad38171..b4abd38 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -121,7 +121,8 @@ NGGridLayoutAlgorithm::GridItemData::GridItemData(const NGBlockNode node) : node(node) {} -AutoPlacementType NGGridLayoutAlgorithm::GridItemData::AutoPlacement( +NGGridLayoutAlgorithm::AutoPlacementType +NGGridLayoutAlgorithm::GridItemData::AutoPlacement( GridTrackSizingDirection flow_direction) const { bool is_major_indefinite = Span(flow_direction).IsIndefinite(); bool is_minor_indefinite = @@ -259,7 +260,7 @@ LayoutUnit NGGridLayoutAlgorithm::ContributionSizeForGridItem( const GridItemData& grid_item, GridTrackSizingDirection track_direction, - NGGridItemContributionType contribution_type) const { + GridItemContributionType contribution_type) const { const ComputedStyle& grid_item_style = grid_item.node.Style(); GridTrackSizingDirection grid_item_track_direction = track_direction; @@ -669,19 +670,22 @@ // Helpers for the track sizing algorithm. namespace { +using GridItemContributionType = + NGGridLayoutAlgorithm::GridItemContributionType; + // Returns the corresponding size to be increased by accommodating a grid item's // contribution; for intrinsic min track sizing functions, return the base size. // For intrinsic max track sizing functions, return the growth limit. static LayoutUnit AffectedSizeForContribution( const NGGridSet& set, - NGGridItemContributionType contribution_type) { + GridItemContributionType contribution_type) { switch (contribution_type) { - case NGGridItemContributionType::kForIntrinsicMinimums: - case NGGridItemContributionType::kForContentBasedMinimums: - case NGGridItemContributionType::kForMaxContentMinimums: + case GridItemContributionType::kForIntrinsicMinimums: + case GridItemContributionType::kForContentBasedMinimums: + case GridItemContributionType::kForMaxContentMinimums: return set.BaseSize(); - case NGGridItemContributionType::kForIntrinsicMaximums: - case NGGridItemContributionType::kForMaxContentMaximums: + case GridItemContributionType::kForIntrinsicMaximums: + case GridItemContributionType::kForMaxContentMaximums: LayoutUnit growth_limit = set.GrowthLimit(); // For infinite growth limits, substitute with the track's base size. if (growth_limit == kIndefiniteSize) @@ -692,15 +696,15 @@ static void GrowAffectedSizeByPlannedIncrease( NGGridSet& set, - NGGridItemContributionType contribution_type) { + GridItemContributionType contribution_type) { switch (contribution_type) { - case NGGridItemContributionType::kForIntrinsicMinimums: - case NGGridItemContributionType::kForContentBasedMinimums: - case NGGridItemContributionType::kForMaxContentMinimums: + case GridItemContributionType::kForIntrinsicMinimums: + case GridItemContributionType::kForContentBasedMinimums: + case GridItemContributionType::kForMaxContentMinimums: set.SetBaseSize(set.BaseSize() + set.PlannedIncrease()); break; - case NGGridItemContributionType::kForIntrinsicMaximums: - case NGGridItemContributionType::kForMaxContentMaximums: + case GridItemContributionType::kForIntrinsicMaximums: + case GridItemContributionType::kForMaxContentMaximums: LayoutUnit growth_limit = set.GrowthLimit(); // If the affected size to grow is an infinite growth limit, set it to the // track's base size plus the planned increase. @@ -716,20 +720,20 @@ // https://drafts.csswg.org/css-grid-1/#algo-spanning-items; false otherwise. static bool IsContributionAppliedToSet( const NGGridSet& set, - NGGridItemContributionType contribution_type) { + GridItemContributionType contribution_type) { switch (contribution_type) { - case NGGridItemContributionType::kForIntrinsicMinimums: + case GridItemContributionType::kForIntrinsicMinimums: return set.TrackSize().HasIntrinsicMinTrackBreadth(); - case NGGridItemContributionType::kForContentBasedMinimums: + case GridItemContributionType::kForContentBasedMinimums: return set.TrackSize().HasMinOrMaxContentMinTrackBreadth(); - case NGGridItemContributionType::kForMaxContentMinimums: + case GridItemContributionType::kForMaxContentMinimums: // TODO(ethavar): Check if the grid container is being sized under a // 'max-content' constraint to consider 'auto' min track sizing functions, // see https://drafts.csswg.org/css-grid-1/#track-size-max-content-min. return set.TrackSize().HasMaxContentMinTrackBreadth(); - case NGGridItemContributionType::kForIntrinsicMaximums: + case GridItemContributionType::kForIntrinsicMaximums: return set.TrackSize().HasIntrinsicMaxTrackBreadth(); - case NGGridItemContributionType::kForMaxContentMaximums: + case GridItemContributionType::kForMaxContentMaximums: return set.TrackSize().HasMaxContentOrAutoMaxTrackBreadth(); } } @@ -741,32 +745,32 @@ // collection of tracks different than "all affected tracks". static bool ShouldUsedSizeGrowBeyondLimit( const NGGridSet& set, - NGGridItemContributionType contribution_type) { + GridItemContributionType contribution_type) { // This function assumes that we already determined that extra space // distribution will be applied to the specified set. DCHECK(IsContributionAppliedToSet(set, contribution_type)); switch (contribution_type) { - case NGGridItemContributionType::kForIntrinsicMinimums: - case NGGridItemContributionType::kForContentBasedMinimums: + case GridItemContributionType::kForIntrinsicMinimums: + case GridItemContributionType::kForContentBasedMinimums: return set.TrackSize().HasIntrinsicMaxTrackBreadth(); - case NGGridItemContributionType::kForMaxContentMinimums: + case GridItemContributionType::kForMaxContentMinimums: return set.TrackSize().HasMaxContentMaxTrackBreadth(); - case NGGridItemContributionType::kForIntrinsicMaximums: - case NGGridItemContributionType::kForMaxContentMaximums: + case GridItemContributionType::kForIntrinsicMaximums: + case GridItemContributionType::kForMaxContentMaximums: return false; } } static bool IsDistributionForGrowthLimits( - NGGridItemContributionType contribution_type) { + GridItemContributionType contribution_type) { switch (contribution_type) { - case NGGridItemContributionType::kForIntrinsicMinimums: - case NGGridItemContributionType::kForContentBasedMinimums: - case NGGridItemContributionType::kForMaxContentMinimums: + case GridItemContributionType::kForIntrinsicMinimums: + case GridItemContributionType::kForContentBasedMinimums: + case GridItemContributionType::kForMaxContentMinimums: return false; - case NGGridItemContributionType::kForIntrinsicMaximums: - case NGGridItemContributionType::kForMaxContentMaximums: + case GridItemContributionType::kForIntrinsicMaximums: + case GridItemContributionType::kForMaxContentMaximums: return true; } } @@ -778,19 +782,19 @@ // as "infinitely growable", and equal to the growth limit otherwise. static LayoutUnit GrowthPotentialForSet( const NGGridSet& set, - NGGridItemContributionType contribution_type, + GridItemContributionType contribution_type, InfinitelyGrowableBehavior infinitely_growable_behavior = InfinitelyGrowableBehavior::kEnforce) { switch (contribution_type) { - case NGGridItemContributionType::kForIntrinsicMinimums: - case NGGridItemContributionType::kForContentBasedMinimums: - case NGGridItemContributionType::kForMaxContentMinimums: { + case GridItemContributionType::kForIntrinsicMinimums: + case GridItemContributionType::kForContentBasedMinimums: + case GridItemContributionType::kForMaxContentMinimums: { LayoutUnit growth_limit = set.GrowthLimit(); return (growth_limit == kIndefiniteSize) ? kIndefiniteSize : growth_limit - set.BaseSize(); } - case NGGridItemContributionType::kForIntrinsicMaximums: - case NGGridItemContributionType::kForMaxContentMaximums: { + case GridItemContributionType::kForIntrinsicMaximums: + case GridItemContributionType::kForMaxContentMaximums: { if (infinitely_growable_behavior == InfinitelyGrowableBehavior::kEnforce && !set.IsInfinitelyGrowable()) { @@ -826,7 +830,7 @@ // notice that this method replaces the notion of "tracks" with "sets". void NGGridLayoutAlgorithm::DistributeExtraSpaceToSets( LayoutUnit extra_space, - NGGridItemContributionType contribution_type, + GridItemContributionType contribution_type, NGGridSetVector* sets_to_grow, NGGridSetVector* sets_to_grow_beyond_limit) { DCHECK(sets_to_grow && extra_space >= 0); @@ -968,7 +972,7 @@ GridTrackSizingDirection track_direction, ReorderedGridItems::Iterator group_begin, ReorderedGridItems::Iterator group_end, - NGGridItemContributionType contribution_type) { + GridItemContributionType contribution_type) { auto& track_collection = TrackCollection(track_direction); for (auto set_iterator = track_collection.GetSetIterator(); !set_iterator.IsAtEnd(); set_iterator.MoveToNextSet()) { @@ -1075,7 +1079,7 @@ IncreaseTrackSizesToAccommodateGridItems( track_direction, current_group_begin, current_group_end, - NGGridItemContributionType::kForIntrinsicMinimums); + GridItemContributionType::kForIntrinsicMinimums); // TODO(ethavar): Add remaining stages, mark infinitely growable sets... current_group_begin = current_group_end;
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h index df08a06..144a396 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
@@ -14,26 +14,25 @@ namespace blink { -// This enum corresponds to each step used to accommodate grid items across -// intrinsic tracks according to their min and max track sizing functions, as -// defined in https://drafts.csswg.org/css-grid-1/#algo-spanning-items. -enum class NGGridItemContributionType { - kForIntrinsicMinimums, - kForContentBasedMinimums, - kForMaxContentMinimums, - kForIntrinsicMaximums, - kForMaxContentMaximums -}; - -enum class AutoPlacementType { kNotNeeded, kMajor, kMinor, kBoth }; - class CORE_EXPORT NGGridLayoutAlgorithm : public NGLayoutAlgorithm<NGBlockNode, NGBoxFragmentBuilder, NGBlockBreakToken> { public: + enum class AutoPlacementType { kNotNeeded, kMajor, kMinor, kBoth }; enum class AxisEdge { kStart, kCenter, kEnd, kBaseline }; + // This enum corresponds to each step used to accommodate grid items across + // intrinsic tracks according to their min and max track sizing functions, as + // defined in https://drafts.csswg.org/css-grid-1/#algo-spanning-items. + enum class GridItemContributionType { + kForIntrinsicMinimums, + kForContentBasedMinimums, + kForMaxContentMinimums, + kForIntrinsicMaximums, + kForMaxContentMaximums + }; + struct GridItemData { explicit GridItemData(const NGBlockNode node); @@ -136,7 +135,7 @@ LayoutUnit ContributionSizeForGridItem( const GridItemData& grid_item, GridTrackSizingDirection track_direction, - NGGridItemContributionType contribution_type) const; + GridItemContributionType contribution_type) const; void ConstructAndAppendGridItems(); GridItemData MeasureGridItem(const NGBlockNode node); @@ -166,9 +165,9 @@ GridTrackSizingDirection track_direction, ReorderedGridItems::Iterator group_begin, ReorderedGridItems::Iterator group_end, - NGGridItemContributionType contribution_type); + GridItemContributionType contribution_type); void DistributeExtraSpaceToSets(LayoutUnit extra_space, - NGGridItemContributionType contribution_type, + GridItemContributionType contribution_type, NGGridSetVector* sets_to_grow, NGGridSetVector* sets_to_grow_beyond_limit);
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_placement.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_placement.cc index e19c2b2..9744716 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_placement.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_placement.cc
@@ -58,12 +58,16 @@ for (NGGridLayoutAlgorithm::GridItemData* grid_item : items_not_locked_to_major_axis_) { DCHECK(grid_item); - const AutoPlacementType item_placement_type = - grid_item->AutoPlacement(major_direction_); - if (item_placement_type == AutoPlacementType::kMajor) { - PlaceAutoMajorAxisGridItem(*grid_item); - } else if (item_placement_type == AutoPlacementType::kBoth) { - PlaceAutoBothAxisGridItem(*grid_item); + switch (grid_item->AutoPlacement(major_direction_)) { + case NGGridLayoutAlgorithm::AutoPlacementType::kBoth: + PlaceAutoBothAxisGridItem(*grid_item); + break; + case NGGridLayoutAlgorithm::AutoPlacementType::kMajor: + PlaceAutoMajorAxisGridItem(*grid_item); + break; + case NGGridLayoutAlgorithm::AutoPlacementType::kMinor: + case NGGridLayoutAlgorithm::AutoPlacementType::kNotNeeded: + break; } } } @@ -99,7 +103,7 @@ items_locked_to_major_axis_) { DCHECK(grid_item); DCHECK_EQ(grid_item->AutoPlacement(major_direction_), - AutoPlacementType::kMinor); + NGGridLayoutAlgorithm::AutoPlacementType::kMinor); wtf_size_t minor_start; if (packing_behavior_ == PackingBehavior::kSparse && minor_cursors.Contains(grid_item->StartLine(major_direction_) + 1)) {
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc index 85d4c23a..c57bcf6 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
@@ -129,6 +129,11 @@ return LayoutObjectFactory::CreateAnonymousTableCellWithParent(*parent); } +LayoutBlock* LayoutNGTableCell::StickyContainer() const { + NOT_DESTROYED(); + return Table(); +} + bool LayoutNGTableCell::BackgroundIsKnownToBeOpaqueInRect( const PhysicalRect& local_rect) const { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h index a3e638b..bc5e82401 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
@@ -87,6 +87,8 @@ LayoutBox* CreateAnonymousBoxWithSameTypeAs( const LayoutObject* parent) const override; + LayoutBlock* StickyContainer() const override; + // LayoutBlockFlow methods end. // LayoutNGTableCellInterface methods start.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc index 98fe9be..c101bfbb 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc
@@ -105,6 +105,11 @@ return LayoutObjectFactory::CreateAnonymousTableRowWithParent(*parent); } +LayoutBlock* LayoutNGTableRow::StickyContainer() const { + NOT_DESTROYED(); + return Table(); +} + // This is necessary because TableRow paints beyond border box if it contains // rowspanned cells. void LayoutNGTableRow::AddVisualOverflowFromBlockChildren() {
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h index 3e24e38..2a2513c 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h
@@ -46,6 +46,8 @@ LayoutBox* CreateAnonymousBoxWithSameTypeAs( const LayoutObject* parent) const override; + LayoutBlock* StickyContainer() const override; + // Whether a row has opaque background depends on many factors, e.g. border // spacing, border collapsing, missing cells, etc. // For simplicity, just conservatively assume all table rows are not opaque.
diff --git a/third_party/blink/renderer/core/page/page_animator.cc b/third_party/blink/renderer/core/page/page_animator.cc index a3cf9c9..91bd40f 100644 --- a/third_party/blink/renderer/core/page/page_animator.cc +++ b/third_party/blink/renderer/core/page/page_animator.cc
@@ -140,13 +140,12 @@ view->UpdateAllLifecyclePhases(reason); } -void PageAnimator::UpdateAllLifecyclePhasesExceptPaint( - LocalFrame& root_frame, - DocumentUpdateReason reason) { +void PageAnimator::UpdateLifecycleToPrePaintClean(LocalFrame& root_frame, + DocumentUpdateReason reason) { LocalFrameView* view = root_frame.View(); base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_, true); - view->UpdateAllLifecyclePhasesExceptPaint(reason); + view->UpdateLifecycleToPrePaintClean(reason); } void PageAnimator::UpdateLifecycleToLayoutClean(LocalFrame& root_frame,
diff --git a/third_party/blink/renderer/core/page/page_animator.h b/third_party/blink/renderer/core/page/page_animator.h index efce1740..b9e3406 100644 --- a/third_party/blink/renderer/core/page/page_animator.h +++ b/third_party/blink/renderer/core/page/page_animator.h
@@ -43,8 +43,8 @@ // See documents of methods with the same names in LocalFrameView class. void UpdateAllLifecyclePhases(LocalFrame& root_frame, DocumentUpdateReason reason); - void UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame, - DocumentUpdateReason reason); + void UpdateLifecycleToPrePaintClean(LocalFrame& root_frame, + DocumentUpdateReason reason); void UpdateLifecycleToLayoutClean(LocalFrame& root_frame, DocumentUpdateReason reason); AnimationClock& Clock() { return animation_clock_; }
diff --git a/third_party/blink/renderer/core/page/page_widget_delegate.cc b/third_party/blink/renderer/core/page/page_widget_delegate.cc index e2fec977..7276be98a 100644 --- a/third_party/blink/renderer/core/page/page_widget_delegate.cc +++ b/third_party/blink/renderer/core/page/page_widget_delegate.cc
@@ -67,7 +67,7 @@ if (requested_update == WebLifecycleUpdate::kLayout) { page.Animator().UpdateLifecycleToLayoutClean(root, reason); } else if (requested_update == WebLifecycleUpdate::kPrePaint) { - page.Animator().UpdateAllLifecyclePhasesExceptPaint(root, reason); + page.Animator().UpdateLifecycleToPrePaintClean(root, reason); } else { page.Animator().UpdateAllLifecyclePhases(root, reason); }
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index a9231c68..3a07bc8 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -1597,22 +1597,24 @@ } void PaintLayer::UpdateScrollableArea() { - if (RequiresScrollableArea() && !scrollable_area_) { + if (RequiresScrollableArea() == !!scrollable_area_) + return; + + if (!scrollable_area_) { scrollable_area_ = MakeGarbageCollected<PaintLayerScrollableArea>(*this); - if (Compositor()) { - Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree); - } - GetLayoutObject().SetNeedsPaintPropertyUpdate(); - } else if (!RequiresScrollableArea() && scrollable_area_) { + } else { scrollable_area_->Dispose(); scrollable_area_.Clear(); - if (Compositor()) { - Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree); - } GetLayoutObject().SetBackgroundPaintLocation( kBackgroundPaintInGraphicsLayer); - GetLayoutObject().SetNeedsPaintPropertyUpdate(); } + + GetLayoutObject().SetNeedsPaintPropertyUpdate(); + // Need to update z-ordering of overlay overflow controls. + if (!scrollable_area_ || NeedsReorderOverlayOverflowControls()) + DirtyStackingContextZOrderLists(); + if (auto* compositor = Compositor()) + compositor->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree); } bool PaintLayer::HasOverflowControls() const {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc index 7c5a701..2add15f 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc
@@ -61,7 +61,7 @@ // in order to determine if we isStacked() we have to ask the paint // layer about some of its state. PaintLayerStackingNode::PaintLayerStackingNode(PaintLayer& layer) - : layer_(layer), z_order_lists_dirty_(true) { + : layer_(layer) { DCHECK(layer.GetLayoutObject().IsStackingContext()); }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h index 9f5b6e9..2d9a544a 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h +++ b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h
@@ -201,7 +201,7 @@ PaintLayers overlay_overflow_controls_reordered_list_; // Indicates whether the z-order lists above are dirty. - bool z_order_lists_dirty_ : 1; + bool z_order_lists_dirty_ = true; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc index 49abbec..6d0eb2a 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -465,11 +465,17 @@ void InitOverflowStyle(const char* id) { GetDocument().getElementById(id)->setAttribute( html_names::kStyleAttr, GetOverlayType() == kOverlayScrollbars - ? "overflow : auto" + ? "overflow: auto" : "overflow: hidden; resize: both"); UpdateAllLifecyclePhasesForTest(); } + void RemoveOverflowStyle(const char* id) { + GetDocument().getElementById(id)->setAttribute(html_names::kStyleAttr, + "overflow: visible"); + UpdateAllLifecyclePhasesForTest(); + } + void SetUp() override { EnableCompositing(); RenderingTest::SetUp(); @@ -542,14 +548,14 @@ TEST_P(ReorderOverlayOverflowControlsTest, StackedWithOutOfFlowDescendant) { SetBodyInnerHTML(R"HTML( <style> - #child { - width: 200px; - height: 200px; - } #parent { position: relative; height: 100px; } + #child { + width: 200px; + height: 200px; + } </style> <div id='parent'> <div id='child' style='position: absolute'></div> @@ -1008,6 +1014,42 @@ EXPECT_TRUE(LayersPaintingOverlayOverflowControlsAfter(child)); } +TEST_P(ReorderOverlayOverflowControlsTest, AddRemoveScrollableArea) { + SetBodyInnerHTML(R"HTML( + <style> + #parent { + position: relative; + height: 100px; + } + #child { + position: absolute; + width: 200px; + height: 200px; + } + </style> + <div id='parent'> + <div id='child'></div> + </div> + )HTML"); + + auto* parent = GetPaintLayerByElementId("parent"); + auto* child = GetPaintLayerByElementId("child"); + EXPECT_FALSE(parent->GetScrollableArea()); + EXPECT_FALSE(parent->NeedsReorderOverlayOverflowControls()); + EXPECT_FALSE(LayersPaintingOverlayOverflowControlsAfter(child)); + + InitOverflowStyle("parent"); + EXPECT_TRUE(parent->GetScrollableArea()); + EXPECT_TRUE(parent->NeedsReorderOverlayOverflowControls()); + EXPECT_THAT(LayersPaintingOverlayOverflowControlsAfter(child), + Pointee(ElementsAre(parent))); + + RemoveOverflowStyle("parent"); + EXPECT_FALSE(parent->GetScrollableArea()); + EXPECT_FALSE(parent->NeedsReorderOverlayOverflowControls()); + EXPECT_FALSE(LayersPaintingOverlayOverflowControlsAfter(child)); +} + TEST_P(PaintLayerTest, SubsequenceCachingStackedLayers) { SetBodyInnerHTML(R"HTML( <div id='parent' style='position:relative'>
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc index 9bf9c4b..c61e07f 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -401,62 +401,71 @@ auto* iframe = To<HTMLIFrameElement>(GetDocument().getElementById("iframe")); iframe->setAttribute(html_names::kStyleAttr, "transform: translateY(5555px)"); UpdateAllLifecyclePhasesForTest(); - // Ensure intersection observer notifications get delivered. - test::RunPendingTasks(); EXPECT_FALSE(GetDocument().View()->IsHiddenForThrottling()); + EXPECT_FALSE(GetDocument().View()->ShouldThrottleRenderingForTest()); EXPECT_TRUE(ChildDocument().View()->IsHiddenForThrottling()); + EXPECT_TRUE(ChildDocument().View()->ShouldThrottleRenderingForTest()); auto* transform = GetLayoutObjectByElementId("transform"); auto* iframe_layout_view = ChildDocument().GetLayoutView(); auto* iframe_transform = ChildDocument().getElementById("iframeTransform")->GetLayoutObject(); - // Invalidate properties in the iframe and ensure ancestors are marked. + // Invalidate properties in the iframe; invalidations will be propagated from + // the throttled frame into the embedding document. iframe_transform->SetNeedsPaintPropertyUpdate(); + iframe_transform->SetShouldCheckForPaintInvalidation(); EXPECT_FALSE(GetDocument().GetLayoutView()->NeedsPaintPropertyUpdate()); EXPECT_TRUE( GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate()); + EXPECT_TRUE(GetDocument().GetLayoutView()->ShouldCheckForPaintInvalidation()); EXPECT_FALSE(transform->NeedsPaintPropertyUpdate()); EXPECT_FALSE(transform->DescendantNeedsPaintPropertyUpdate()); + EXPECT_FALSE(transform->ShouldCheckForPaintInvalidation()); EXPECT_FALSE(iframe_layout_view->NeedsPaintPropertyUpdate()); EXPECT_TRUE(iframe_layout_view->DescendantNeedsPaintPropertyUpdate()); + EXPECT_TRUE(iframe_layout_view->ShouldCheckForPaintInvalidation()); EXPECT_TRUE(iframe_transform->NeedsPaintPropertyUpdate()); EXPECT_FALSE(iframe_transform->DescendantNeedsPaintPropertyUpdate()); + EXPECT_TRUE(iframe_transform->ShouldCheckForPaintInvalidation()); + // Invalidate properties in the top document. transform->SetNeedsPaintPropertyUpdate(); + EXPECT_FALSE(GetDocument().GetLayoutView()->NeedsPaintPropertyUpdate()); + EXPECT_TRUE( + GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate()); EXPECT_TRUE(transform->NeedsPaintPropertyUpdate()); EXPECT_FALSE(transform->DescendantNeedsPaintPropertyUpdate()); - EXPECT_FALSE(GetDocument().View()->ShouldThrottleRenderingForTest()); - EXPECT_TRUE(ChildDocument().View()->ShouldThrottleRenderingForTest()); - - // A lifecycle update should update all properties except those with - // actively throttled descendants. + // A full lifecycle update with the iframe throttled will clear flags in the + // top document, but not in the throttled iframe. The iframe's LayoutView + // will be marked for paint property update because it was skipped while + // paint properties were updated in the embedding document. UpdateAllLifecyclePhasesForTest(); EXPECT_FALSE(GetDocument().GetLayoutView()->NeedsPaintPropertyUpdate()); EXPECT_FALSE( GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate()); EXPECT_FALSE(transform->NeedsPaintPropertyUpdate()); EXPECT_FALSE(transform->DescendantNeedsPaintPropertyUpdate()); - EXPECT_FALSE(iframe_layout_view->NeedsPaintPropertyUpdate()); + EXPECT_TRUE(iframe_layout_view->NeedsPaintPropertyUpdate()); EXPECT_TRUE(iframe_layout_view->DescendantNeedsPaintPropertyUpdate()); + EXPECT_TRUE(iframe_layout_view->ShouldCheckForPaintInvalidation()); EXPECT_TRUE(iframe_transform->NeedsPaintPropertyUpdate()); EXPECT_FALSE(iframe_transform->DescendantNeedsPaintPropertyUpdate()); + EXPECT_TRUE(iframe_transform->ShouldCheckForPaintInvalidation()); - EXPECT_FALSE(GetDocument().View()->ShouldThrottleRendering()); - EXPECT_FALSE(ChildDocument().View()->ShouldThrottleRendering()); - // Once unthrottled, a lifecycel update should update all properties. - GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling( + // Run a force-unthrottled lifecycle update. All flags should be cleared. + GetDocument().View()->UpdateLifecycleToPrePaintClean( DocumentUpdateReason::kTest); - EXPECT_FALSE(GetDocument().GetLayoutView()->NeedsPaintPropertyUpdate()); EXPECT_FALSE( GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate()); - EXPECT_FALSE(transform->NeedsPaintPropertyUpdate()); EXPECT_FALSE(transform->DescendantNeedsPaintPropertyUpdate()); EXPECT_FALSE(iframe_layout_view->NeedsPaintPropertyUpdate()); EXPECT_FALSE(iframe_layout_view->DescendantNeedsPaintPropertyUpdate()); + EXPECT_FALSE(iframe_layout_view->ShouldCheckForPaintInvalidation()); EXPECT_FALSE(iframe_transform->NeedsPaintPropertyUpdate()); EXPECT_FALSE(iframe_transform->DescendantNeedsPaintPropertyUpdate()); + EXPECT_FALSE(iframe_transform->ShouldCheckForPaintInvalidation()); } TEST_P(PaintPropertyTreeUpdateTest, ClipChangesUpdateOverflowClip) {
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc index 9ecfc82..cae05e9 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -233,11 +233,6 @@ } void PrePaintTreeWalk::Walk(LocalFrameView& frame_view) { - if (frame_view.ShouldThrottleRendering()) { - // Skip the throttled frame. Will update it when it becomes unthrottled. - return; - } - // We need to be careful not to have a reference to the parent context, since // this reference will be to the context_storage_ memory which may be // reallocated during this function call. @@ -250,6 +245,25 @@ bool needs_tree_builder_context_update = NeedsTreeBuilderContextUpdate(frame_view, parent_context()); + if (frame_view.ShouldThrottleRendering()) { + // Skip the throttled frame, and set dirty bits that will be applied when it + // becomes unthrottled. + frame_view.SetPrePaintSkippedWhileThrottled(); + if (LayoutView* layout_view = frame_view.GetLayoutView()) { + if (needs_tree_builder_context_update) { + layout_view->AddSubtreePaintPropertyUpdateReason( + SubtreePaintPropertyUpdateReason::kPreviouslySkipped); + } + if (parent_context().paint_invalidator_context.NeedsSubtreeWalk()) + layout_view->SetSubtreeShouldDoFullPaintInvalidation(); + if (parent_context().effective_allowed_touch_action_changed) + layout_view->MarkEffectiveAllowedTouchActionChanged(); + if (parent_context().blocking_wheel_event_handler_changed) + layout_view->MarkBlockingWheelEventHandlerChanged(); + } + return; + } + // Note that because we're emplacing an object constructed from // parent_context() (which is a reference to the vector itself), it's // important to first ensure that there's sufficient capacity in the vector.
diff --git a/third_party/blink/renderer/core/streams/count_queuing_strategy.cc b/third_party/blink/renderer/core/streams/count_queuing_strategy.cc index bfd6d1f..98ca424 100644 --- a/third_party/blink/renderer/core/streams/count_queuing_strategy.cc +++ b/third_party/blink/renderer/core/streams/count_queuing_strategy.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h" #include "third_party/blink/renderer/core/streams/queuing_strategy_common.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/bindings/v8_binding.h" #include "third_party/blink/renderer/platform/heap/visitor.h" namespace blink {
diff --git a/third_party/blink/renderer/core/streams/readable_stream.cc b/third_party/blink/renderer/core/streams/readable_stream.cc index b79380a..ba9f6e0 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.cc +++ b/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -10,6 +10,9 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_abort_signal.h" #include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream_get_reader_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_readable_writable_pair.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/bindings/core/v8/v8_writable_stream.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" @@ -19,10 +22,7 @@ #include "third_party/blink/renderer/core/streams/promise_handler.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_controller.h" #include "third_party/blink/renderer/core/streams/readable_stream_generic_reader.h" -#include "third_party/blink/renderer/core/streams/readable_stream_get_reader_options.h" -#include "third_party/blink/renderer/core/streams/readable_writable_pair.h" #include "third_party/blink/renderer/core/streams/stream_algorithms.h" -#include "third_party/blink/renderer/core/streams/stream_pipe_options.h" #include "third_party/blink/renderer/core/streams/stream_promise_resolver.h" #include "third_party/blink/renderer/core/streams/transferable_streams.h" #include "third_party/blink/renderer/core/streams/underlying_source_base.h"
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h index af13e114..5677fe37 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h +++ b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_H_ +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_trusted_type_policy_options.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
diff --git a/third_party/blink/renderer/core/xml/dom_parser.cc b/third_party/blink/renderer/core/xml/dom_parser.cc index 949b2d9..f2345ba 100644 --- a/third_party/blink/renderer/core/xml/dom_parser.cc +++ b/third_party/blink/renderer/core/xml/dom_parser.cc
@@ -19,10 +19,10 @@ #include "third_party/blink/renderer/core/xml/dom_parser.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_parse_from_string_options.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document_init.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" -#include "third_party/blink/renderer/core/xml/parse_from_string_options.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/modules/accessibility/BUILD.gn b/third_party/blink/renderer/modules/accessibility/BUILD.gn index c4724fb..87f1b2f 100644 --- a/third_party/blink/renderer/modules/accessibility/BUILD.gn +++ b/third_party/blink/renderer/modules/accessibility/BUILD.gn
@@ -40,8 +40,6 @@ "ax_position.h", "ax_progress_indicator.cc", "ax_progress_indicator.h", - "ax_radio_input.cc", - "ax_radio_input.h", "ax_range.cc", "ax_range.h", "ax_relation_cache.cc",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index fc3fbd3..30654af 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -400,7 +400,7 @@ const LayoutObject* layout_object = GetLayoutObject(); if (layout_object->IsBR() || layout_object->IsLayoutBlock() || - layout_object->IsAnonymousBlock() || + layout_object->IsTableSection() || layout_object->IsAnonymousBlock() || (layout_object->IsLayoutBlockFlow() && layout_object->StyleRef().IsDisplayBlockContainer())) { return true;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 0987cd4..71e0e29 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -532,10 +532,6 @@ return IsListElement(parent_node); if (current_role == ax::mojom::blink::Role::kListMarker) return IsA<HTMLLIElement>(*parent_node); - if (current_role == ax::mojom::blink::Role::kMenuItemCheckBox || - current_role == ax::mojom::blink::Role::kMenuItem || - current_role == ax::mojom::blink::Role::kMenuItemRadio) - return IsA<HTMLMenuElement>(*parent_node); if (!current_element) return false; @@ -1288,14 +1284,6 @@ return html_select_element && html_select_element->IsMultiple(); } -bool AXNodeObject::IsNativeCheckboxOrRadio() const { - if (const auto* input = DynamicTo<HTMLInputElement>(GetNode())) { - return input->type() == input_type_names::kCheckbox || - input->type() == input_type_names::kRadio; - } - return false; -} - bool AXNodeObject::IsNativeImage() const { Node* node = this->GetNode(); if (!node) @@ -3225,59 +3213,6 @@ children_.push_back(ax_object); } -// Hidden children are those that are not laid out or visible, but are -// specifically marked as aria-hidden=false, -// meaning that they should be exposed to the AX hierarchy. -void AXNodeObject::AddHiddenChildren() { - Node* node = this->GetNode(); - if (!node) - return; - - // First do a quick run through to determine if we have any hidden nodes (most - // often we will not). If we do have hidden nodes, we need to determine where - // to insert them so they match DOM order as close as possible. - bool should_insert_hidden_nodes = false; - for (Node& child : NodeTraversal::ChildrenOf(*node)) { - if (!child.GetLayoutObject() && IsNodeAriaVisible(&child)) { - should_insert_hidden_nodes = true; - break; - } - } - - if (!should_insert_hidden_nodes) - return; - - // Iterate through all of the children, including those that may have already - // been added, and try to insert hidden nodes in the correct place in the DOM - // order. - unsigned insertion_index = 0; - for (Node& child : NodeTraversal::ChildrenOf(*node)) { - if (child.GetLayoutObject()) { - // Find out where the last layout sibling is located within children_. - if (AXObject* child_object = - AXObjectCache().Get(child.GetLayoutObject())) { - if (!child_object->AccessibilityIsIncludedInTree()) { - const auto& children = child_object->ChildrenIncludingIgnored(); - child_object = children.size() ? children.back().Get() : nullptr; - } - if (child_object) - insertion_index = children_.Find(child_object) + 1; - continue; - } - } - - if (!IsNodeAriaVisible(&child)) - continue; - - unsigned previous_size = children_.size(); - if (insertion_index > previous_size) - insertion_index = previous_size; - - InsertChild(AXObjectCache().GetOrCreate(&child), insertion_index); - insertion_index += (children_.size() - previous_size); - } -} - void AXNodeObject::AddImageMapChildren() { LayoutBoxModelObject* css_box = GetLayoutBoxModelObject(); if (!css_box || !css_box->IsLayoutImage()) @@ -3411,7 +3346,6 @@ } } - AddHiddenChildren(); AddPopupChildren(); AddRemoteSVGChildren(); AddImageMapChildren();
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/third_party/blink/renderer/modules/accessibility/ax_node_object.h index 6cf1fb75..6f03bf3 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -77,7 +77,6 @@ bool IsTextControl() const override; Element* MenuItemElementForMenu() const; Element* MouseButtonListener() const; - bool IsNativeCheckboxOrRadio() const; void SetNode(Node*); AXObject* CorrespondingControlAXObjectForLabelElement() const; AXObject* CorrespondingLabelAXObject() const; @@ -142,9 +141,13 @@ Vector<AXRange>* marker_ranges) const override; AXObject* InPageLinkTarget() const override; AccessibilityOrientation Orientation() const override; + + // Used to compute kRadioGroupIds, which is only used on Mac. + // TODO(accessibility) Consider computing on browser side and removing here. AXObjectVector RadioButtonsInGroup() const override; static HeapVector<Member<HTMLInputElement>> FindAllRadioButtonsWithSameName( HTMLInputElement* radio_button); + String GetText() const override; String ImageDataUrl(const IntSize& max_size) const final; int TextLength() const override;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 838d353..11742bb 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1254,12 +1254,17 @@ return RoleValue() == ax::mojom::blink::Role::kCanvas; } -bool AXObject::IsCheckbox() const { - return RoleValue() == ax::mojom::blink::Role::kCheckBox; -} - bool AXObject::IsCheckboxOrRadio() const { - return IsCheckbox() || IsRadioButton(); + switch (RoleValue()) { + case ax::mojom::blink::Role::kCheckBox: + case ax::mojom::blink::Role::kMenuItemCheckBox: + case ax::mojom::blink::Role::kMenuItemRadio: + case ax::mojom::blink::Role::kRadioButton: + return true; + default: + break; + } + return false; } bool AXObject::IsColorWell() const {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index 30053b651..bb760a4 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -428,7 +428,6 @@ bool IsAnchor() const; bool IsButton() const; bool IsCanvas() const; - bool IsCheckbox() const; bool IsCheckboxOrRadio() const; bool IsColorWell() const; virtual bool IsControl() const; @@ -453,9 +452,6 @@ virtual bool IsPasswordField() const; bool IsPasswordFieldAndShouldHideValue() const; bool IsPresentational() const; - bool IsRadioButton() const { - return RoleValue() == ax::mojom::blink::Role::kRadioButton; - } bool IsRangeValueSupported() const; bool IsScrollbar() const { return RoleValue() == ax::mojom::blink::Role::kScrollBar;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index 6189d03..24a26387 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -84,7 +84,6 @@ #include "third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h" #include "third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h" #include "third_party/blink/renderer/modules/accessibility/ax_progress_indicator.h" -#include "third_party/blink/renderer/modules/accessibility/ax_radio_input.h" #include "third_party/blink/renderer/modules/accessibility/ax_relation_cache.h" #include "third_party/blink/renderer/modules/accessibility/ax_slider.h" #include "third_party/blink/renderer/modules/accessibility/ax_svg_root.h" @@ -465,8 +464,6 @@ if (auto* html_input_element = DynamicTo<HTMLInputElement>(node)) { const AtomicString& type = html_input_element->type(); - if (type == input_type_names::kRadio) - return MakeGarbageCollected<AXRadioInput>(layout_object, *this); if (type == input_type_names::kRange) return MakeGarbageCollected<AXSlider>(layout_object, *this); } @@ -1625,27 +1622,6 @@ PostNotification(layout_object, ax::mojom::Event::kLocationChanged); } -void AXObjectCacheImpl::RadiobuttonRemovedFromGroup( - HTMLInputElement* group_member) { - SCOPED_DISALLOW_LIFECYCLE_TRANSITION(group_member->GetDocument()); - - auto* ax_object = DynamicTo<AXRadioInput>(Get(group_member)); - if (!ax_object) - return; - - // The 'posInSet' and 'setSize' attributes should be updated from the first - // node, as the removed node is already detached from tree. - auto* first_radio = ax_object->FindFirstRadioButtonInGroup(group_member); - AXObject* first_obj = Get(first_radio); - auto* ax_first_obj = DynamicTo<AXRadioInput>(first_obj); - if (!ax_first_obj) - return; - - ax_first_obj->UpdatePosAndSetSize(1); - PostNotification(first_obj, ax::mojom::Event::kAriaAttributeChanged); - ax_first_obj->RequestUpdateToNextNode(true); -} - void AXObjectCacheImpl::ImageLoaded(const LayoutObject* layout_object) { AXObject* obj = Get(layout_object); MarkAXObjectDirty(obj, false);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index a86d912..210320f 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -97,7 +97,6 @@ void ListboxSelectedChildrenChanged(HTMLSelectElement*) override; void ListboxActiveIndexChanged(HTMLSelectElement*) override; void LocationChanged(const LayoutObject*) override; - void RadiobuttonRemovedFromGroup(HTMLInputElement*) override; void ImageLoaded(const LayoutObject*) override; void Remove(AccessibleNode*) override;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_position_test.cc b/third_party/blink/renderer/modules/accessibility/ax_position_test.cc index 56a29df..b653528 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_position_test.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
@@ -1472,10 +1472,14 @@ TEST_F(AccessibilityTest, PositionAtStartAndEndOfTable) { SetBodyInnerHTML(kHTMLTable); - // In the accessibility tree, the thead and tbody elements are ignored, but - // they are used as anchors when converting an AX position to a DOM position - // because they are the closest anchor to the first and last unignored AX - // positions inside the table. + // In the accessibility tree, the thead and tbody elements are accessibility + // ignored but included in the AXTree. + // Calling CreateFirstPositionInObject and CreateLastPositionInObject with the + // |table| element will create a position anchored to |table| which points to + // the |thead| element and the last whitespace text node within the table + // respectively. + const Node* table = GetElementById("table"); + ASSERT_NE(nullptr, table); const Node* thead = GetElementById("thead"); ASSERT_NE(nullptr, thead); const Node* header_row = GetElementById("headerRow"); @@ -1490,26 +1494,25 @@ ASSERT_NE(nullptr, ax_header_row); ASSERT_EQ(ax::mojom::Role::kRow, ax_header_row->RoleValue()); + const AXObject* ax_thead = GetAXObjectByElementId("thead"); const auto ax_position_at_start = AXPosition::CreateFirstPositionInObject(*ax_table); const auto position_at_start = ax_position_at_start.ToPositionWithAffinity(); - EXPECT_EQ(thead, position_at_start.AnchorNode()); + EXPECT_EQ(table, position_at_start.AnchorNode()); EXPECT_EQ(1, position_at_start.GetPosition().OffsetInContainerNode()); - EXPECT_EQ(header_row, - position_at_start.GetPosition().ComputeNodeAfterPosition()); + EXPECT_EQ(thead, position_at_start.GetPosition().ComputeNodeAfterPosition()); const auto ax_position_at_start_from_dom = AXPosition::FromPosition(position_at_start); EXPECT_EQ(ax_position_at_start, ax_position_at_start_from_dom); - EXPECT_EQ(ax_header_row, - ax_position_at_start_from_dom.ChildAfterTreePosition()); + EXPECT_EQ(ax_thead, ax_position_at_start_from_dom.ChildAfterTreePosition()); const auto ax_position_at_end = AXPosition::CreateLastPositionInObject(*ax_table); const auto position_at_end = ax_position_at_end.ToPositionWithAffinity(); - EXPECT_EQ(tbody, position_at_end.AnchorNode()); + EXPECT_EQ(table, position_at_end.AnchorNode()); // There are three rows and a line break before and after each one. - EXPECT_EQ(6, position_at_end.GetPosition().OffsetInContainerNode()); + EXPECT_EQ(4, position_at_end.GetPosition().OffsetInContainerNode()); const auto ax_position_at_end_from_dom = AXPosition::FromPosition(position_at_end);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc b/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc deleted file mode 100644 index 18e5c357..0000000 --- a/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc +++ /dev/null
@@ -1,132 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/modules/accessibility/ax_radio_input.h" - -#include "third_party/blink/renderer/core/aom/accessible_node.h" -#include "third_party/blink/renderer/core/html/forms/html_input_element.h" -#include "third_party/blink/renderer/core/html/forms/radio_input_type.h" -#include "third_party/blink/renderer/core/input_type_names.h" -#include "third_party/blink/renderer/core/layout/layout_object.h" -#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" - -namespace blink { - -AXRadioInput::AXRadioInput(LayoutObject* layout_object, - AXObjectCacheImpl& ax_object_cache) - : AXLayoutObject(layout_object, ax_object_cache) { - // Updates posInSet and setSize for the current object and the next objects. - if (!CalculatePosInSet()) - return; - // When a new object is inserted, it needs to update setSize for the previous - // objects. - RequestUpdateToNextNode(false); -} - -void AXRadioInput::UpdatePosAndSetSize(int position) { - if (position) - pos_in_set_ = position; - set_size_ = SizeOfRadioGroup(); -} - -void AXRadioInput::RequestUpdateToNextNode(bool forward) { - HTMLInputElement* next_element = - RadioInputType::NextRadioButtonInGroup(GetInputElement(), forward); - AXObject* next_axobject = AXObjectCache().Get(next_element); - auto* ax_radio_input = DynamicTo<AXRadioInput>(next_axobject); - if (!ax_radio_input) - return; - - int position = 0; - if (forward) - position = PosInSet() + 1; - // If it is backward, it keeps position as positions are already assigned for - // previous objects. updatePosAndSetSize() is called with '0' and it doesn't - // modify m_posInSet and updates m_setSize as size is increased. - - ax_radio_input->UpdatePosAndSetSize(position); - AXObjectCache().PostNotification(next_axobject, - ax::mojom::Event::kAriaAttributeChanged); - ax_radio_input->RequestUpdateToNextNode(forward); -} - -HTMLInputElement* AXRadioInput::FindFirstRadioButtonInGroup( - HTMLInputElement* current) const { - while (HTMLInputElement* prev_element = - RadioInputType::NextRadioButtonInGroup(current, false)) - current = prev_element; - return current; -} - -int AXRadioInput::PosInSet() const { - uint32_t pos_in_set; - if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kPosInSet, pos_in_set)) - return pos_in_set; - return pos_in_set_; -} - -int AXRadioInput::SetSize() const { - int32_t set_size; - if (HasAOMPropertyOrARIAAttribute(AOMIntProperty::kSetSize, set_size)) - return set_size; - return set_size_; -} - -bool AXRadioInput::CalculatePosInSet() { - // Calculate 'posInSet' attribute when AXRadioInputs need to be updated - // as a new AXRadioInput Object is added or one of objects from RadioGroup is - // removed. - bool need_to_update_prev = false; - int position = 1; - HTMLInputElement* prev_element = - RadioInputType::NextRadioButtonInGroup(GetInputElement(), false); - if (prev_element) { - AXObject* object = AXObjectCache().Get(prev_element); - // If the previous element doesn't have AXObject yet, caculate position - // from the first element. Otherwise, get position from the previous - // AXObject. - if (!object || !object->IsAXRadioInput()) { - position = CountFromFirstElement(); - } else { - position = object->PosInSet() + 1; - // It returns true if previous objects need to be updated. - // When AX tree exists already and a new node is inserted, - // as updating is started from the inserted node, - // we need to update setSize for previous nodes. - if (SetSize() != object->SetSize()) - need_to_update_prev = true; - } - } - UpdatePosAndSetSize(position); - - // If it is not the last element, request update to the next node. - if (position != SetSize()) - RequestUpdateToNextNode(true); - return need_to_update_prev; -} - -int AXRadioInput::CountFromFirstElement() const { - int count = 1; - HTMLInputElement* current = GetInputElement(); - while (HTMLInputElement* prev_element = - RadioInputType::NextRadioButtonInGroup(current, false)) { - current = prev_element; - count++; - } - return count; -} - -HTMLInputElement* AXRadioInput::GetInputElement() const { - return To<HTMLInputElement>(layout_object_->GetNode()); -} - -int AXRadioInput::SizeOfRadioGroup() const { - int size = GetInputElement()->SizeOfRadioGroup(); - // If it has no size in Group, it means that there is only itself. - if (!size) - return 1; - return size; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/accessibility/ax_radio_input.h b/third_party/blink/renderer/modules/accessibility/ax_radio_input.h deleted file mode 100644 index e171357..0000000 --- a/third_party/blink/renderer/modules/accessibility/ax_radio_input.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_RADIO_INPUT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_RADIO_INPUT_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/modules/accessibility/ax_layout_object.h" - -namespace blink { - -class AXObjectCacheImpl; -class HTMLInputElement; - -class AXRadioInput final : public AXLayoutObject { - public: - AXRadioInput(LayoutObject*, AXObjectCacheImpl&); - ~AXRadioInput() override = default; - - bool IsAXRadioInput() const override { return true; } - void UpdatePosAndSetSize(int position = 0); - void RequestUpdateToNextNode(bool forward); - HTMLInputElement* FindFirstRadioButtonInGroup( - HTMLInputElement* current) const; - - int PosInSet() const final; - int SetSize() const final; - - private: - bool CalculatePosInSet(); - int CountFromFirstElement() const; - HTMLInputElement* GetInputElement() const; - int SizeOfRadioGroup() const; - - int pos_in_set_; - int set_size_; - - DISALLOW_COPY_AND_ASSIGN(AXRadioInput); -}; - -template <> -struct DowncastTraits<AXRadioInput> { - static bool AllowFrom(const AXObject& object) { - return object.IsAXRadioInput(); - } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_RADIO_INPUT_H_
diff --git a/third_party/blink/renderer/modules/accessibility/testing/data/selection/table-ax.txt b/third_party/blink/renderer/modules/accessibility/testing/data/selection/table-ax.txt index d37521e6..ff8604f 100644 --- a/third_party/blink/renderer/modules/accessibility/testing/data/selection/table-ax.txt +++ b/third_party/blink/renderer/modules/accessibility/testing/data/selection/table-ax.txt
@@ -5,26 +5,29 @@ ++<GenericContainer> ++++<GenericContainer> ++++++<Table> -++++++++<Row> -++++++++++<ColumnHeader: Sum> -^++++++++++++<StaticText: ^Sum> -++++++++++<ColumnHeader: Subtraction> -++++++++++++<StaticText: Subtraction|> -++++++++<Row> -++++++++++<Cell: 10> -++++++++++++<StaticText: 10> -++++++++++<Cell: 7> -++++++++++++<StaticText: 7> -++++++++<Row> -++++++++++<Cell: 2> -++++++++++++<StaticText: 2> -++++++++++<Cell: 4> -++++++++++++<StaticText: 4> -++++++++<Row> -++++++++++<Cell: 12> -++++++++++++<StaticText: 12> -++++++++++<Cell: 3> -++++++++++++<StaticText: 3> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<ColumnHeader: Sum> +^++++++++++++++<StaticText: ^Sum> +++++++++++++<ColumnHeader: Subtraction> +++++++++++++++<StaticText: Subtraction|> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<Cell: 10> +++++++++++++++<StaticText: 10> +++++++++++++<Cell: 7> +++++++++++++++<StaticText: 7> +++++++++++<Row> +++++++++++++<Cell: 2> +++++++++++++++<StaticText: 2> +++++++++++++<Cell: 4> +++++++++++++++<StaticText: 4> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<Cell: 12> +++++++++++++++<StaticText: 12> +++++++++++++<Cell: 3> +++++++++++++++<StaticText: 3> ================================================================================ AXSelection from AX text position in "StaticText": "7", 1 to AX text position in "StaticText": "10", 0 @@ -32,26 +35,29 @@ ++<GenericContainer> ++++<GenericContainer> ++++++<Table> -++++++++<Row> -++++++++++<ColumnHeader: Sum> -++++++++++++<StaticText: Sum> -++++++++++<ColumnHeader: Subtraction> -++++++++++++<StaticText: Subtraction> -++++++++<Row> -++++++++++<Cell: 10> -|++++++++++++<StaticText: |10> -++++++++++<Cell: 7> -++++++++++++<StaticText: 7^> -++++++++<Row> -++++++++++<Cell: 2> -++++++++++++<StaticText: 2> -++++++++++<Cell: 4> -++++++++++++<StaticText: 4> -++++++++<Row> -++++++++++<Cell: 12> -++++++++++++<StaticText: 12> -++++++++++<Cell: 3> -++++++++++++<StaticText: 3> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<ColumnHeader: Sum> +++++++++++++++<StaticText: Sum> +++++++++++++<ColumnHeader: Subtraction> +++++++++++++++<StaticText: Subtraction> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<Cell: 10> +|++++++++++++++<StaticText: |10> +++++++++++++<Cell: 7> +++++++++++++++<StaticText: 7^> +++++++++++<Row> +++++++++++++<Cell: 2> +++++++++++++++<StaticText: 2> +++++++++++++<Cell: 4> +++++++++++++++<StaticText: 4> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<Cell: 12> +++++++++++++++<StaticText: 12> +++++++++++++<Cell: 3> +++++++++++++++<StaticText: 3> ================================================================================ AXSelection from AX text position in "StaticText": "2", 1 to AX text position in "StaticText": "4", 0 @@ -59,26 +65,29 @@ ++<GenericContainer> ++++<GenericContainer> ++++++<Table> -++++++++<Row> -++++++++++<ColumnHeader: Sum> -++++++++++++<StaticText: Sum> -++++++++++<ColumnHeader: Subtraction> -++++++++++++<StaticText: Subtraction> -++++++++<Row> -++++++++++<Cell: 10> -++++++++++++<StaticText: 10> -++++++++++<Cell: 7> -++++++++++++<StaticText: 7> -++++++++<Row> -++++++++++<Cell: 2> -++++++++++++<StaticText: 2^> -++++++++++<Cell: 4> -|++++++++++++<StaticText: |4> -++++++++<Row> -++++++++++<Cell: 12> -++++++++++++<StaticText: 12> -++++++++++<Cell: 3> -++++++++++++<StaticText: 3> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<ColumnHeader: Sum> +++++++++++++++<StaticText: Sum> +++++++++++++<ColumnHeader: Subtraction> +++++++++++++++<StaticText: Subtraction> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<Cell: 10> +++++++++++++++<StaticText: 10> +++++++++++++<Cell: 7> +++++++++++++++<StaticText: 7> +++++++++++<Row> +++++++++++++<Cell: 2> +++++++++++++++<StaticText: 2^> +++++++++++++<Cell: 4> +|++++++++++++++<StaticText: |4> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<Cell: 12> +++++++++++++++<StaticText: 12> +++++++++++++<Cell: 3> +++++++++++++++<StaticText: 3> ================================================================================ AXSelection from AX text position in "StaticText": "12", 0 to AX text position in "StaticText": "3", 1 @@ -86,23 +95,26 @@ ++<GenericContainer> ++++<GenericContainer> ++++++<Table> -++++++++<Row> -++++++++++<ColumnHeader: Sum> -++++++++++++<StaticText: Sum> -++++++++++<ColumnHeader: Subtraction> -++++++++++++<StaticText: Subtraction> -++++++++<Row> -++++++++++<Cell: 10> -++++++++++++<StaticText: 10> -++++++++++<Cell: 7> -++++++++++++<StaticText: 7> -++++++++<Row> -++++++++++<Cell: 2> -++++++++++++<StaticText: 2> -++++++++++<Cell: 4> -++++++++++++<StaticText: 4> -++++++++<Row> -++++++++++<Cell: 12> -^++++++++++++<StaticText: ^12> -++++++++++<Cell: 3> -++++++++++++<StaticText: 3|> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<ColumnHeader: Sum> +++++++++++++++<StaticText: Sum> +++++++++++++<ColumnHeader: Subtraction> +++++++++++++++<StaticText: Subtraction> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<Cell: 10> +++++++++++++++<StaticText: 10> +++++++++++++<Cell: 7> +++++++++++++++<StaticText: 7> +++++++++++<Row> +++++++++++++<Cell: 2> +++++++++++++++<StaticText: 2> +++++++++++++<Cell: 4> +++++++++++++++<StaticText: 4> +++++++++<RowGroup> +++++++++++<Row> +++++++++++++<Cell: 12> +^++++++++++++++<StaticText: ^12> +++++++++++++<Cell: 3> +++++++++++++++<StaticText: 3|>
diff --git a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc index 3d66740..6866dd3e 100644 --- a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -31,8 +31,10 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_credential_creation_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_credential_instrument.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_creation_options.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_request_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_rp_entity.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_user_entity.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -56,8 +58,6 @@ #include "third_party/blink/renderer/modules/credentialmanager/password_credential.h" #include "third_party/blink/renderer/modules/credentialmanager/payment_credential.h" #include "third_party/blink/renderer/modules/credentialmanager/public_key_credential.h" -#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_descriptor.h" -#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_user_entity.h" #include "third_party/blink/renderer/modules/credentialmanager/scoped_promise_resolver.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/heap.h"
diff --git a/third_party/blink/renderer/modules/file_system_access/native_file_system_writable_file_stream.cc b/third_party/blink/renderer/modules/file_system_access/native_file_system_writable_file_stream.cc index 64c6c20..90e1e1eb 100644 --- a/third_party/blink/renderer/modules/file_system_access/native_file_system_writable_file_stream.cc +++ b/third_party/blink/renderer/modules/file_system_access/native_file_system_writable_file_stream.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_write_params.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/streams/count_queuing_strategy.h" #include "third_party/blink/renderer/core/streams/writable_stream_default_controller.h" #include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc index 8298ee6..d38b297 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
@@ -27,6 +27,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/web_size.h" +#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_configuration.h"
diff --git a/third_party/blink/renderer/modules/mediastream/identifiability_metrics.cc b/third_party/blink/renderer/modules/mediastream/identifiability_metrics.cc index 9e64389f..9ef3ba4 100644 --- a/third_party/blink/renderer/modules/mediastream/identifiability_metrics.cc +++ b/third_party/blink/renderer/modules/mediastream/identifiability_metrics.cc
@@ -15,8 +15,9 @@ #include "third_party/blink/renderer/bindings/modules/v8/long_or_constrain_long_range.h" #include "third_party/blink/renderer/bindings/modules/v8/point_2d_sequence_or_constrain_point_2d_parameters.h" #include "third_party/blink/renderer/bindings/modules/v8/string_or_string_sequence_or_constrain_dom_string_parameters.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraint_set.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/modules/mediastream/media_track_constraint_set.h" #include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/mediastream/identifiability_metrics.h b/third_party/blink/renderer/modules/mediastream/identifiability_metrics.h index a718c58..e2ce423 100644 --- a/third_party/blink/renderer/modules/mediastream/identifiability_metrics.h +++ b/third_party/blink/renderer/modules/mediastream/identifiability_metrics.h
@@ -7,10 +7,12 @@ #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" #include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h" -#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints.h" namespace blink { +class ExecutionContext; +class MediaStreamConstraints; + IdentifiableToken TokenFromConstraints( const MediaStreamConstraints* constraints);
diff --git a/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h b/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h index 8104f2b..0cb1832 100644 --- a/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h +++ b/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h
@@ -36,6 +36,7 @@ namespace blink { class ExceptionState; +class LocalFrame; class NavigatorContentUtilsClient; // Verify custom handler schemes for errors as described in
diff --git a/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc b/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc index 1959cff..6204aa1 100644 --- a/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc +++ b/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h" +#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_can_make_payment_response.h"
diff --git a/third_party/blink/renderer/modules/payments/payment_request_test.cc b/third_party/blink/renderer/modules/payments/payment_request_test.cc index 740369c..84873d73 100644 --- a/third_party/blink/renderer/modules/payments/payment_request_test.cc +++ b/third_party/blink/renderer/modules/payments/payment_request_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/payments/payment_request.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/event_type_names.h"
diff --git a/third_party/blink/renderer/modules/payments/secure_payment_confirmation_helper.cc b/third_party/blink/renderer/modules/payments/secure_payment_confirmation_helper.cc index 6d6e0de..1ed7cf0b 100644 --- a/third_party/blink/renderer/modules/payments/secure_payment_confirmation_helper.cc +++ b/third_party/blink/renderer/modules/payments/secure_payment_confirmation_helper.cc
@@ -8,6 +8,7 @@ #include "base/logging.h" #include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_secure_payment_confirmation_request.h" #include "third_party/blink/renderer/modules/payments/secure_payment_confirmation_type_converter.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.cc b/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.cc index 4a3403c..b06cc77 100644 --- a/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.cc +++ b/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.cc
@@ -3,8 +3,11 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_capability.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.h" + +#include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_capabilities.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_codec_capability.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_header_extension_capability.h" #include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h b/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h index 04a63aa..07376ae 100644 --- a/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h +++ b/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h
@@ -5,11 +5,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_IDENTIFIABILITY_METRICS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_IDENTIFIABILITY_METRICS_H_ -#include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.h" - namespace blink { +class RTCRtpCapabilities; +class IdentifiableTokenBuilder; + void IdentifiabilityAddRTCRtpCapabilitiesToBuilder( IdentifiableTokenBuilder& builder, const RTCRtpCapabilities& capabilities);
diff --git a/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc b/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc index 67aa88f2..7780d3da 100644 --- a/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc +++ b/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc
@@ -4,6 +4,10 @@ #include "third_party/blink/renderer/modules/service_worker/extendable_message_event.h" +#include "third_party/blink/renderer/core/messaging/message_port.h" +#include "third_party/blink/renderer/modules/service_worker/service_worker.h" +#include "third_party/blink/renderer/modules/service_worker/service_worker_client.h" + namespace blink { ExtendableMessageEvent* ExtendableMessageEvent::Create(
diff --git a/third_party/blink/renderer/modules/service_worker/extendable_message_event.h b/third_party/blink/renderer/modules/service_worker/extendable_message_event.h index 8709481d..8526303 100644 --- a/third_party/blink/renderer/modules/service_worker/extendable_message_event.h +++ b/third_party/blink/renderer/modules/service_worker/extendable_message_event.h
@@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_EXTENDABLE_MESSAGE_EVENT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_EXTENDABLE_MESSAGE_EVENT_H_ +#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" +#include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h" #include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_extendable_message_event_init.h" #include "third_party/blink/renderer/modules/event_modules.h" @@ -13,6 +15,10 @@ namespace blink { +class MessagePort; +class ServiceWorkerClient; +class ServiceWorker; + class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent { DEFINE_WRAPPERTYPEINFO();
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index ca15ecb..92eef09 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -74,6 +74,7 @@ #include "third_party/blink/renderer/core/loader/threadable_loader.h" #include "third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h" #include "third_party/blink/renderer/core/messaging/blink_transferable_message.h" +#include "third_party/blink/renderer/core/messaging/message_port.h" #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc index 3e7676e..ee9d081 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc +++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
@@ -17,6 +17,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_config.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_init.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_frame_output_callback.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.h"
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc index 2d38ace..a919dfc 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc
@@ -8,6 +8,7 @@ #include "media/media_buildflags.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_image_decoder_init.h"
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc index aa42413c..71d7e58 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -458,8 +458,7 @@ return ScriptPromise(); Request* request = MakeGarbageCollected<Request>(); - request->resolver = - MakeGarbageCollected<ScriptPromiseResolver>(script_state_); + request->resolver = MakePromise(); request->reset_count = reset_count_; request->type = Request::Type::kFlush; EnqueueRequest(request); @@ -471,9 +470,8 @@ if (ThrowIfCodecStateClosed(state_, "reset", exception_state)) return; - ResetInternal(); - state_ = V8CodecState(V8CodecState::Enum::kUnconfigured); + ResetInternal(); } void VideoEncoder::ResetInternal() { @@ -482,15 +480,36 @@ while (!requests_.empty()) { Request* pending_req = requests_.TakeFirst(); DCHECK(pending_req); - if (pending_req->resolver) { - auto* ex = MakeGarbageCollected<DOMException>( - DOMExceptionCode::kOperationError, "reset() was called."); - pending_req->resolver.Release()->Reject(ex); - } + RejectPromise(pending_req); } stall_request_processing_ = false; } +ScriptPromiseResolver* VideoEncoder::MakePromise() { + outstanding_promises_++; + return MakeGarbageCollected<ScriptPromiseResolver>(script_state_); +} + +void VideoEncoder::ResolvePromise(Request* req) { + if (!req || !req->resolver) + return; + req->resolver.Release()->Resolve(); + DCHECK_GT(outstanding_promises_, 0u); + outstanding_promises_--; +} + +void VideoEncoder::RejectPromise(Request* req, DOMException* ex) { + if (!req || !req->resolver) + return; + auto* resolver = req->resolver.Release(); + if (ex) + resolver->Reject(ex); + else + resolver->Reject(); + DCHECK_GT(outstanding_promises_, 0u); + outstanding_promises_--; +} + void VideoEncoder::HandleError(DOMException* ex) { // Save a temp before we clear the callback. V8WebCodecsErrorCallback* error_callback = error_callback_.Get(); @@ -636,18 +655,22 @@ auto done_callback = [](VideoEncoder* self, Request* req, media::Status status) { - if (!self || self->reset_count_ != req->reset_count) + if (!self) return; - DCHECK(req->resolver); DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_); + if (self->reset_count_ != req->reset_count) { + self->RejectPromise(req); + return; + } + DCHECK(req->resolver); if (status.is_ok()) { - req->resolver.Release()->Resolve(); + self->ResolvePromise(req); } else { std::string error_msg = "Flushing error."; self->HandleError(error_msg, status); auto* ex = MakeGarbageCollected<DOMException>( DOMExceptionCode::kOperationError, error_msg.c_str()); - req->resolver.Release()->Reject(ex); + self->RejectPromise(req, ex); } self->stall_request_processing_ = false; self->ProcessRequests(); @@ -698,6 +721,10 @@ parent_media_log_ = nullptr; } +bool VideoEncoder::HasPendingActivity() const { + return outstanding_promises_ > 0; +} + void VideoEncoder::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(output_callback_);
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.h b/third_party/blink/renderer/modules/webcodecs/video_encoder.h index 083e170..92e573d 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.h +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.h
@@ -13,6 +13,7 @@ #include "media/base/video_codecs.h" #include "media/base/video_color_space.h" #include "media/base/video_encoder.h" +#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_codec_state.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_output_callback.h" @@ -38,6 +39,7 @@ class MODULES_EXPORT VideoEncoder final : public ScriptWrappable, + public ActiveScriptWrappable<VideoEncoder>, public ExecutionContextLifecycleObserver { DEFINE_WRAPPERTYPEINFO(); @@ -68,6 +70,9 @@ // ExecutionContextLifecycleObserver override. void ContextDestroyed() override; + // ScriptWrappable override. + bool HasPendingActivity() const override; + // GarbageCollected override. void Trace(Visitor*) const override; @@ -119,6 +124,9 @@ void UpdateEncoderLog(std::string encoder_name, bool is_hw_accelerated); void ResetInternal(); + ScriptPromiseResolver* MakePromise(); + void ResolvePromise(Request* req); + void RejectPromise(Request* req, DOMException* ex = nullptr); std::unique_ptr<ParsedConfig> ParseConfig(const VideoEncoderConfig*, ExceptionState&); @@ -151,6 +159,9 @@ // an operation and its callback. uint32_t reset_count_ = 0; + // Number of not resolved/rejected promises created by this VideoEncoder. + uint32_t outstanding_promises_ = 0; + // Some kConfigure and kFlush requests can't be executed in parallel with // kEncode. This flag stops processing of new requests in the requests_ queue // till the current requests is finished.
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.idl b/third_party/blink/renderer/modules/webcodecs/video_encoder.idl index 9c77233..6efa78c8 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.idl +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.idl
@@ -6,7 +6,8 @@ [ Exposed=Window, - RuntimeEnabled=WebCodecs + RuntimeEnabled=WebCodecs, + ActiveScriptWrappable ] interface VideoEncoder { [CallWith=ScriptState, RaisesException, MeasureAs=WebCodecsVideoEncoder] constructor(VideoEncoderInit init);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc index a19e407..9b3b2b9 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -21,6 +21,7 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h" #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.h" #include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h" #include "third_party/blink/renderer/modules/webgpu/gpu_query_set.h" #include "third_party/blink/renderer/modules/webgpu/gpu_queue.h" @@ -30,6 +31,7 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h" #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" #include "third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_validation_error.h" #include "third_party/blink/renderer/platform/heap/heap.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webid/web_id.cc b/third_party/blink/renderer/modules/webid/web_id.cc index f69efd7..2bf48e2 100644 --- a/third_party/blink/renderer/modules/webid/web_id.cc +++ b/third_party/blink/renderer/modules/webid/web_id.cc
@@ -7,8 +7,8 @@ #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_web_id_request_options.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/modules/webid/web_id_request_options.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/bindings/script_state.h"
diff --git a/third_party/blink/renderer/modules/xr/xr_light_probe.cc b/third_party/blink/renderer/modules/xr/xr_light_probe.cc index ecdb5a7..e23dad67 100644 --- a/third_party/blink/renderer/modules/xr/xr_light_probe.cc +++ b/third_party/blink/renderer/modules/xr/xr_light_probe.cc
@@ -5,12 +5,12 @@ #include "third_party/blink/renderer/modules/xr/xr_light_probe.h" #include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_light_probe_init.h" #include "third_party/blink/renderer/core/geometry/dom_point_read_only.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/xr/xr_cube_map.h" #include "third_party/blink/renderer/modules/xr/xr_light_estimate.h" -#include "third_party/blink/renderer/modules/xr/xr_light_probe_init.h" #include "third_party/blink/renderer/modules/xr/xr_object_space.h" #include "third_party/blink/renderer/modules/xr/xr_session.h"
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index e6c691c..8f2d1c3 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -1260,10 +1260,11 @@ if (light_probe_init->reflectionFormat() != "srgba8" && light_probe_init->reflectionFormat() != "rgba16f") { - exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, - "Reflection format \"" + - light_probe_init->reflectionFormat() + - "\" not supported."); + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Reflection format \"" + + IDLEnumAsString(light_probe_init->reflectionFormat()) + + "\" not supported."); return ScriptPromise(); }
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_allocator.h b/third_party/blink/renderer/platform/heap/impl/heap_allocator.h index 8fc46cb..a9b3bae 100644 --- a/third_party/blink/renderer/platform/heap/impl/heap_allocator.h +++ b/third_party/blink/renderer/platform/heap/impl/heap_allocator.h
@@ -114,18 +114,6 @@ MarkAsConstructed(ThreadHeap::Allocate<Metadata>(size))); } - // Compilers sometimes eagerly instantiates the unused 'operator delete', so - // we provide a version that asserts and fails at run-time if used. - static void Free(void*) { NOTREACHED(); } - - template <typename T> - static void* NewArray(size_t bytes) { - NOTREACHED(); - return nullptr; - } - - static void DeleteArray(void* ptr) { NOTREACHED(); } - static bool IsAllocationAllowed() { return ThreadState::Current()->IsAllocationAllowed(); }
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index b34ab11..43a5455 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -663,6 +663,7 @@ crbug.com/613753 external/wpt/css/css-tables/border-spacing-included-in-sizes-001.html [ Failure ] crbug.com/353580 external/wpt/css/css-tables/height-distribution/percentage-sizing-of-table-cell-children-005.html [ Failure ] crbug.com/1108224 external/wpt/css/css-tables/min-max-size-table-content-box.html [ Failure ] +crbug.com/958381 external/wpt/css/css-tables/tentative/position-sticky-container.html [ Failure ] # [css-contain] @@ -5990,6 +5991,10 @@ # Sheriff 2020-11-12 crbug.com/1148259 [ Mac ] external/wpt/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html [ Failure ] +# Sheriff 2020-11-19 +crbug.com/1150700 [ Win ] virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/registration-updateviacache.https.html [ Pass Timeout ] +crbug.com/1150700 [ Win ] virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/update-bytecheck-cors-import.https.html [ Pass Timeout ] + # Disable flaky tests when scroll unification is enabled crbug.com/1130020 virtual/scroll-unification/fast/scrolling/scrollbars/scrollbar-mousedown-move-mouseup.html [ Pass Failure Timeout ] crbug.com/1130020 virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-mousedown-move-mouseup.html [ Pass Failure Timeout ] @@ -6003,4 +6008,4 @@ crbug.com/1149987 external/wpt/websockets/Create-blocked-port.any.html [ Pass Timeout ] crbug.com/1149987 external/wpt/websockets/Create-blocked-port.any.worker.html [ Pass Timeout ] crbug.com/1150518 [ Win ] virtual/gpu/fast/canvas/canvas-composite-shadow.html [ Pass Timeout ] -crbug.com/1150475 fast/dom/open-and-close-by-DOM.html [ Pass Failure ] \ No newline at end of file +crbug.com/1150475 fast/dom/open-and-close-by-DOM.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations index b1d3437a..c1d6c9ff 100644 --- a/third_party/blink/web_tests/WebDriverExpectations +++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -78,6 +78,17 @@ crbug.com/1020018 [ Linux ] external/wpt/webdriver/tests/get_active_element/get.py>>test_sucess_input_non_interactable [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_window/switch.py>>test_element_not_found_after_tab_switch [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_click/click.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_top_browsing_context [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_top_browsing_context [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_touch_pointer_properties [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_pen_pointer_properties [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/release_actions/release.py>>test_no_browsing_context [ Failure ]
diff --git a/third_party/blink/web_tests/accessibility/aria-hidden.html b/third_party/blink/web_tests/accessibility/aria-hidden.html index 6cad1b2..30cb91f 100644 --- a/third_party/blink/web_tests/accessibility/aria-hidden.html +++ b/third_party/blink/web_tests/accessibility/aria-hidden.html
@@ -24,5 +24,18 @@ </script> +<div id="hidden-container" style="display: none"> + <h2 aria-hidden="false">h2</h2> +</div> + +<script> +test((t) => { + var hiddenContainer = accessibilityController.accessibleElementById("hidden-container"); + assert_true(hiddenContainer.isIgnored); + assert_equals(hiddenContainer.childrenCount, 1); + var ariaVisibleH2 = hiddenContainer.childAtIndex(0); + assert_false(ariaVisibleH2.isIgnored); +}, "Elements with aria-hidden=false inside a non-rendered element should be exposed in the accessibility tree, and not ignored"); + </script> </body> </html>
diff --git a/third_party/blink/web_tests/accessibility/aria-setsize-posinset.html b/third_party/blink/web_tests/accessibility/aria-setsize-posinset.html index 60e964b..5af9f4ee 100644 --- a/third_party/blink/web_tests/accessibility/aria-setsize-posinset.html +++ b/third_party/blink/web_tests/accessibility/aria-setsize-posinset.html
@@ -22,25 +22,6 @@ }, "Tests that aria-posinset and aria-setSize for a simple list are exposed to accessibility correctly"); </script> -<form id ="form"> - <input type="radio" name="meals" value="breakfast"> - <input type="radio" name="meals" value="lunch"> - <input type="radio" name="meals" value="dinner"> -</form> - -<script> - test(function(t){ - var form = accessibilityController.accessibleElementById("form"); - // aria-posinset and aria-setSize can be implicitly caluclated for input type of radio. - assert_equals(form.childAtIndex(0).posInSet,1); - assert_equals(form.childAtIndex(1).posInSet,2); - assert_equals(form.childAtIndex(2).posInSet,3); - assert_equals(form.childAtIndex(0).setSize,3); - assert_equals(form.childAtIndex(1).setSize,3); - assert_equals(form.childAtIndex(2).setSize,3); - }, "Tests that aria-posinset and aria-setSize for native radio inputs are exposed to accessibility correctly"); -</script> - <div id="radiogroup" role="radiogroup"> <hr> <div id="radio1" role="radio" aria-setSize="3" aria-posinset="2">Radio 1</div>
diff --git a/third_party/blink/web_tests/accessibility/element-role-mapping-normal-expected.txt b/third_party/blink/web_tests/accessibility/element-role-mapping-normal-expected.txt index d04cfda..5d8dabc 100644 --- a/third_party/blink/web_tests/accessibility/element-role-mapping-normal-expected.txt +++ b/third_party/blink/web_tests/accessibility/element-role-mapping-normal-expected.txt
@@ -182,13 +182,14 @@ AXRole: AXCaption AXRole: AXStaticText "Caption" AXRole: AXInlineTextBox "Caption" - AXRole: AXRow - AXRole: AXCell "Cell1" - AXRole: AXStaticText "Cell1" - AXRole: AXInlineTextBox "Cell1" - AXRole: AXCell "Cell2" - AXRole: AXStaticText "Cell2" - AXRole: AXInlineTextBox "Cell2" + AXRole: AXRowGroup + AXRole: AXRow + AXRole: AXCell "Cell1" + AXRole: AXStaticText "Cell1" + AXRole: AXInlineTextBox "Cell1" + AXRole: AXCell "Cell2" + AXRole: AXStaticText "Cell2" + AXRole: AXInlineTextBox "Cell2" AXRole: AXFigure "Fig1. - Blue Box" AXRole: AXImage "blue" AXRole: AXFigcaption
diff --git a/third_party/blink/web_tests/accessibility/presentation-owned-elements-expected.txt b/third_party/blink/web_tests/accessibility/presentation-owned-elements-expected.txt index 54f91511..fc0550c 100644 --- a/third_party/blink/web_tests/accessibility/presentation-owned-elements-expected.txt +++ b/third_party/blink/web_tests/accessibility/presentation-owned-elements-expected.txt
@@ -55,37 +55,42 @@ AXRole: AXInlineTextBox "These two tables have static text roles because they have presentation roles." AXRole: AXPresentational AXRole: AXGenericContainer - AXRole: AXStaticText "Presentation th" - AXRole: AXInlineTextBox "Presentation th" + AXRole: AXGenericContainer + AXRole: AXStaticText "Presentation th" + AXRole: AXInlineTextBox "Presentation th" AXRole: AXGenericContainer - AXRole: AXStaticText "Presentation th" - AXRole: AXInlineTextBox "Presentation th" + AXRole: AXGenericContainer + AXRole: AXStaticText "Presentation th" + AXRole: AXInlineTextBox "Presentation th" AXRole: AXPresentational AXRole: AXGenericContainer - AXRole: AXStaticText "Presentation th" - AXRole: AXInlineTextBox "Presentation th" + AXRole: AXGenericContainer + AXRole: AXStaticText "Presentation th" + AXRole: AXInlineTextBox "Presentation th" AXRole: AXGenericContainer AXRole: AXStaticText "The "Presentation th" has a static text role because it has a presentation role." AXRole: AXInlineTextBox "The "Presentation th" has a static text role because it has a presentation role." AXRole: AXTable - AXRole: AXGenericContainer - AXRole: AXStaticText "Presentation th" - AXRole: AXInlineTextBox "Presentation th" - AXRole: AXRow - AXRole: AXCell "Normal td" - AXRole: AXStaticText "Normal td" - AXRole: AXInlineTextBox "Normal td" + AXRole: AXRowGroup + AXRole: AXGenericContainer + AXRole: AXStaticText "Presentation th" + AXRole: AXInlineTextBox "Presentation th" + AXRole: AXRow + AXRole: AXCell "Normal td" + AXRole: AXStaticText "Normal td" + AXRole: AXInlineTextBox "Normal td" AXRole: AXGenericContainer AXRole: AXStaticText "The row for "Explicit th" has a row role even if table has a presentation role because it has an explicit role." AXRole: AXInlineTextBox "The row for "Explicit th" has a row role even if table has a presentation role because it has an explicit role." AXRole: AXPresentational AXRole: AXGenericContainer AXRole: AXGenericContainer - AXRole: AXStaticText "Explicit th" - AXRole: AXInlineTextBox "Explicit th" - AXRole: AXGenericContainer - AXRole: AXStaticText "Implicit td" - AXRole: AXInlineTextBox "Implicit td" + AXRole: AXGenericContainer + AXRole: AXStaticText "Explicit th" + AXRole: AXInlineTextBox "Explicit th" + AXRole: AXGenericContainer + AXRole: AXStaticText "Implicit td" + AXRole: AXInlineTextBox "Implicit td" AXRole: AXGenericContainer AXRole: AXStaticText "The menu items except button have a static text role because it has a presentation role and is disabled." AXRole: AXInlineTextBox "The menu items except button have a static text role because it has a presentation role and is disabled."
diff --git a/third_party/blink/web_tests/accessibility/table-header-column-row-expected.txt b/third_party/blink/web_tests/accessibility/table-header-column-row-expected.txt index 6f9483a..df34d4c 100644 --- a/third_party/blink/web_tests/accessibility/table-header-column-row-expected.txt +++ b/third_party/blink/web_tests/accessibility/table-header-column-row-expected.txt
@@ -27,145 +27,150 @@ AXRole: AXCaption AXRole: AXStaticText "scope test" AXRole: AXInlineTextBox "scope test" - AXRole: AXRow - AXRole: AXColumnHeader "col head" - AXRole: AXStaticText "col head" - AXRole: AXInlineTextBox "col head" - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXColumnHeader "col head" - AXRole: AXStaticText "col head" - AXRole: AXInlineTextBox "col head" - AXRole: AXRow - AXRole: AXColumnHeader "col head" - AXRole: AXStaticText "col head" - AXRole: AXInlineTextBox "col head" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXRow - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXColumnHeader "col head" - AXRole: AXStaticText "col head" - AXRole: AXInlineTextBox "col head" + AXRole: AXRowGroup + AXRole: AXRow + AXRole: AXColumnHeader "col head" + AXRole: AXStaticText "col head" + AXRole: AXInlineTextBox "col head" + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXColumnHeader "col head" + AXRole: AXStaticText "col head" + AXRole: AXInlineTextBox "col head" + AXRole: AXRow + AXRole: AXColumnHeader "col head" + AXRole: AXStaticText "col head" + AXRole: AXInlineTextBox "col head" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXRow + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXColumnHeader "col head" + AXRole: AXStaticText "col head" + AXRole: AXInlineTextBox "col head" AXRole: AXTable "row header and column header (1)" AXRole: AXCaption AXRole: AXStaticText "row header and column header (1)" AXRole: AXInlineTextBox "row header and column header (1)" - AXRole: AXRow - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXRow - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXRow - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" + AXRole: AXRowGroup + AXRole: AXRow + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXRow + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXRow + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" AXRole: AXTable "row header and column header (2)" AXRole: AXCaption AXRole: AXStaticText "row header and column header (2)" AXRole: AXInlineTextBox "row header and column header (2)" - AXRole: AXRow - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXRow - AXRole: AXColumnHeader "column head" - AXRole: AXStaticText "column head" - AXRole: AXInlineTextBox "column head" - AXRole: AXColumnHeader "column head" - AXRole: AXStaticText "column head" - AXRole: AXInlineTextBox "column head" - AXRole: AXColumnHeader "column head" - AXRole: AXStaticText "column head" - AXRole: AXInlineTextBox "column head" - AXRole: AXRow - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" + AXRole: AXRowGroup + AXRole: AXRow + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXRow + AXRole: AXColumnHeader "column head" + AXRole: AXStaticText "column head" + AXRole: AXInlineTextBox "column head" + AXRole: AXColumnHeader "column head" + AXRole: AXStaticText "column head" + AXRole: AXInlineTextBox "column head" + AXRole: AXColumnHeader "column head" + AXRole: AXStaticText "column head" + AXRole: AXInlineTextBox "column head" + AXRole: AXRow + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" AXRole: AXTable "row header and column header (3)" AXRole: AXCaption AXRole: AXStaticText "row header and column header (3)" AXRole: AXInlineTextBox "row header and column header (3)" - AXRole: AXRow - AXRole: AXCell - AXRole: AXColumnHeader "col head" - AXRole: AXStaticText "col head" - AXRole: AXInlineTextBox "col head" - AXRole: AXRow - AXRole: AXColumnHeader "col head" - AXRole: AXStaticText "col head" - AXRole: AXInlineTextBox "col head" - AXRole: AXColumnHeader "col head" - AXRole: AXStaticText "col head" - AXRole: AXInlineTextBox "col head" - AXRole: AXRow - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" - AXRole: AXCell "data" - AXRole: AXStaticText "data" - AXRole: AXInlineTextBox "data" + AXRole: AXRowGroup + AXRole: AXRow + AXRole: AXCell + AXRole: AXColumnHeader "col head" + AXRole: AXStaticText "col head" + AXRole: AXInlineTextBox "col head" + AXRole: AXRow + AXRole: AXColumnHeader "col head" + AXRole: AXStaticText "col head" + AXRole: AXInlineTextBox "col head" + AXRole: AXColumnHeader "col head" + AXRole: AXStaticText "col head" + AXRole: AXInlineTextBox "col head" + AXRole: AXRow + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" + AXRole: AXCell "data" + AXRole: AXStaticText "data" + AXRole: AXInlineTextBox "data" AXRole: AXTable "row header and column header (4)" AXRole: AXCaption AXRole: AXStaticText "row header and column header (4)" AXRole: AXInlineTextBox "row header and column header (4)" - AXRole: AXRow - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" - AXRole: AXColumnHeader "col head" - AXRole: AXStaticText "col head" - AXRole: AXInlineTextBox "col head" - AXRole: AXRow - AXRole: AXRowHeader "row head" - AXRole: AXStaticText "row head" - AXRole: AXInlineTextBox "row head" + AXRole: AXRowGroup + AXRole: AXRow + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" + AXRole: AXColumnHeader "col head" + AXRole: AXStaticText "col head" + AXRole: AXInlineTextBox "col head" + AXRole: AXRow + AXRole: AXRowHeader "row head" + AXRole: AXStaticText "row head" + AXRole: AXInlineTextBox "row head" PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/accessibility/table-with-empty-thead-causes-crash-expected.txt b/third_party/blink/web_tests/accessibility/table-with-empty-thead-causes-crash-expected.txt index 736b124..19ba326 100644 --- a/third_party/blink/web_tests/accessibility/table-with-empty-thead-causes-crash-expected.txt +++ b/third_party/blink/web_tests/accessibility/table-with-empty-thead-causes-crash-expected.txt
@@ -8,13 +8,15 @@ AXRole: AXGenericContainer AXRole: AXTable "table" - AXRole: AXRow - AXRole: AXCell "1" - AXRole: AXStaticText "1" - AXRole: AXInlineTextBox "1" - AXRole: AXCell "2" - AXRole: AXStaticText "2" - AXRole: AXInlineTextBox "2" + AXRole: AXRowGroup + AXRole: AXRowGroup + AXRole: AXRow + AXRole: AXCell "1" + AXRole: AXStaticText "1" + AXRole: AXInlineTextBox "1" + AXRole: AXCell "2" + AXRole: AXStaticText "2" + AXRole: AXInlineTextBox "2" PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/accessibility/table-with-presentation-role.html b/third_party/blink/web_tests/accessibility/table-with-presentation-role.html index 39a147fc..56a018d 100644 --- a/third_party/blink/web_tests/accessibility/table-with-presentation-role.html +++ b/third_party/blink/web_tests/accessibility/table-with-presentation-role.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> +<!-- <script src="../resources/accessibility-helper.js"></script> --> <div id="container"> <table role="presentation"> @@ -13,16 +14,20 @@ </table> </div> +<pre id="console"></pre> <script> + // buildAccessibilityTree(accessibilityController.accessibleElementById('container'), 0, 1, []); test(() => { var axTableContainer = accessibilityController.accessibleElementById('container').childAtIndex(0); - assert_equals(axTableContainer.childrenCount, 4); - var axTextContainer1 = axTableContainer.childAtIndex(0); + assert_equals(axTableContainer.childrenCount, 1); + var axSectionContainer = axTableContainer.childAtIndex(0); + assert_equals(axSectionContainer.role, "AXRole: AXGenericContainer"); + var axTextContainer1 = axSectionContainer.childAtIndex(0); assert_equals(axTextContainer1.role, "AXRole: AXGenericContainer"); var axText1 = axTextContainer1.childAtIndex(0); assert_equals(axText1.role, "AXRole: AXStaticText"); assert_equals(axText1.name, "A"); - var axTextContainer2 = axTableContainer.childAtIndex(1); + var axTextContainer2 = axSectionContainer.childAtIndex(1); assert_equals(axTextContainer2.role, "AXRole: AXGenericContainer"); var axText2 = axTextContainer2.childAtIndex(0); assert_equals(axText2.role, "AXRole: AXStaticText");
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index c0742649..7b0c9ff 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -51482,6 +51482,21 @@ {} ] ], + "hidpi": { + "simple-bg-color.html": [ + "07bea44d21964b832cd9e4b4f32098ec41a2c206", + [ + null, + [ + [ + "/css/css-backgrounds/hidpi/simple-bg-color-ref.html", + "==" + ] + ], + {} + ] + ] + }, "inline-background-rtl-001.html": [ "a7149e2f3c83acf175b5de4f8bcbf63a2c20d4f1", [ @@ -58273,6 +58288,19 @@ ], {} ] + ], + "content-visibility-078.html": [ + "51382bccf04456ae4adea00cc08daceaf9e952f6", + [ + null, + [ + [ + "/css/css-contain/content-visibility/content-visibility-078-ref.html", + "==" + ] + ], + {} + ] ] }, "counter-scoping-001.html": [ @@ -180617,6 +180645,12 @@ "10324966edb042c1c7298ce22dad76766c2a777b", [] ], + "hidpi": { + "simple-bg-color-ref.html": [ + "d768c02b25a82e45cd8cb9e7120d2655d55f33d5", + [] + ] + }, "inset-box-shadow-scroll-ref.html": [ "55be941bfc35e8d064e811335242fd06dc28da67", [] @@ -182082,6 +182116,10 @@ "4b37070bd7e03bfcef0baaf9440d978859d1e780", [] ], + "content-visibility-078-ref.html": [ + "64629ca11977c77e4b1420881c5bc59a50816323", + [] + ], "inline-container-with-child-ref.html": [ "af51cbd5db8f3eff56411345860548e95fe4d354", [] @@ -239630,6 +239668,10 @@ "944de61c71561d9a96825b9a344bc642a48f262a", [] ], + "__init__.py": [ + "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + [] + ], "no-entries-for-cross-origin-css-fetched.sub-expected.txt": [ "a256bb2dc766a40f21115049572246bf003499ba", [] @@ -251591,7 +251633,7 @@ [] ], "manifestupdate.py": [ - "129457b3fd1270dc66029d3ea873d353714aa607", + "c74632b0486ceb891b855c1573e090459d718a6a", [] ], "metadata.py": [ @@ -254367,7 +254409,7 @@ [] ], "fixtures.py": [ - "957c4d05868b9cb3ba440727de79d3c4b120c5a3", + "3eb5ffd26fa5f8e1f909b98214024dffefc704fe", [] ], "helpers.py": [ @@ -278607,10 +278649,12 @@ ] ], "frame-ancestors-nested-cross-in-same-star-allow.html": [ - "c523b9ef10a7832cc21dbe90902dec16431c0651", + "3658fb65023b0a70a763b1e4e34c39c6d503eb7d", [ null, - {} + { + "timeout": "long" + } ] ], "frame-ancestors-nested-cross-in-same-url-allow.html": [ @@ -282665,10 +282709,12 @@ ] ], "match.html": [ - "14921d1d62c0d80349cf1149e55e3af0b51f77d5", + "e42ee24f3d0af258ac35534301c1626331ec55ed", [ null, - {} + { + "timeout": "long" + } ] ] }, @@ -298776,6 +298822,13 @@ null, {} ] + ], + "position-sticky-container.html": [ + "604b536df17c13467083fb7626001bf3552b71ca", + [ + null, + {} + ] ] }, "visibility-collapse-col-001.html": [ @@ -314270,10 +314323,12 @@ ] ], "xml_xpath_runner.html": [ - "42404562a3c95b3004c7b0b7402ea366faeb4d83", + "03edf50515c231a9f9fbf0a0587261627b949e19", [ null, - {} + { + "timeout": "long" + } ] ] }, @@ -314352,10 +314407,12 @@ ] ], "white-spaces-after-execCommand-delete.tentative.html": [ - "6aafdddcef01b9fb77a3bfd7f9343170a653913b", + "1490bf06f55a6c2b1e10afc044b19b108e5dd482", [ null, - {} + { + "timeout": "long" + } ] ], "white-spaces-after-execCommand-forwarddelete.tentative.html": [ @@ -359371,17 +359428,21 @@ ] ], "popup-coop-by-sw-from-coop.https.html": [ - "fc38ea1c66b3ec5ccd8f517a2e76a0c203846c8e", + "0b7d6d91001d406b575ce4185f2ae68ef2a909e2", [ null, - {} + { + "timeout": "long" + } ] ], "popup-coop-by-sw.https.html": [ - "13d9e79ca77c65e9dbd719e4601f6a8af476ae7f", + "830318c208f3ad52585882bd265500f51a4ea95d", [ null, - {} + { + "timeout": "long" + } ] ], "popup-meta-http-equiv.https.html": [ @@ -362421,10 +362482,12 @@ }, "rendering": { "dimension-attributes.html": [ - "2c544aac31ead3b04ca8d3fc8cb490c51a74e8bb", + "00a5ff9a9673f1bc5bea22807e2e90a41c3348af", [ null, - {} + { + "timeout": "long" + } ] ], "non-replaced-elements": { @@ -365017,10 +365080,12 @@ ] ], "track-mode.html": [ - "2474a11fb1adb0ccd2a4f7a5b82098fa7ea04e57", + "206ac9968f8e4b47b6defa09f669aeaf57fb5593", [ null, - {} + { + "timeout": "long" + } ] ], "track-node-add-remove.html": [ @@ -374943,11 +375008,12 @@ ] ], "consumption-crossorigin.sub.tentative.html": [ - "cc21418e47dbe074b121430f2463aaca76347187", + "ebeeb935c062979bd9758bc4cc66d2ed516976ec", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -375005,11 +375071,12 @@ ] ], "propagation-crossorigin.sub.tentative.html": [ - "c29c9d8440d0ff25fe3ef88ae9b8b3382dfb4bcf", + "467dfb81b75c3ace7f2186856f7404995ee7f24c", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -378098,11 +378165,12 @@ ] ], "pause.html": [ - "72f34c1bde8cf54814cdf91b3fdeeaff90dd07e3", + "ec33c5110292c420009b0ce46461754390975f76", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -391287,11 +391355,12 @@ ] ], "pointerevent_touch-action-inherit_child-auto-child-none_touch.html": [ - "257043f2249c63b5ac6e3245d17acb80caa83732", + "53eafbb2f2ae2854ffe54c49b66f760b0bc94e10", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -391305,11 +391374,12 @@ ] ], "pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch.html": [ - "c2f4bd35aebbb67194f4cc17d3d52709d63f732a", + "a820b4f3cf4ca29a6b37286e084a18102cc054af", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -391332,11 +391402,12 @@ ] ], "pointerevent_touch-action-inherit_parent-none_touch.html": [ - "04db243676fd2f454421d10b6a7e6a1cef4e3e04", + "e8c205a042f283296c39d0d249739a2b0d23afe0", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -391387,11 +391458,12 @@ ] ], "pointerevent_touch-action-pan-right-css_touch.html": [ - "c211e17b17c8fd5d817dc31de060d26a550d1a74", + "99882a079c91c23212c7689d5141fb863815a0b0", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -392090,10 +392162,12 @@ ] ], "preload-with-type.html": [ - "eb5675f993b1e98014fd38d8674858f7c66ed7e6", + "7f92606cb7954cab45f28495499fbd84c3446459", [ null, - {} + { + "timeout": "long" + } ] ], "preload-xhr.html": [ @@ -402802,10 +402876,12 @@ ] ], "callback-idle-periods.html": [ - "c066c6055d86f7814dfed52674da1103bbcb4ffb", + "3c2de61bfeadd452ea1a80d30c42a799704ab1b3", [ null, - {} + { + "timeout": "long" + } ] ], "callback-iframe.html": [ @@ -402818,10 +402894,12 @@ ] ], "callback-invoked.html": [ - "5e799cf39f985a9bb66b418771ca0fa57ee85ad8", + "dc52f1422b08f3e07521fa09995d6da4ce68452b", [ null, - {} + { + "timeout": "long" + } ] ], "callback-multiple-calls.html": [ @@ -404545,10 +404623,12 @@ }, "secure-payment-confirmation": { "secure-payment-confirmation.tenative.https.html": [ - "1cc12d49eba1369d57512a52de30eab4fa477da2", + "1eabdd41145b3edae1a5b68c0219fd5e178f7a71", [ null, - {} + { + "timeout": "long" + } ] ] }, @@ -437325,10 +437405,12 @@ ] ], "Worker_terminate_event_queue.htm": [ - "5d9472a1c46f460e0606e99e3302b3039cd390c9", + "e4f106ad3a86b07efb3e4f449c0de904e667f30e", [ null, - {} + { + "timeout": "long" + } ] ], "abrupt-completion.html": [ @@ -454008,7 +454090,7 @@ }, "close_window": { "close.py": [ - "53af5730f83fbd158e8540ac680c44896f5323ba", + "2d665d5a8836df3f5bca6928d6fb6fe58d9b87db", [ null, {} @@ -454105,7 +454187,7 @@ ] ], "click.py": [ - "3a5d737216d95de1110f48cc004438b0913d1ca0", + "50982fe4bdd8add9e1f10a9df60e1104238c71c9", [ null, {} @@ -454207,7 +454289,7 @@ ] ], "send_keys.py": [ - "edf91e776148562721f89d8f7aef8e8eefbde78a", + "acdc1164a406ee6364492c6d12bd70f4fa025db5", [ null, {} @@ -454458,7 +454540,7 @@ }, "get_element_attribute": { "get.py": [ - "b18d9ca8b22a8a576dac66863408337992151a27", + "f67a6c3d7c0ac63b8eac1cf800e6ca855a526366", [ null, {} @@ -454476,7 +454558,7 @@ }, "get_element_css_value": { "get.py": [ - "4e8704d50af93cfe94d496302a2d33807a7a3a5a", + "25fae26a69c549173f8504ffdc340c6a9f100280", [ null, {} @@ -454494,7 +454576,7 @@ }, "get_element_property": { "get.py": [ - "5c0247edb7020599306dada98c8e7d35b31b7751", + "27b4bea5f173d83f4ef3517acc650ede136cf281", [ null, {} @@ -454512,7 +454594,7 @@ }, "get_element_rect": { "get.py": [ - "494c45f8e45b847909d3d602186423bfd9d2e7ad", + "d461c01c3120dc5aa95bb893b1f84544a9429bce", [ null, {} @@ -454530,7 +454612,7 @@ }, "get_element_tag_name": { "get.py": [ - "ffe6dd641e82a3982da89f11f773d019858450ef", + "4ca818f76a5704b5875be5e22206840c3a248d4d", [ null, {} @@ -454548,7 +454630,7 @@ }, "get_element_text": { "get.py": [ - "5f169a3a233b50de73de31f241a3bff4d749d6c2", + "642bc1d2c62298a6dc9e9f4d38b2a63345027c6d", [ null, {} @@ -454699,7 +454781,7 @@ }, "is_element_enabled": { "enabled.py": [ - "88b1534ded1ae5d7a34a83cd8f763d115b6312a5", + "64058ebd577e23c55a81a745fa63a9228f98d28c", [ null, {} @@ -454717,7 +454799,7 @@ }, "is_element_selected": { "selected.py": [ - "79a1615dd9fdfcc7f3fd07f971f0bbec84247bca", + "b09927c7a12e0c7cbc235a204bec990f8530ebff", [ null, {} @@ -455187,7 +455269,7 @@ ] ], "switch.py": [ - "9e5315588e3bbea859a10d2c367d41354c3240ea", + "88a1a244b2d27bcf60f1be55752b3633863b4ad6", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/position-sticky-container.html b/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/position-sticky-container.html new file mode 100644 index 0000000..604b536 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/position-sticky-container.html
@@ -0,0 +1,170 @@ +<!doctype html> +<title>Table parts sticky containers</title> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<link rel="author" title="Aleks Totic" href="mailto:atotic@chromium.org" /> +<link rel="help" href="https://www.w3.org/TR/css-tables-3/" /> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5020"/> +<style> + body { + margin: 0; + } + main * { + box-sizing: border-box; + } + + main .scroller { + width: 350px; + height: 302px; + overflow-y: scroll; + outline-offset: -1px; + outline: gray solid 1px; + } + main .padblock { + width: 300px; + height: 400px; + outline-offset: -2px; + outline: black dotted 2px; + } + main table { + border-spacing: 0; + } + + main td { + width: 100px; + height: 25px; + } + .sticky { + position:sticky; + top: 0; + background: rgba(0,255,0, 0.3); + } + +</style> +<main> + <div class="scroller"> + <div class="padblock">top</div> + <table> + <thead> + <tr> + <td>h:0,0</td> + <td>h:0,1</td> + <td>h:0,2</td> + </tr> + <tr > + <td>h:1,0</td> + <td >h:1,1</td> + <td>h:1,2</td> + </tr> + <tr> + <td>h:2,0</td> + <td>h:2,1</td> + <td>h:2,2</td> + </tr> + </thead> + <tbody> + <tr> + <td>b:0,0</td> + <td>b:0,1</td> + <td>b:0,2</td> + </tr> + <tr> + <td>b:1,0</td> + <td>b:1,1</td> + <td>b:1,2</td> + </tr> + <tr> + <td>b:2,0</td> + <td>b:2,1</td> + <td>b:2,2</td> + </tr> + </tbody> + <tfoot> + <tr> + <td>f:0,0</td> + <td>f:0,1</td> + <td>f:0,2</td> + </tr> + <tr> + <td>f:1,0</td> + <td>f:1,1</td> + <td>f:1,2</td> + </tr> + <tr> + <td>f:2,0</td> + <td>f:2,1</td> + <td>f:2,2</td> + </tr> + </tfoot> + </table> + <div class="padblock">bottom</div> + </div> +</main> +<script> + + function scrollTo(y) { + let scroller = document.querySelector("main .scroller"); + scroller.scrollTop = y; + } + + test( () => { + // Setup + let target = document.querySelector("main tbody tr:nth-child(2) td:nth-child(2)"); + let scroller = document.querySelector("main .scroller"); + target.classList.toggle("sticky"); + + // Tests + scrollTo(0); + assert_equals(target.getBoundingClientRect().top, 500, "intrinsic position"); + + scrollTo(600); + assert_equals(target.getBoundingClientRect().top, 0, "sticking to the table"); + + scrollTo(640); + assert_equals(target.getBoundingClientRect().top, -40, "sticking to the table bottom"); + + // Teardown + target.classList.toggle("sticky"); + }, "TD sticky container is table"); + + test( () => { + // Setup + let target = document.querySelector("main tbody tr:nth-child(2)"); + let scroller = document.querySelector("main .scroller"); + target.classList.toggle("sticky"); + + // Tests + scrollTo(0); + assert_equals(target.getBoundingClientRect().top, 500, "intrinsic position"); + + scrollTo(600); + assert_equals(target.getBoundingClientRect().top, 0, "sticking to the table"); + + scrollTo(640); + assert_equals(target.getBoundingClientRect().top, -40, "sticking to the table bottom"); + // Teardown + target.classList.toggle("sticky"); + }, "TR sticky container is table"); + + + test( () => { + // Setup + let target = document.querySelector("main tbody"); + let scroller = document.querySelector("main .scroller"); + target.classList.toggle("sticky"); + + // Tests + scrollTo(0); + assert_equals(target.getBoundingClientRect().top, 475, "intrinsic position"); + + scrollTo(550); + assert_equals(target.getBoundingClientRect().top, 0, "sticking to the table"); + + scrollTo(600); + assert_equals(target.getBoundingClientRect().top, -50, "sticking to the table bottom"); + + // Teardown + target.classList.toggle("sticky"); + }, "TBODY sticky container is table"); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/widgets/appearance/default-styles-expected.txt b/third_party/blink/web_tests/external/wpt/html/rendering/widgets/appearance/default-styles-expected.txt index f2b7d40..b03e6bf 100644 --- a/third_party/blink/web_tests/external/wpt/html/rendering/widgets/appearance/default-styles-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/rendering/widgets/appearance/default-styles-expected.txt
@@ -1,31 +1,31 @@ This is a testharness.js-based test. -FAIL <input> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="text"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="TEXT"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="search"> assert_equals: -webkit-appearance expected "auto" but got "searchfield" -FAIL <input type="tel"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="url"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="email"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="password"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="date"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="month"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="week"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="time"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="datetime-local"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="number"> assert_equals: -webkit-appearance expected "auto" but got "textfield" -FAIL <input type="range"> assert_equals: -webkit-appearance expected "auto" but got "slider-horizontal" +PASS <input> +PASS <input type="text"> +PASS <input type="TEXT"> +PASS <input type="search"> +PASS <input type="tel"> +PASS <input type="url"> +PASS <input type="email"> +PASS <input type="password"> +PASS <input type="date"> +PASS <input type="month"> +PASS <input type="week"> +PASS <input type="time"> +PASS <input type="datetime-local"> +PASS <input type="number"> +PASS <input type="range"> PASS <input type="color"> PASS <input type="checkbox"> PASS <input type="radio"> PASS <input type="submit"> PASS <input type="reset"> PASS <input type="button"> -FAIL <input type="unknowntype"> assert_equals: -webkit-appearance expected "auto" but got "textfield" +PASS <input type="unknowntype"> FAIL <select> assert_equals: -webkit-appearance expected "auto" but got "menulist" FAIL <select multiple=""> assert_equals: -webkit-appearance expected "auto" but got "listbox" FAIL <select size="2"> assert_equals: -webkit-appearance expected "auto" but got "listbox" PASS <button> -FAIL <textarea> assert_equals: -webkit-appearance expected "auto" but got "textarea" +PASS <textarea> PASS <meter> PASS <progress> PASS <input type="hidden">
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/manifestupdate.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/manifestupdate.py index 129457b3..c74632b0 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/manifestupdate.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/manifestupdate.py
@@ -718,15 +718,18 @@ # add them in to expected. if count > 0 or not self.remove_intermittent: expected.append(status) + + # If the new intermittent is a subset of the existing one, just use the existing one + # This prevents frequent flip-flopping of results between e.g. [OK, TIMEOUT] and + # [TIMEOUT, OK] + if current and set(expected).issubset(set(current)): + return current + if self.update_intermittent: if len(expected) == 1: return expected[0] return expected - # If nothing has changed and not self.update_intermittent, preserve existing - # intermittent. - if set(expected).issubset(set(current)): - return current # If we are not updating intermittents, return the status with the highest occurence. return expected[0]
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/close.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/close.py index 53af573..2d665d5a8 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/close.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/close_window/close.py
@@ -81,3 +81,23 @@ # With no more open top-level browsing contexts, the session is closed. session.session_id = None + + +def test_element_usage_after_closing_browsing_context(session): + session.url = inline("<p id='a'>foo") + a = session.find.css("p", all=False) + first = session.window_handle + + second = session.new_window(type_hint="tab") + session.window_handle = second + + session.url = inline("<p id='b'>other") + b = session.find.css("p", all=False) + + session.window_handle = first + response = close(session) + assert_success(response) + assert len(session.handles) == 1 + + session.window_handle = second + assert b.attribute("id") == "b"
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/click.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/click.py index 3a5d7372..50982fe 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/click.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/element_click/click.py
@@ -22,10 +22,17 @@ def test_no_top_browsing_context(session, closed_window): element = Element("foo", session) - response = element_click(session, element) assert_error(response, "no such window") + original_handle, element = closed_window + response = element_click(session, element) + assert_error(response, "no such window") + + session.window_handle = original_handle + response = element_click(session, element) + assert_error(response, "no such element") + def test_no_browsing_context(session, closed_frame): element = Element("foo", session)
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/send_keys.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/send_keys.py index edf91e77..acdc116 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/send_keys.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/element_send_keys/send_keys.py
@@ -36,10 +36,17 @@ def test_no_top_browsing_context(session, closed_window): element = Element("foo", session) - response = element_send_keys(session, element, "foo") assert_error(response, "no such window") + original_handle, element = closed_window + response = element_send_keys(session, element, "foo") + assert_error(response, "no such window") + + session.window_handle = original_handle + response = element_send_keys(session, element, "foo") + assert_error(response, "no such element") + def test_no_browsing_context(session, closed_frame): element = Element("foo", session)
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/get.py index b18d9ca8..f67a6c3 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/get.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_attribute/get.py
@@ -13,8 +13,14 @@ def test_no_top_browsing_context(session, closed_window): + original_handle, element = closed_window + response = get_element_attribute(session, element.id, "id") + assert_error(response, "no such window") response = get_element_attribute(session, "foo", "id") assert_error(response, "no such window") + session.window_handle = original_handle + response = get_element_attribute(session, element.id, "id") + assert_error(response, "no such element") def test_no_browsing_context(session, closed_frame):
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/get.py index 4e8704d..25fae26 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/get.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_css_value/get.py
@@ -14,9 +14,15 @@ def test_no_top_browsing_context(session, closed_window): + original_handle, element = closed_window + response = get_element_css_value(session, element.id, "display") + assert_error(response, "no such window") response = get_element_css_value(session, "foo", "bar") assert_error(response, "no such window") + session.window_handle = original_handle + response = get_element_css_value(session, element.id, "display") + assert_error(response, "no such element") def test_no_browsing_context(session, closed_frame): response = get_element_css_value(session, "foo", "bar")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/get.py index 5c0247e..27b4bea 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/get.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_property/get.py
@@ -13,9 +13,16 @@ def test_no_top_browsing_context(session, closed_window): + original_handle, element = closed_window + response = get_element_property(session, element.id, "value") + assert_error(response, "no such window") response = get_element_property(session, "foo", "id") assert_error(response, "no such window") + session.window_handle = original_handle + response = get_element_property(session, element.id, "value") + assert_error(response, "no such element") + def test_no_browsing_context(session, closed_frame): response = get_element_property(session, "foo", "id")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/get.py index 494c45f8..d461c01 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/get.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_rect/get.py
@@ -14,9 +14,16 @@ def test_no_top_browsing_context(session, closed_window): + original_handle, element = closed_window + response = get_element_rect(session, element.id) + assert_error(response, "no such window") response = get_element_rect(session, "foo") assert_error(response, "no such window") + session.window_handle = original_handle + response = get_element_rect(session, element.id) + assert_error(response, "no such element") + def test_no_browsing_context(session, closed_frame): response = get_element_rect(session, "foo")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/get.py index ffe6dd64..4ca818f 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/get.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_tag_name/get.py
@@ -10,9 +10,16 @@ def test_no_top_browsing_context(session, closed_window): + original_handle, element = closed_window + response = get_element_tag_name(session, element.id) + assert_error(response, "no such window") response = get_element_tag_name(session, "foo") assert_error(response, "no such window") + session.window_handle = original_handle + response = get_element_tag_name(session, element.id) + assert_error(response, "no such element") + def test_no_browsing_context(session, closed_frame): response = get_element_tag_name(session, "foo")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/get.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/get.py index 5f169a3..642bc1d 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/get.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/get_element_text/get.py
@@ -10,9 +10,16 @@ def test_no_top_browsing_context(session, closed_window): + original_handle, element = closed_window + response = get_element_text(session, element.id) + assert_error(response, "no such window") response = get_element_text(session, "foo") assert_error(response, "no such window") + session.window_handle = original_handle + response = get_element_text(session, element.id) + assert_error(response, "no such element") + def test_no_browsing_context(session, closed_frame): response = get_element_text(session, "foo") @@ -27,12 +34,8 @@ def test_read_element_text(session): - session.url = inline(""" - <body> - Noise before <span id='id'>This has an ID</span>. Noise after - </body>""") - + session.url = inline("Before f<span id='id'>oo</span> after") element = session.find.css("#id", all=False) result = get_element_text(session, element.id) - assert_success(result, "This has an ID") + assert_success(result, "oo")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/enabled.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/enabled.py index 88b1534d..64058eb 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/enabled.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_enabled/enabled.py
@@ -15,9 +15,16 @@ def test_no_top_browsing_context(session, closed_window): + original_handle, element = closed_window + response = is_element_enabled(session, element.id) + assert_error(response, "no such window") response = is_element_enabled(session, "foo") assert_error(response, "no such window") + session.window_handle = original_handle + response = is_element_enabled(session, element.id) + assert_error(response, "no such element") + def test_no_browsing_context(session, closed_frame): response = is_element_enabled(session, "foo")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/selected.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/selected.py index 79a1615d..b09927c 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/selected.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/is_element_selected/selected.py
@@ -22,9 +22,17 @@ def test_no_top_browsing_context(session, closed_window): + original_handle, element = closed_window + + response = is_element_selected(session, element.id) + assert_error(response, "no such window") response = is_element_selected(session, "foo") assert_error(response, "no such window") + session.window_handle = original_handle + response = is_element_selected(session, element.id) + assert_error(response, "no such element") + def test_no_browsing_context(session, closed_frame): response = is_element_selected(session, "foo")
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py index 957c4d0..3eb5ffd 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures.py
@@ -11,6 +11,7 @@ from tests.support import defaults from tests.support.helpers import cleanup_session +from tests.support.inline import inline from tests.support.http_request import HTTPRequest from tests.support.sync import Poll @@ -243,10 +244,12 @@ new_handle = session.new_window() session.window_handle = new_handle + session.url = inline("<input id='a' value='b'>") + element = session.find.css("input", all=False) session.window.close() assert new_handle not in session.handles, "Unable to close window {}".format(new_handle) - yield new_handle + yield (original_handle, element) session.window_handle = original_handle
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/switch.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/switch.py index 9e531558..88a1a244 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/switch.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/switch_to_window/switch.py
@@ -1,3 +1,6 @@ +import pytest + +from webdriver.error import NoSuchElementException from webdriver.transport import Response from tests.support.asserts import assert_error, assert_success @@ -65,3 +68,12 @@ assert_success(response) session.find.css("iframe", all=False) + +def test_element_not_found_after_tab_switch(session): + session.url = inline("<p id='a'>foo") + paragraph = session.find.css("p", all=False) + + session.window_handle = session.new_window(type_hint="tab") + + with pytest.raises(NoSuchElementException): + paragraph.attribute("id")
diff --git a/third_party/eigen3/BUILD.gn b/third_party/eigen3/BUILD.gn new file mode 100644 index 0000000..2b9ffae6 --- /dev/null +++ b/third_party/eigen3/BUILD.gn
@@ -0,0 +1,19 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("eigen_includes") { + include_dirs = [ "src" ] + + cflags = [ + "-Wno-unused-result", + "-Wno-extra-semi", + "-Wno-unused-function", + ] + + defines = [ + "EIGEN_MPL2_ONLY", + "EIGEN_MAX_ALIGN_BYTES=64", + "EIGEN_HAS_TYPE_TRAITS=0", + ] +}
diff --git a/third_party/eigen3/LICENSE b/third_party/eigen3/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/third_party/eigen3/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/third_party/eigen3/OWNERS b/third_party/eigen3/OWNERS new file mode 100644 index 0000000..f14a8b97 --- /dev/null +++ b/third_party/eigen3/OWNERS
@@ -0,0 +1,4 @@ +mcrouse@chromium.org +sophiechang@chromium.org +tbansal@chromium.org +# COMPONENT: Internals>OptimizationGuide
diff --git a/third_party/eigen3/README.chromium b/third_party/eigen3/README.chromium new file mode 100644 index 0000000..699b8be --- /dev/null +++ b/third_party/eigen3/README.chromium
@@ -0,0 +1,11 @@ +Name: Eigen +Short Name: eigen3 +URL: http://eigen.tuxfamily.org/ +Version: 2ce2f5198929caab4b41a6ad1b9c93f67d8b9a69 +License: MPL 2 +License File: LICENSE +Security Critical: Yes + +Description: +Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms. +
diff --git a/third_party/farmhash/BUILD.gn b/third_party/farmhash/BUILD.gn new file mode 100644 index 0000000..3af22438 --- /dev/null +++ b/third_party/farmhash/BUILD.gn
@@ -0,0 +1,18 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("farmhash_include") { + include_dirs = [ "src/src" ] +} + +source_set("farmhash") { + public = [ "src/src/farmhash.h" ] + + sources = [ "src/src/farmhash.cc" ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + + public_configs = [ ":farmhash_include" ] +}
diff --git a/third_party/farmhash/LICENSE b/third_party/farmhash/LICENSE new file mode 100644 index 0000000..8176e66 --- /dev/null +++ b/third_party/farmhash/LICENSE
@@ -0,0 +1,19 @@ +// Copyright (c) 2014 Google, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE.
diff --git a/third_party/farmhash/OWNERS b/third_party/farmhash/OWNERS new file mode 100644 index 0000000..f14a8b97 --- /dev/null +++ b/third_party/farmhash/OWNERS
@@ -0,0 +1,4 @@ +mcrouse@chromium.org +sophiechang@chromium.org +tbansal@chromium.org +# COMPONENT: Internals>OptimizationGuide
diff --git a/third_party/farmhash/README.chromium b/third_party/farmhash/README.chromium new file mode 100644 index 0000000..5790a26 --- /dev/null +++ b/third_party/farmhash/README.chromium
@@ -0,0 +1,19 @@ +Name: FarmHash +Short Name: farmhash +URL: https://github.com/google/farmhash +Version: 1.1 +Date: 2017/09/13 +Revision: 816a4ae622e964763ca0862d9dbd19324a1eaf45 +License: Custom +License File: LICENSE +Security Critical: Yes +License Android Compatible: Yes + +Description: +FarmHash, a family of hash functions. + +Local Modifications: +- Included only the source files in `src/`: + - farmhash.h + - farmhash.cc +- Extracted LICENSE file separately.
diff --git a/third_party/fft2d/BUILD.gn b/third_party/fft2d/BUILD.gn new file mode 100644 index 0000000..9db18a3e --- /dev/null +++ b/third_party/fft2d/BUILD.gn
@@ -0,0 +1,12 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("fft2d") { + sources = [ + "src/fftsg.c", + "src/fftsg2d.c", + ] + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] +}
diff --git a/third_party/fft2d/LICENSE b/third_party/fft2d/LICENSE new file mode 100644 index 0000000..2bd8550 --- /dev/null +++ b/third_party/fft2d/LICENSE
@@ -0,0 +1,3 @@ +Copyright(C) 1997,2001 Takuya OOURA (email: ooura@kurims.kyoto-u.ac.jp). +You may use, copy, modify this code for any purpose and +without fee. You may distribute this ORIGINAL package.
diff --git a/third_party/fft2d/OWNERS b/third_party/fft2d/OWNERS new file mode 100644 index 0000000..f14a8b97 --- /dev/null +++ b/third_party/fft2d/OWNERS
@@ -0,0 +1,4 @@ +mcrouse@chromium.org +sophiechang@chromium.org +tbansal@chromium.org +# COMPONENT: Internals>OptimizationGuide
diff --git a/third_party/fft2d/README.chromium b/third_party/fft2d/README.chromium new file mode 100644 index 0000000..6e1a48da --- /dev/null +++ b/third_party/fft2d/README.chromium
@@ -0,0 +1,22 @@ +Name: 2-dim General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package +Short Name: fft2d +URL: http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html +Version: 0 +Date: 2006/12/28 +License: Custom +License File: LICENSE +Security Critical: yes +License Android Compatible: yes + +Description: +This directory contains the third-party one- and two-dimensional +fast Fourier transform and related sinusoidal transform code written +by Takuya Ooura. + +Local Modifications: +- Included only the C source files required by //third_party/tflite + +Version: +-------- + "fft2d.tgz (53KB) updated: 2006/12/28" + SHA512(fft2d.tgz)= af993f68e8e1eb3cb927a51e86da8f74cfafc912a7cd055515e50fe543dd19ab5a6f7b1c2be4a55d6f4a0e5d766ead34c3be4c5705be6353f78cb2a55bd5cf16
diff --git a/third_party/fft2d/src/fftsg.c b/third_party/fft2d/src/fftsg.c new file mode 100644 index 0000000..43d75344 --- /dev/null +++ b/third_party/fft2d/src/fftsg.c
@@ -0,0 +1,3314 @@ +/* +Fast Fourier/Cosine/Sine Transform + dimension :one + data length :power of 2 + decimation :frequency + radix :split-radix + data :inplace + table :use +functions + cdft: Complex Discrete Fourier Transform + rdft: Real Discrete Fourier Transform + ddct: Discrete Cosine Transform + ddst: Discrete Sine Transform + dfct: Cosine Transform of RDFT (Real Symmetric DFT) + dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) +function prototypes + void cdft(int, int, double *, int *, double *); + void rdft(int, int, double *, int *, double *); + void ddct(int, int, double *, int *, double *); + void ddst(int, int, double *, int *, double *); + void dfct(int, double *, double *, int *, double *); + void dfst(int, double *, double *, int *, double *); +macro definitions + USE_CDFT_PTHREADS : default=not defined + CDFT_THREADS_BEGIN_N : must be >= 512, default=8192 + CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536 + USE_CDFT_WINTHREADS : default=not defined + CDFT_THREADS_BEGIN_N : must be >= 512, default=32768 + CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288 + + +-------- Complex DFT (Discrete Fourier Transform) -------- + [definition] + <case1> + X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n + <case2> + X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n + (notes: sum_j=0^n-1 is a summation from j=0 to n-1) + [usage] + <case1> + ip[0] = 0; // first time only + cdft(2*n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + cdft(2*n, -1, a, ip, w); + [parameters] + 2*n :data length (int) + n >= 1, n = power of 2 + a[0...2*n-1] :input/output data (double *) + input data + a[2*j] = Re(x[j]), + a[2*j+1] = Im(x[j]), 0<=j<n + output data + a[2*k] = Re(X[k]), + a[2*k+1] = Im(X[k]), 0<=k<n + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n) + strictly, + length of ip >= + 2+(1<<(int)(log(n+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + cdft(2*n, -1, a, ip, w); + is + cdft(2*n, 1, a, ip, w); + for (j = 0; j <= 2 * n - 1; j++) { + a[j] *= 1.0 / n; + } + . + + +-------- Real DFT / Inverse of Real DFT -------- + [definition] + <case1> RDFT + R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 + I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2 + <case2> IRDFT (excluding scale) + a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n + [usage] + <case1> + ip[0] = 0; // first time only + rdft(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + rdft(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + <case1> + output data + a[2*k] = R[k], 0<=k<n/2 + a[2*k+1] = I[k], 0<k<n/2 + a[1] = R[n/2] + <case2> + input data + a[2*j] = R[j], 0<=j<n/2 + a[2*j+1] = I[j], 0<j<n/2 + a[1] = R[n/2] + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + rdft(n, 1, a, ip, w); + is + rdft(n, -1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- DCT (Discrete Cosine Transform) / Inverse of DCT -------- + [definition] + <case1> IDCT (excluding scale) + C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n + <case2> DCT + C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n + [usage] + <case1> + ip[0] = 0; // first time only + ddct(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + ddct(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + output data + a[k] = C[k], 0<=k<n + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/4-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddct(n, -1, a, ip, w); + is + a[0] *= 0.5; + ddct(n, 1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- DST (Discrete Sine Transform) / Inverse of DST -------- + [definition] + <case1> IDST (excluding scale) + S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n + <case2> DST + S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n + [usage] + <case1> + ip[0] = 0; // first time only + ddst(n, 1, a, ip, w); + <case2> + ip[0] = 0; // first time only + ddst(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + <case1> + input data + a[j] = A[j], 0<j<n + a[0] = A[n] + output data + a[k] = S[k], 0<=k<n + <case2> + output data + a[k] = S[k], 0<k<n + a[0] = S[n] + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/4-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddst(n, -1, a, ip, w); + is + a[0] *= 0.5; + ddst(n, 1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- Cosine Transform of RDFT (Real Symmetric DFT) -------- + [definition] + C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n + [usage] + ip[0] = 0; // first time only + dfct(n, a, t, ip, w); + [parameters] + n :data length - 1 (int) + n >= 2, n = power of 2 + a[0...n] :input/output data (double *) + output data + a[k] = C[k], 0<=k<=n + t[0...n/2] :work area (double *) + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/4) + strictly, + length of ip >= + 2+(1<<(int)(log(n/4+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/8-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + a[0] *= 0.5; + a[n] *= 0.5; + dfct(n, a, t, ip, w); + is + a[0] *= 0.5; + a[n] *= 0.5; + dfct(n, a, t, ip, w); + for (j = 0; j <= n; j++) { + a[j] *= 2.0 / n; + } + . + + +-------- Sine Transform of RDFT (Real Anti-symmetric DFT) -------- + [definition] + S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n + [usage] + ip[0] = 0; // first time only + dfst(n, a, t, ip, w); + [parameters] + n :data length + 1 (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + output data + a[k] = S[k], 0<k<n + (a[0] is used for work area) + t[0...n/2-1] :work area (double *) + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/4) + strictly, + length of ip >= + 2+(1<<(int)(log(n/4+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/8-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + dfst(n, a, t, ip, w); + is + dfst(n, a, t, ip, w); + for (j = 1; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + +Appendix : + The cos/sin table is recalculated when the larger table required. + w[] and ip[] are compatible with all routines. +*/ + + +void cdft(int n, int isgn, double *a, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void cftbsub(int n, double *a, int *ip, int nw, double *w); + int nw; + + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + if (isgn >= 0) { + cftfsub(n, a, ip, nw, w); + } else { + cftbsub(n, a, ip, nw, w); + } +} + + +void rdft(int n, int isgn, double *a, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void cftbsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void rftbsub(int n, double *a, int nc, double *c); + int nw, nc; + double xi; + + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 2)) { + nc = n >> 2; + makect(nc, ip, w + nw); + } + if (isgn >= 0) { + if (n > 4) { + cftfsub(n, a, ip, nw, w); + rftfsub(n, a, nc, w + nw); + } else if (n == 4) { + cftfsub(n, a, ip, nw, w); + } + xi = a[0] - a[1]; + a[0] += a[1]; + a[1] = xi; + } else { + a[1] = 0.5 * (a[0] - a[1]); + a[0] -= a[1]; + if (n > 4) { + rftbsub(n, a, nc, w + nw); + cftbsub(n, a, ip, nw, w); + } else if (n == 4) { + cftbsub(n, a, ip, nw, w); + } + } +} + + +void ddct(int n, int isgn, double *a, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void cftbsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void rftbsub(int n, double *a, int nc, double *c); + void dctsub(int n, double *a, int nc, double *c); + int j, nw, nc; + double xr; + + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > nc) { + nc = n; + makect(nc, ip, w + nw); + } + if (isgn < 0) { + xr = a[n - 1]; + for (j = n - 2; j >= 2; j -= 2) { + a[j + 1] = a[j] - a[j - 1]; + a[j] += a[j - 1]; + } + a[1] = a[0] - xr; + a[0] += xr; + if (n > 4) { + rftbsub(n, a, nc, w + nw); + cftbsub(n, a, ip, nw, w); + } else if (n == 4) { + cftbsub(n, a, ip, nw, w); + } + } + dctsub(n, a, nc, w + nw); + if (isgn >= 0) { + if (n > 4) { + cftfsub(n, a, ip, nw, w); + rftfsub(n, a, nc, w + nw); + } else if (n == 4) { + cftfsub(n, a, ip, nw, w); + } + xr = a[0] - a[1]; + a[0] += a[1]; + for (j = 2; j < n; j += 2) { + a[j - 1] = a[j] - a[j + 1]; + a[j] += a[j + 1]; + } + a[n - 1] = xr; + } +} + + +void ddst(int n, int isgn, double *a, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void cftbsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void rftbsub(int n, double *a, int nc, double *c); + void dstsub(int n, double *a, int nc, double *c); + int j, nw, nc; + double xr; + + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > nc) { + nc = n; + makect(nc, ip, w + nw); + } + if (isgn < 0) { + xr = a[n - 1]; + for (j = n - 2; j >= 2; j -= 2) { + a[j + 1] = -a[j] - a[j - 1]; + a[j] -= a[j - 1]; + } + a[1] = a[0] + xr; + a[0] -= xr; + if (n > 4) { + rftbsub(n, a, nc, w + nw); + cftbsub(n, a, ip, nw, w); + } else if (n == 4) { + cftbsub(n, a, ip, nw, w); + } + } + dstsub(n, a, nc, w + nw); + if (isgn >= 0) { + if (n > 4) { + cftfsub(n, a, ip, nw, w); + rftfsub(n, a, nc, w + nw); + } else if (n == 4) { + cftfsub(n, a, ip, nw, w); + } + xr = a[0] - a[1]; + a[0] += a[1]; + for (j = 2; j < n; j += 2) { + a[j - 1] = -a[j] - a[j + 1]; + a[j] -= a[j + 1]; + } + a[n - 1] = -xr; + } +} + + +void dfct(int n, double *a, double *t, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void dctsub(int n, double *a, int nc, double *c); + int j, k, l, m, mh, nw, nc; + double xr, xi, yr, yi; + + nw = ip[0]; + if (n > (nw << 3)) { + nw = n >> 3; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 1)) { + nc = n >> 1; + makect(nc, ip, w + nw); + } + m = n >> 1; + yi = a[m]; + xi = a[0] + a[n]; + a[0] -= a[n]; + t[0] = xi - yi; + t[m] = xi + yi; + if (n > 2) { + mh = m >> 1; + for (j = 1; j < mh; j++) { + k = m - j; + xr = a[j] - a[n - j]; + xi = a[j] + a[n - j]; + yr = a[k] - a[n - k]; + yi = a[k] + a[n - k]; + a[j] = xr; + a[k] = yr; + t[j] = xi - yi; + t[k] = xi + yi; + } + t[mh] = a[mh] + a[n - mh]; + a[mh] -= a[n - mh]; + dctsub(m, a, nc, w + nw); + if (m > 4) { + cftfsub(m, a, ip, nw, w); + rftfsub(m, a, nc, w + nw); + } else if (m == 4) { + cftfsub(m, a, ip, nw, w); + } + a[n - 1] = a[0] - a[1]; + a[1] = a[0] + a[1]; + for (j = m - 2; j >= 2; j -= 2) { + a[2 * j + 1] = a[j] + a[j + 1]; + a[2 * j - 1] = a[j] - a[j + 1]; + } + l = 2; + m = mh; + while (m >= 2) { + dctsub(m, t, nc, w + nw); + if (m > 4) { + cftfsub(m, t, ip, nw, w); + rftfsub(m, t, nc, w + nw); + } else if (m == 4) { + cftfsub(m, t, ip, nw, w); + } + a[n - l] = t[0] - t[1]; + a[l] = t[0] + t[1]; + k = 0; + for (j = 2; j < m; j += 2) { + k += l << 2; + a[k - l] = t[j] - t[j + 1]; + a[k + l] = t[j] + t[j + 1]; + } + l <<= 1; + mh = m >> 1; + for (j = 0; j < mh; j++) { + k = m - j; + t[j] = t[m + k] - t[m + j]; + t[k] = t[m + k] + t[m + j]; + } + t[mh] = t[m + mh]; + m = mh; + } + a[l] = t[0]; + a[n] = t[2] - t[1]; + a[0] = t[2] + t[1]; + } else { + a[1] = a[0]; + a[2] = t[0]; + a[0] = t[1]; + } +} + + +void dfst(int n, double *a, double *t, int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void cftfsub(int n, double *a, int *ip, int nw, double *w); + void rftfsub(int n, double *a, int nc, double *c); + void dstsub(int n, double *a, int nc, double *c); + int j, k, l, m, mh, nw, nc; + double xr, xi, yr, yi; + + nw = ip[0]; + if (n > (nw << 3)) { + nw = n >> 3; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > (nc << 1)) { + nc = n >> 1; + makect(nc, ip, w + nw); + } + if (n > 2) { + m = n >> 1; + mh = m >> 1; + for (j = 1; j < mh; j++) { + k = m - j; + xr = a[j] + a[n - j]; + xi = a[j] - a[n - j]; + yr = a[k] + a[n - k]; + yi = a[k] - a[n - k]; + a[j] = xr; + a[k] = yr; + t[j] = xi + yi; + t[k] = xi - yi; + } + t[0] = a[mh] - a[n - mh]; + a[mh] += a[n - mh]; + a[0] = a[m]; + dstsub(m, a, nc, w + nw); + if (m > 4) { + cftfsub(m, a, ip, nw, w); + rftfsub(m, a, nc, w + nw); + } else if (m == 4) { + cftfsub(m, a, ip, nw, w); + } + a[n - 1] = a[1] - a[0]; + a[1] = a[0] + a[1]; + for (j = m - 2; j >= 2; j -= 2) { + a[2 * j + 1] = a[j] - a[j + 1]; + a[2 * j - 1] = -a[j] - a[j + 1]; + } + l = 2; + m = mh; + while (m >= 2) { + dstsub(m, t, nc, w + nw); + if (m > 4) { + cftfsub(m, t, ip, nw, w); + rftfsub(m, t, nc, w + nw); + } else if (m == 4) { + cftfsub(m, t, ip, nw, w); + } + a[n - l] = t[1] - t[0]; + a[l] = t[0] + t[1]; + k = 0; + for (j = 2; j < m; j += 2) { + k += l << 2; + a[k - l] = -t[j] - t[j + 1]; + a[k + l] = t[j] - t[j + 1]; + } + l <<= 1; + mh = m >> 1; + for (j = 1; j < mh; j++) { + k = m - j; + t[j] = t[m + k] + t[m + j]; + t[k] = t[m + k] - t[m + j]; + } + t[0] = t[m + mh]; + m = mh; + } + a[l] = t[0]; + } + a[0] = 0; +} + + +/* -------- initializing routines -------- */ + + +#include <math.h> + +void makewt(int nw, int *ip, double *w) +{ + void makeipt(int nw, int *ip); + int j, nwh, nw0, nw1; + double delta, wn4r, wk1r, wk1i, wk3r, wk3i; + + ip[0] = nw; + ip[1] = 1; + if (nw > 2) { + nwh = nw >> 1; + delta = atan(1.0) / nwh; + wn4r = cos(delta * nwh); + w[0] = 1; + w[1] = wn4r; + if (nwh == 4) { + w[2] = cos(delta * 2); + w[3] = sin(delta * 2); + } else if (nwh > 4) { + makeipt(nw, ip); + w[2] = 0.5 / cos(delta * 2); + w[3] = 0.5 / cos(delta * 6); + for (j = 4; j < nwh; j += 4) { + w[j] = cos(delta * j); + w[j + 1] = sin(delta * j); + w[j + 2] = cos(3 * delta * j); + w[j + 3] = -sin(3 * delta * j); + } + } + nw0 = 0; + while (nwh > 2) { + nw1 = nw0 + nwh; + nwh >>= 1; + w[nw1] = 1; + w[nw1 + 1] = wn4r; + if (nwh == 4) { + wk1r = w[nw0 + 4]; + wk1i = w[nw0 + 5]; + w[nw1 + 2] = wk1r; + w[nw1 + 3] = wk1i; + } else if (nwh > 4) { + wk1r = w[nw0 + 4]; + wk3r = w[nw0 + 6]; + w[nw1 + 2] = 0.5 / wk1r; + w[nw1 + 3] = 0.5 / wk3r; + for (j = 4; j < nwh; j += 4) { + wk1r = w[nw0 + 2 * j]; + wk1i = w[nw0 + 2 * j + 1]; + wk3r = w[nw0 + 2 * j + 2]; + wk3i = w[nw0 + 2 * j + 3]; + w[nw1 + j] = wk1r; + w[nw1 + j + 1] = wk1i; + w[nw1 + j + 2] = wk3r; + w[nw1 + j + 3] = wk3i; + } + } + nw0 = nw1; + } + } +} + + +void makeipt(int nw, int *ip) +{ + int j, l, m, m2, p, q; + + ip[2] = 0; + ip[3] = 16; + m = 2; + for (l = nw; l > 32; l >>= 2) { + m2 = m << 1; + q = m2 << 3; + for (j = m; j < m2; j++) { + p = ip[j] << 2; + ip[m + j] = p; + ip[m2 + j] = p + q; + } + m = m2; + } +} + + +void makect(int nc, int *ip, double *c) +{ + int j, nch; + double delta; + + ip[1] = nc; + if (nc > 1) { + nch = nc >> 1; + delta = atan(1.0) / nch; + c[0] = cos(delta * nch); + c[nch] = 0.5 * c[0]; + for (j = 1; j < nch; j++) { + c[j] = 0.5 * cos(delta * j); + c[nc - j] = 0.5 * sin(delta * j); + } + } +} + + +/* -------- child routines -------- */ + + +#ifdef USE_CDFT_PTHREADS +#define USE_CDFT_THREADS +#ifndef CDFT_THREADS_BEGIN_N +#define CDFT_THREADS_BEGIN_N 8192 +#endif +#ifndef CDFT_4THREADS_BEGIN_N +#define CDFT_4THREADS_BEGIN_N 65536 +#endif +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#define cdft_thread_t pthread_t +#define cdft_thread_create(thp,func,argp) { \ + if (pthread_create(thp, NULL, func, (void *) argp) != 0) { \ + fprintf(stderr, "cdft thread error\n"); \ + exit(1); \ + } \ +} +#define cdft_thread_wait(th) { \ + if (pthread_join(th, NULL) != 0) { \ + fprintf(stderr, "cdft thread error\n"); \ + exit(1); \ + } \ +} +#endif /* USE_CDFT_PTHREADS */ + + +#ifdef USE_CDFT_WINTHREADS +#define USE_CDFT_THREADS +#ifndef CDFT_THREADS_BEGIN_N +#define CDFT_THREADS_BEGIN_N 32768 +#endif +#ifndef CDFT_4THREADS_BEGIN_N +#define CDFT_4THREADS_BEGIN_N 524288 +#endif +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#define cdft_thread_t HANDLE +#define cdft_thread_create(thp,func,argp) { \ + DWORD thid; \ + *(thp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, (LPVOID) argp, 0, &thid); \ + if (*(thp) == 0) { \ + fprintf(stderr, "cdft thread error\n"); \ + exit(1); \ + } \ +} +#define cdft_thread_wait(th) { \ + WaitForSingleObject(th, INFINITE); \ + CloseHandle(th); \ +} +#endif /* USE_CDFT_WINTHREADS */ + + +void cftfsub(int n, double *a, int *ip, int nw, double *w) +{ + void bitrv2(int n, int *ip, double *a); + void bitrv216(double *a); + void bitrv208(double *a); + void cftf1st(int n, double *a, double *w); + void cftrec4(int n, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftfx41(int n, double *a, int nw, double *w); + void cftf161(double *a, double *w); + void cftf081(double *a, double *w); + void cftf040(double *a); + void cftx020(double *a); +#ifdef USE_CDFT_THREADS + void cftrec4_th(int n, double *a, int nw, double *w); +#endif /* USE_CDFT_THREADS */ + + if (n > 8) { + if (n > 32) { + cftf1st(n, a, &w[nw - (n >> 2)]); +#ifdef USE_CDFT_THREADS + if (n > CDFT_THREADS_BEGIN_N) { + cftrec4_th(n, a, nw, w); + } else +#endif /* USE_CDFT_THREADS */ + if (n > 512) { + cftrec4(n, a, nw, w); + } else if (n > 128) { + cftleaf(n, 1, a, nw, w); + } else { + cftfx41(n, a, nw, w); + } + bitrv2(n, ip, a); + } else if (n == 32) { + cftf161(a, &w[nw - 8]); + bitrv216(a); + } else { + cftf081(a, w); + bitrv208(a); + } + } else if (n == 8) { + cftf040(a); + } else if (n == 4) { + cftx020(a); + } +} + + +void cftbsub(int n, double *a, int *ip, int nw, double *w) +{ + void bitrv2conj(int n, int *ip, double *a); + void bitrv216neg(double *a); + void bitrv208neg(double *a); + void cftb1st(int n, double *a, double *w); + void cftrec4(int n, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftfx41(int n, double *a, int nw, double *w); + void cftf161(double *a, double *w); + void cftf081(double *a, double *w); + void cftb040(double *a); + void cftx020(double *a); +#ifdef USE_CDFT_THREADS + void cftrec4_th(int n, double *a, int nw, double *w); +#endif /* USE_CDFT_THREADS */ + + if (n > 8) { + if (n > 32) { + cftb1st(n, a, &w[nw - (n >> 2)]); +#ifdef USE_CDFT_THREADS + if (n > CDFT_THREADS_BEGIN_N) { + cftrec4_th(n, a, nw, w); + } else +#endif /* USE_CDFT_THREADS */ + if (n > 512) { + cftrec4(n, a, nw, w); + } else if (n > 128) { + cftleaf(n, 1, a, nw, w); + } else { + cftfx41(n, a, nw, w); + } + bitrv2conj(n, ip, a); + } else if (n == 32) { + cftf161(a, &w[nw - 8]); + bitrv216neg(a); + } else { + cftf081(a, w); + bitrv208neg(a); + } + } else if (n == 8) { + cftb040(a); + } else if (n == 4) { + cftx020(a); + } +} + + +void bitrv2(int n, int *ip, double *a) +{ + int j, j1, k, k1, l, m, nh, nm; + double xr, xi, yr, yi; + + m = 1; + for (l = n >> 2; l > 8; l >>= 2) { + m <<= 1; + } + nh = n >> 1; + nm = 4 * m; + if (l == 8) { + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 4 * j + 2 * ip[m + k]; + k1 = 4 * k + 2 * ip[m + j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + 2 * ip[m + k]; + j1 = k1 + 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= 2; + k1 -= nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh + 2; + k1 += nh + 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh - nm; + k1 += 2 * nm - 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } else { + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 4 * j + ip[m + k]; + k1 = 4 * k + ip[m + j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + ip[m + k]; + j1 = k1 + 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } +} + + +void bitrv2conj(int n, int *ip, double *a) +{ + int j, j1, k, k1, l, m, nh, nm; + double xr, xi, yr, yi; + + m = 1; + for (l = n >> 2; l > 8; l >>= 2) { + m <<= 1; + } + nh = n >> 1; + nm = 4 * m; + if (l == 8) { + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 4 * j + 2 * ip[m + k]; + k1 = 4 * k + 2 * ip[m + j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + 2 * ip[m + k]; + j1 = k1 + 2; + k1 += nh; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= 2; + k1 -= nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh + 2; + k1 += nh + 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh - nm; + k1 += 2 * nm - 2; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + } + } else { + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 4 * j + ip[m + k]; + k1 = 4 * k + ip[m + j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + ip[m + k]; + j1 = k1 + 2; + k1 += nh; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + j1 += nm; + k1 += nm; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + } + } +} + + +void bitrv216(double *a) +{ + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, + x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x7r = a[14]; + x7i = a[15]; + x8r = a[16]; + x8i = a[17]; + x10r = a[20]; + x10i = a[21]; + x11r = a[22]; + x11i = a[23]; + x12r = a[24]; + x12i = a[25]; + x13r = a[26]; + x13i = a[27]; + x14r = a[28]; + x14i = a[29]; + a[2] = x8r; + a[3] = x8i; + a[4] = x4r; + a[5] = x4i; + a[6] = x12r; + a[7] = x12i; + a[8] = x2r; + a[9] = x2i; + a[10] = x10r; + a[11] = x10i; + a[14] = x14r; + a[15] = x14i; + a[16] = x1r; + a[17] = x1i; + a[20] = x5r; + a[21] = x5i; + a[22] = x13r; + a[23] = x13i; + a[24] = x3r; + a[25] = x3i; + a[26] = x11r; + a[27] = x11i; + a[28] = x7r; + a[29] = x7i; +} + + +void bitrv216neg(double *a) +{ + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, + x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, + x13r, x13i, x14r, x14i, x15r, x15i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x6r = a[12]; + x6i = a[13]; + x7r = a[14]; + x7i = a[15]; + x8r = a[16]; + x8i = a[17]; + x9r = a[18]; + x9i = a[19]; + x10r = a[20]; + x10i = a[21]; + x11r = a[22]; + x11i = a[23]; + x12r = a[24]; + x12i = a[25]; + x13r = a[26]; + x13i = a[27]; + x14r = a[28]; + x14i = a[29]; + x15r = a[30]; + x15i = a[31]; + a[2] = x15r; + a[3] = x15i; + a[4] = x7r; + a[5] = x7i; + a[6] = x11r; + a[7] = x11i; + a[8] = x3r; + a[9] = x3i; + a[10] = x13r; + a[11] = x13i; + a[12] = x5r; + a[13] = x5i; + a[14] = x9r; + a[15] = x9i; + a[16] = x1r; + a[17] = x1i; + a[18] = x14r; + a[19] = x14i; + a[20] = x6r; + a[21] = x6i; + a[22] = x10r; + a[23] = x10i; + a[24] = x2r; + a[25] = x2i; + a[26] = x12r; + a[27] = x12i; + a[28] = x4r; + a[29] = x4i; + a[30] = x8r; + a[31] = x8i; +} + + +void bitrv208(double *a) +{ + double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i; + + x1r = a[2]; + x1i = a[3]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x6r = a[12]; + x6i = a[13]; + a[2] = x4r; + a[3] = x4i; + a[6] = x6r; + a[7] = x6i; + a[8] = x1r; + a[9] = x1i; + a[12] = x3r; + a[13] = x3i; +} + + +void bitrv208neg(double *a) +{ + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x6r, x6i, x7r, x7i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x6r = a[12]; + x6i = a[13]; + x7r = a[14]; + x7i = a[15]; + a[2] = x7r; + a[3] = x7i; + a[4] = x3r; + a[5] = x3i; + a[6] = x5r; + a[7] = x5i; + a[8] = x1r; + a[9] = x1i; + a[10] = x6r; + a[11] = x6i; + a[12] = x2r; + a[13] = x2i; + a[14] = x4r; + a[15] = x4i; +} + + +void cftf1st(int n, double *a, double *w) +{ + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, + wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = a[1] + a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = a[1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j2] = x1r - x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + csc1 = w[2]; + csc3 = w[3]; + wd1r = 1; + wd1i = 0; + wd3r = 1; + wd3i = 0; + k = 0; + for (j = 2; j < mh - 2; j += 4) { + k += 4; + wk1r = csc1 * (wd1r + w[k]); + wk1i = csc1 * (wd1i + w[k + 1]); + wk3r = csc3 * (wd3r + w[k + 2]); + wk3i = csc3 * (wd3i + w[k + 3]); + wd1r = w[k]; + wd1i = w[k + 1]; + wd3r = w[k + 2]; + wd3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = a[j + 1] + a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = a[j + 1] - a[j2 + 1]; + y0r = a[j + 2] + a[j2 + 2]; + y0i = a[j + 3] + a[j2 + 3]; + y1r = a[j + 2] - a[j2 + 2]; + y1i = a[j + 3] - a[j2 + 3]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 + 2] + a[j3 + 2]; + y2i = a[j1 + 3] + a[j3 + 3]; + y3r = a[j1 + 2] - a[j3 + 2]; + y3i = a[j1 + 3] - a[j3 + 3]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j + 2] = y0r + y2r; + a[j + 3] = y0i + y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j1 + 2] = y0r - y2r; + a[j1 + 3] = y0i - y2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = y1r - y3i; + x0i = y1i + y3r; + a[j2 + 2] = wd1r * x0r - wd1i * x0i; + a[j2 + 3] = wd1r * x0i + wd1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + x0r = y1r + y3i; + x0i = y1i - y3r; + a[j3 + 2] = wd3r * x0r + wd3i * x0i; + a[j3 + 3] = wd3r * x0i - wd3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + y0r = a[j0 - 2] + a[j2 - 2]; + y0i = a[j0 - 1] + a[j2 - 1]; + y1r = a[j0 - 2] - a[j2 - 2]; + y1i = a[j0 - 1] - a[j2 - 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 - 2] + a[j3 - 2]; + y2i = a[j1 - 1] + a[j3 - 1]; + y3r = a[j1 - 2] - a[j3 - 2]; + y3i = a[j1 - 1] - a[j3 - 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j0 - 2] = y0r + y2r; + a[j0 - 1] = y0i + y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j1 - 2] = y0r - y2r; + a[j1 - 1] = y0i - y2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = y1r - y3i; + x0i = y1i + y3r; + a[j2 - 2] = wd1i * x0r - wd1r * x0i; + a[j2 - 1] = wd1i * x0i + wd1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + x0r = y1r + y3i; + x0i = y1i - y3r; + a[j3 - 2] = wd3i * x0r + wd3r * x0i; + a[j3 - 1] = wd3i * x0i - wd3r * x0r; + } + wk1r = csc1 * (wd1r + wn4r); + wk1i = csc1 * (wd1i + wn4r); + wk3r = csc3 * (wd3r - wn4r); + wk3i = csc3 * (wd3i - wn4r); + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0 - 2] + a[j2 - 2]; + x0i = a[j0 - 1] + a[j2 - 1]; + x1r = a[j0 - 2] - a[j2 - 2]; + x1i = a[j0 - 1] - a[j2 - 1]; + x2r = a[j1 - 2] + a[j3 - 2]; + x2i = a[j1 - 1] + a[j3 - 1]; + x3r = a[j1 - 2] - a[j3 - 2]; + x3i = a[j1 - 1] - a[j3 - 1]; + a[j0 - 2] = x0r + x2r; + a[j0 - 1] = x0i + x2i; + a[j1 - 2] = x0r - x2r; + a[j1 - 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2 - 2] = wk1r * x0r - wk1i * x0i; + a[j2 - 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3 - 2] = wk3r * x0r + wk3i * x0i; + a[j3 - 1] = wk3r * x0i - wk3i * x0r; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); + x0r = a[j0 + 2] + a[j2 + 2]; + x0i = a[j0 + 3] + a[j2 + 3]; + x1r = a[j0 + 2] - a[j2 + 2]; + x1i = a[j0 + 3] - a[j2 + 3]; + x2r = a[j1 + 2] + a[j3 + 2]; + x2i = a[j1 + 3] + a[j3 + 3]; + x3r = a[j1 + 2] - a[j3 + 2]; + x3i = a[j1 + 3] - a[j3 + 3]; + a[j0 + 2] = x0r + x2r; + a[j0 + 3] = x0i + x2i; + a[j1 + 2] = x0r - x2r; + a[j1 + 3] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2 + 2] = wk1i * x0r - wk1r * x0i; + a[j2 + 3] = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3 + 2] = wk3i * x0r + wk3r * x0i; + a[j3 + 3] = wk3i * x0i - wk3r * x0r; +} + + +void cftb1st(int n, double *a, double *w) +{ + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, + wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = -a[1] - a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = -a[1] + a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i - x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j2] = x1r + x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r - x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + csc1 = w[2]; + csc3 = w[3]; + wd1r = 1; + wd1i = 0; + wd3r = 1; + wd3i = 0; + k = 0; + for (j = 2; j < mh - 2; j += 4) { + k += 4; + wk1r = csc1 * (wd1r + w[k]); + wk1i = csc1 * (wd1i + w[k + 1]); + wk3r = csc3 * (wd3r + w[k + 2]); + wk3i = csc3 * (wd3i + w[k + 3]); + wd1r = w[k]; + wd1i = w[k + 1]; + wd3r = w[k + 2]; + wd3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = -a[j + 1] - a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = -a[j + 1] + a[j2 + 1]; + y0r = a[j + 2] + a[j2 + 2]; + y0i = -a[j + 3] - a[j2 + 3]; + y1r = a[j + 2] - a[j2 + 2]; + y1i = -a[j + 3] + a[j2 + 3]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 + 2] + a[j3 + 2]; + y2i = a[j1 + 3] + a[j3 + 3]; + y3r = a[j1 + 2] - a[j3 + 2]; + y3i = a[j1 + 3] - a[j3 + 3]; + a[j] = x0r + x2r; + a[j + 1] = x0i - x2i; + a[j + 2] = y0r + y2r; + a[j + 3] = y0i - y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j1 + 2] = y0r - y2r; + a[j1 + 3] = y0i + y2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = y1r + y3i; + x0i = y1i + y3r; + a[j2 + 2] = wd1r * x0r - wd1i * x0i; + a[j2 + 3] = wd1r * x0i + wd1i * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + x0r = y1r - y3i; + x0i = y1i - y3r; + a[j3 + 2] = wd3r * x0r + wd3i * x0i; + a[j3 + 3] = wd3r * x0i - wd3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = -a[j0 + 1] - a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = -a[j0 + 1] + a[j2 + 1]; + y0r = a[j0 - 2] + a[j2 - 2]; + y0i = -a[j0 - 1] - a[j2 - 1]; + y1r = a[j0 - 2] - a[j2 - 2]; + y1i = -a[j0 - 1] + a[j2 - 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 - 2] + a[j3 - 2]; + y2i = a[j1 - 1] + a[j3 - 1]; + y3r = a[j1 - 2] - a[j3 - 2]; + y3i = a[j1 - 1] - a[j3 - 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i - x2i; + a[j0 - 2] = y0r + y2r; + a[j0 - 1] = y0i - y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j1 - 2] = y0r - y2r; + a[j1 - 1] = y0i + y2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = y1r + y3i; + x0i = y1i + y3r; + a[j2 - 2] = wd1i * x0r - wd1r * x0i; + a[j2 - 1] = wd1i * x0i + wd1r * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + x0r = y1r - y3i; + x0i = y1i - y3r; + a[j3 - 2] = wd3i * x0r + wd3r * x0i; + a[j3 - 1] = wd3i * x0i - wd3r * x0r; + } + wk1r = csc1 * (wd1r + wn4r); + wk1i = csc1 * (wd1i + wn4r); + wk3r = csc3 * (wd3r - wn4r); + wk3i = csc3 * (wd3i - wn4r); + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0 - 2] + a[j2 - 2]; + x0i = -a[j0 - 1] - a[j2 - 1]; + x1r = a[j0 - 2] - a[j2 - 2]; + x1i = -a[j0 - 1] + a[j2 - 1]; + x2r = a[j1 - 2] + a[j3 - 2]; + x2i = a[j1 - 1] + a[j3 - 1]; + x3r = a[j1 - 2] - a[j3 - 2]; + x3i = a[j1 - 1] - a[j3 - 1]; + a[j0 - 2] = x0r + x2r; + a[j0 - 1] = x0i - x2i; + a[j1 - 2] = x0r - x2r; + a[j1 - 1] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2 - 2] = wk1r * x0r - wk1i * x0i; + a[j2 - 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3 - 2] = wk3r * x0r + wk3i * x0i; + a[j3 - 1] = wk3r * x0i - wk3i * x0r; + x0r = a[j0] + a[j2]; + x0i = -a[j0 + 1] - a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = -a[j0 + 1] + a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i - x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); + x0r = a[j0 + 2] + a[j2 + 2]; + x0i = -a[j0 + 3] - a[j2 + 3]; + x1r = a[j0 + 2] - a[j2 + 2]; + x1i = -a[j0 + 3] + a[j2 + 3]; + x2r = a[j1 + 2] + a[j3 + 2]; + x2i = a[j1 + 3] + a[j3 + 3]; + x3r = a[j1 + 2] - a[j3 + 2]; + x3i = a[j1 + 3] - a[j3 + 3]; + a[j0 + 2] = x0r + x2r; + a[j0 + 3] = x0i - x2i; + a[j1 + 2] = x0r - x2r; + a[j1 + 3] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2 + 2] = wk1i * x0r - wk1r * x0i; + a[j2 + 3] = wk1i * x0i + wk1r * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3 + 2] = wk3i * x0r + wk3r * x0i; + a[j3 + 3] = wk3i * x0i - wk3r * x0r; +} + + +#ifdef USE_CDFT_THREADS +struct cdft_arg_st { + int n0; + int n; + double *a; + int nw; + double *w; +}; +typedef struct cdft_arg_st cdft_arg_t; + + +void cftrec4_th(int n, double *a, int nw, double *w) +{ + void *cftrec1_th(void *p); + void *cftrec2_th(void *p); + int i, idiv4, m, nthread; + cdft_thread_t th[4]; + cdft_arg_t ag[4]; + + nthread = 2; + idiv4 = 0; + m = n >> 1; + if (n > CDFT_4THREADS_BEGIN_N) { + nthread = 4; + idiv4 = 1; + m >>= 1; + } + for (i = 0; i < nthread; i++) { + ag[i].n0 = n; + ag[i].n = m; + ag[i].a = &a[i * m]; + ag[i].nw = nw; + ag[i].w = w; + if (i != idiv4) { + cdft_thread_create(&th[i], cftrec1_th, &ag[i]); + } else { + cdft_thread_create(&th[i], cftrec2_th, &ag[i]); + } + } + for (i = 0; i < nthread; i++) { + cdft_thread_wait(th[i]); + } +} + + +void *cftrec1_th(void *p) +{ + int cfttree(int n, int j, int k, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftmdl1(int n, double *a, double *w); + int isplt, j, k, m, n, n0, nw; + double *a, *w; + + n0 = ((cdft_arg_t *) p)->n0; + n = ((cdft_arg_t *) p)->n; + a = ((cdft_arg_t *) p)->a; + nw = ((cdft_arg_t *) p)->nw; + w = ((cdft_arg_t *) p)->w; + m = n0; + while (m > 512) { + m >>= 2; + cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]); + } + cftleaf(m, 1, &a[n - m], nw, w); + k = 0; + for (j = n - m; j > 0; j -= m) { + k++; + isplt = cfttree(m, j, k, a, nw, w); + cftleaf(m, isplt, &a[j - m], nw, w); + } + return (void *) 0; +} + + +void *cftrec2_th(void *p) +{ + int cfttree(int n, int j, int k, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftmdl2(int n, double *a, double *w); + int isplt, j, k, m, n, n0, nw; + double *a, *w; + + n0 = ((cdft_arg_t *) p)->n0; + n = ((cdft_arg_t *) p)->n; + a = ((cdft_arg_t *) p)->a; + nw = ((cdft_arg_t *) p)->nw; + w = ((cdft_arg_t *) p)->w; + k = 1; + m = n0; + while (m > 512) { + m >>= 2; + k <<= 2; + cftmdl2(m, &a[n - m], &w[nw - m]); + } + cftleaf(m, 0, &a[n - m], nw, w); + k >>= 1; + for (j = n - m; j > 0; j -= m) { + k++; + isplt = cfttree(m, j, k, a, nw, w); + cftleaf(m, isplt, &a[j - m], nw, w); + } + return (void *) 0; +} +#endif /* USE_CDFT_THREADS */ + + +void cftrec4(int n, double *a, int nw, double *w) +{ + int cfttree(int n, int j, int k, double *a, int nw, double *w); + void cftleaf(int n, int isplt, double *a, int nw, double *w); + void cftmdl1(int n, double *a, double *w); + int isplt, j, k, m; + + m = n; + while (m > 512) { + m >>= 2; + cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]); + } + cftleaf(m, 1, &a[n - m], nw, w); + k = 0; + for (j = n - m; j > 0; j -= m) { + k++; + isplt = cfttree(m, j, k, a, nw, w); + cftleaf(m, isplt, &a[j - m], nw, w); + } +} + + +int cfttree(int n, int j, int k, double *a, int nw, double *w) +{ + void cftmdl1(int n, double *a, double *w); + void cftmdl2(int n, double *a, double *w); + int i, isplt, m; + + if ((k & 3) != 0) { + isplt = k & 1; + if (isplt != 0) { + cftmdl1(n, &a[j - n], &w[nw - (n >> 1)]); + } else { + cftmdl2(n, &a[j - n], &w[nw - n]); + } + } else { + m = n; + for (i = k; (i & 3) == 0; i >>= 2) { + m <<= 2; + } + isplt = i & 1; + if (isplt != 0) { + while (m > 128) { + cftmdl1(m, &a[j - m], &w[nw - (m >> 1)]); + m >>= 2; + } + } else { + while (m > 128) { + cftmdl2(m, &a[j - m], &w[nw - m]); + m >>= 2; + } + } + } + return isplt; +} + + +void cftleaf(int n, int isplt, double *a, int nw, double *w) +{ + void cftmdl1(int n, double *a, double *w); + void cftmdl2(int n, double *a, double *w); + void cftf161(double *a, double *w); + void cftf162(double *a, double *w); + void cftf081(double *a, double *w); + void cftf082(double *a, double *w); + + if (n == 512) { + cftmdl1(128, a, &w[nw - 64]); + cftf161(a, &w[nw - 8]); + cftf162(&a[32], &w[nw - 32]); + cftf161(&a[64], &w[nw - 8]); + cftf161(&a[96], &w[nw - 8]); + cftmdl2(128, &a[128], &w[nw - 128]); + cftf161(&a[128], &w[nw - 8]); + cftf162(&a[160], &w[nw - 32]); + cftf161(&a[192], &w[nw - 8]); + cftf162(&a[224], &w[nw - 32]); + cftmdl1(128, &a[256], &w[nw - 64]); + cftf161(&a[256], &w[nw - 8]); + cftf162(&a[288], &w[nw - 32]); + cftf161(&a[320], &w[nw - 8]); + cftf161(&a[352], &w[nw - 8]); + if (isplt != 0) { + cftmdl1(128, &a[384], &w[nw - 64]); + cftf161(&a[480], &w[nw - 8]); + } else { + cftmdl2(128, &a[384], &w[nw - 128]); + cftf162(&a[480], &w[nw - 32]); + } + cftf161(&a[384], &w[nw - 8]); + cftf162(&a[416], &w[nw - 32]); + cftf161(&a[448], &w[nw - 8]); + } else { + cftmdl1(64, a, &w[nw - 32]); + cftf081(a, &w[nw - 8]); + cftf082(&a[16], &w[nw - 8]); + cftf081(&a[32], &w[nw - 8]); + cftf081(&a[48], &w[nw - 8]); + cftmdl2(64, &a[64], &w[nw - 64]); + cftf081(&a[64], &w[nw - 8]); + cftf082(&a[80], &w[nw - 8]); + cftf081(&a[96], &w[nw - 8]); + cftf082(&a[112], &w[nw - 8]); + cftmdl1(64, &a[128], &w[nw - 32]); + cftf081(&a[128], &w[nw - 8]); + cftf082(&a[144], &w[nw - 8]); + cftf081(&a[160], &w[nw - 8]); + cftf081(&a[176], &w[nw - 8]); + if (isplt != 0) { + cftmdl1(64, &a[192], &w[nw - 32]); + cftf081(&a[240], &w[nw - 8]); + } else { + cftmdl2(64, &a[192], &w[nw - 64]); + cftf082(&a[240], &w[nw - 8]); + } + cftf081(&a[192], &w[nw - 8]); + cftf082(&a[208], &w[nw - 8]); + cftf081(&a[224], &w[nw - 8]); + } +} + + +void cftmdl1(int n, double *a, double *w) +{ + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, wk1r, wk1i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = a[1] + a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = a[1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j2] = x1r - x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + k = 0; + for (j = 2; j < mh; j += 2) { + k += 4; + wk1r = w[k]; + wk1i = w[k + 1]; + wk3r = w[k + 2]; + wk3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = a[j + 1] + a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = a[j + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + } + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); +} + + +void cftmdl2(int n, double *a, double *w) +{ + int j, j0, j1, j2, j3, k, kr, m, mh; + double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i; + + mh = n >> 3; + m = 2 * mh; + wn4r = w[1]; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] - a[j2 + 1]; + x0i = a[1] + a[j2]; + x1r = a[0] + a[j2 + 1]; + x1i = a[1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wn4r * (x2r - x2i); + y0i = wn4r * (x2i + x2r); + a[0] = x0r + y0r; + a[1] = x0i + y0i; + a[j1] = x0r - y0r; + a[j1 + 1] = x0i - y0i; + y0r = wn4r * (x3r - x3i); + y0i = wn4r * (x3i + x3r); + a[j2] = x1r - y0i; + a[j2 + 1] = x1i + y0r; + a[j3] = x1r + y0i; + a[j3 + 1] = x1i - y0r; + k = 0; + kr = 2 * m; + for (j = 2; j < mh; j += 2) { + k += 4; + wk1r = w[k]; + wk1i = w[k + 1]; + wk3r = w[k + 2]; + wk3i = w[k + 3]; + kr -= 4; + wd1i = w[kr]; + wd1r = w[kr + 1]; + wd3i = w[kr + 2]; + wd3r = w[kr + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] - a[j2 + 1]; + x0i = a[j + 1] + a[j2]; + x1r = a[j] + a[j2 + 1]; + x1i = a[j + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wk1r * x0r - wk1i * x0i; + y0i = wk1r * x0i + wk1i * x0r; + y2r = wd1r * x2r - wd1i * x2i; + y2i = wd1r * x2i + wd1i * x2r; + a[j] = y0r + y2r; + a[j + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wk3r * x1r + wk3i * x1i; + y0i = wk3r * x1i - wk3i * x1r; + y2r = wd3r * x3r + wd3i * x3i; + y2i = wd3r * x3i - wd3i * x3r; + a[j2] = y0r + y2r; + a[j2 + 1] = y0i + y2i; + a[j3] = y0r - y2r; + a[j3 + 1] = y0i - y2i; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] - a[j2 + 1]; + x0i = a[j0 + 1] + a[j2]; + x1r = a[j0] + a[j2 + 1]; + x1i = a[j0 + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wd1i * x0r - wd1r * x0i; + y0i = wd1i * x0i + wd1r * x0r; + y2r = wk1i * x2r - wk1r * x2i; + y2i = wk1i * x2i + wk1r * x2r; + a[j0] = y0r + y2r; + a[j0 + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wd3i * x1r + wd3r * x1i; + y0i = wd3i * x1i - wd3r * x1r; + y2r = wk3i * x3r + wk3r * x3i; + y2i = wk3i * x3i - wk3r * x3r; + a[j2] = y0r + y2r; + a[j2 + 1] = y0i + y2i; + a[j3] = y0r - y2r; + a[j3 + 1] = y0i - y2i; + } + wk1r = w[m]; + wk1i = w[m + 1]; + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] - a[j2 + 1]; + x0i = a[j0 + 1] + a[j2]; + x1r = a[j0] + a[j2 + 1]; + x1i = a[j0 + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wk1r * x0r - wk1i * x0i; + y0i = wk1r * x0i + wk1i * x0r; + y2r = wk1i * x2r - wk1r * x2i; + y2i = wk1i * x2i + wk1r * x2r; + a[j0] = y0r + y2r; + a[j0 + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wk1i * x1r - wk1r * x1i; + y0i = wk1i * x1i + wk1r * x1r; + y2r = wk1r * x3r - wk1i * x3i; + y2i = wk1r * x3i + wk1i * x3r; + a[j2] = y0r - y2r; + a[j2 + 1] = y0i - y2i; + a[j3] = y0r + y2r; + a[j3 + 1] = y0i + y2i; +} + + +void cftfx41(int n, double *a, int nw, double *w) +{ + void cftf161(double *a, double *w); + void cftf162(double *a, double *w); + void cftf081(double *a, double *w); + void cftf082(double *a, double *w); + + if (n == 128) { + cftf161(a, &w[nw - 8]); + cftf162(&a[32], &w[nw - 32]); + cftf161(&a[64], &w[nw - 8]); + cftf161(&a[96], &w[nw - 8]); + } else { + cftf081(a, &w[nw - 8]); + cftf082(&a[16], &w[nw - 8]); + cftf081(&a[32], &w[nw - 8]); + cftf081(&a[48], &w[nw - 8]); + } +} + + +void cftf161(double *a, double *w) +{ + double wn4r, wk1r, wk1i, + x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, + y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, + y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; + + wn4r = w[1]; + wk1r = w[2]; + wk1i = w[3]; + x0r = a[0] + a[16]; + x0i = a[1] + a[17]; + x1r = a[0] - a[16]; + x1i = a[1] - a[17]; + x2r = a[8] + a[24]; + x2i = a[9] + a[25]; + x3r = a[8] - a[24]; + x3i = a[9] - a[25]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y4r = x0r - x2r; + y4i = x0i - x2i; + y8r = x1r - x3i; + y8i = x1i + x3r; + y12r = x1r + x3i; + y12i = x1i - x3r; + x0r = a[2] + a[18]; + x0i = a[3] + a[19]; + x1r = a[2] - a[18]; + x1i = a[3] - a[19]; + x2r = a[10] + a[26]; + x2i = a[11] + a[27]; + x3r = a[10] - a[26]; + x3i = a[11] - a[27]; + y1r = x0r + x2r; + y1i = x0i + x2i; + y5r = x0r - x2r; + y5i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y9r = wk1r * x0r - wk1i * x0i; + y9i = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + y13r = wk1i * x0r - wk1r * x0i; + y13i = wk1i * x0i + wk1r * x0r; + x0r = a[4] + a[20]; + x0i = a[5] + a[21]; + x1r = a[4] - a[20]; + x1i = a[5] - a[21]; + x2r = a[12] + a[28]; + x2i = a[13] + a[29]; + x3r = a[12] - a[28]; + x3i = a[13] - a[29]; + y2r = x0r + x2r; + y2i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y10r = wn4r * (x0r - x0i); + y10i = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + y14r = wn4r * (x0r + x0i); + y14i = wn4r * (x0i - x0r); + x0r = a[6] + a[22]; + x0i = a[7] + a[23]; + x1r = a[6] - a[22]; + x1i = a[7] - a[23]; + x2r = a[14] + a[30]; + x2i = a[15] + a[31]; + x3r = a[14] - a[30]; + x3i = a[15] - a[31]; + y3r = x0r + x2r; + y3i = x0i + x2i; + y7r = x0r - x2r; + y7i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y11r = wk1i * x0r - wk1r * x0i; + y11i = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + y15r = wk1r * x0r - wk1i * x0i; + y15i = wk1r * x0i + wk1i * x0r; + x0r = y12r - y14r; + x0i = y12i - y14i; + x1r = y12r + y14r; + x1i = y12i + y14i; + x2r = y13r - y15r; + x2i = y13i - y15i; + x3r = y13r + y15r; + x3i = y13i + y15i; + a[24] = x0r + x2r; + a[25] = x0i + x2i; + a[26] = x0r - x2r; + a[27] = x0i - x2i; + a[28] = x1r - x3i; + a[29] = x1i + x3r; + a[30] = x1r + x3i; + a[31] = x1i - x3r; + x0r = y8r + y10r; + x0i = y8i + y10i; + x1r = y8r - y10r; + x1i = y8i - y10i; + x2r = y9r + y11r; + x2i = y9i + y11i; + x3r = y9r - y11r; + x3i = y9i - y11i; + a[16] = x0r + x2r; + a[17] = x0i + x2i; + a[18] = x0r - x2r; + a[19] = x0i - x2i; + a[20] = x1r - x3i; + a[21] = x1i + x3r; + a[22] = x1r + x3i; + a[23] = x1i - x3r; + x0r = y5r - y7i; + x0i = y5i + y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + x0r = y5r + y7i; + x0i = y5i - y7r; + x3r = wn4r * (x0r - x0i); + x3i = wn4r * (x0i + x0r); + x0r = y4r - y6i; + x0i = y4i + y6r; + x1r = y4r + y6i; + x1i = y4i - y6r; + a[8] = x0r + x2r; + a[9] = x0i + x2i; + a[10] = x0r - x2r; + a[11] = x0i - x2i; + a[12] = x1r - x3i; + a[13] = x1i + x3r; + a[14] = x1r + x3i; + a[15] = x1i - x3r; + x0r = y0r + y2r; + x0i = y0i + y2i; + x1r = y0r - y2r; + x1i = y0i - y2i; + x2r = y1r + y3r; + x2i = y1i + y3i; + x3r = y1r - y3r; + x3i = y1i - y3i; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x0r - x2r; + a[3] = x0i - x2i; + a[4] = x1r - x3i; + a[5] = x1i + x3r; + a[6] = x1r + x3i; + a[7] = x1i - x3r; +} + + +void cftf162(double *a, double *w) +{ + double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, + x0r, x0i, x1r, x1i, x2r, x2i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, + y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, + y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; + + wn4r = w[1]; + wk1r = w[4]; + wk1i = w[5]; + wk3r = w[6]; + wk3i = -w[7]; + wk2r = w[8]; + wk2i = w[9]; + x1r = a[0] - a[17]; + x1i = a[1] + a[16]; + x0r = a[8] - a[25]; + x0i = a[9] + a[24]; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + y0r = x1r + x2r; + y0i = x1i + x2i; + y4r = x1r - x2r; + y4i = x1i - x2i; + x1r = a[0] + a[17]; + x1i = a[1] - a[16]; + x0r = a[8] + a[25]; + x0i = a[9] - a[24]; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + y8r = x1r - x2i; + y8i = x1i + x2r; + y12r = x1r + x2i; + y12i = x1i - x2r; + x0r = a[2] - a[19]; + x0i = a[3] + a[18]; + x1r = wk1r * x0r - wk1i * x0i; + x1i = wk1r * x0i + wk1i * x0r; + x0r = a[10] - a[27]; + x0i = a[11] + a[26]; + x2r = wk3i * x0r - wk3r * x0i; + x2i = wk3i * x0i + wk3r * x0r; + y1r = x1r + x2r; + y1i = x1i + x2i; + y5r = x1r - x2r; + y5i = x1i - x2i; + x0r = a[2] + a[19]; + x0i = a[3] - a[18]; + x1r = wk3r * x0r - wk3i * x0i; + x1i = wk3r * x0i + wk3i * x0r; + x0r = a[10] + a[27]; + x0i = a[11] - a[26]; + x2r = wk1r * x0r + wk1i * x0i; + x2i = wk1r * x0i - wk1i * x0r; + y9r = x1r - x2r; + y9i = x1i - x2i; + y13r = x1r + x2r; + y13i = x1i + x2i; + x0r = a[4] - a[21]; + x0i = a[5] + a[20]; + x1r = wk2r * x0r - wk2i * x0i; + x1i = wk2r * x0i + wk2i * x0r; + x0r = a[12] - a[29]; + x0i = a[13] + a[28]; + x2r = wk2i * x0r - wk2r * x0i; + x2i = wk2i * x0i + wk2r * x0r; + y2r = x1r + x2r; + y2i = x1i + x2i; + y6r = x1r - x2r; + y6i = x1i - x2i; + x0r = a[4] + a[21]; + x0i = a[5] - a[20]; + x1r = wk2i * x0r - wk2r * x0i; + x1i = wk2i * x0i + wk2r * x0r; + x0r = a[12] + a[29]; + x0i = a[13] - a[28]; + x2r = wk2r * x0r - wk2i * x0i; + x2i = wk2r * x0i + wk2i * x0r; + y10r = x1r - x2r; + y10i = x1i - x2i; + y14r = x1r + x2r; + y14i = x1i + x2i; + x0r = a[6] - a[23]; + x0i = a[7] + a[22]; + x1r = wk3r * x0r - wk3i * x0i; + x1i = wk3r * x0i + wk3i * x0r; + x0r = a[14] - a[31]; + x0i = a[15] + a[30]; + x2r = wk1i * x0r - wk1r * x0i; + x2i = wk1i * x0i + wk1r * x0r; + y3r = x1r + x2r; + y3i = x1i + x2i; + y7r = x1r - x2r; + y7i = x1i - x2i; + x0r = a[6] + a[23]; + x0i = a[7] - a[22]; + x1r = wk1i * x0r + wk1r * x0i; + x1i = wk1i * x0i - wk1r * x0r; + x0r = a[14] + a[31]; + x0i = a[15] - a[30]; + x2r = wk3i * x0r - wk3r * x0i; + x2i = wk3i * x0i + wk3r * x0r; + y11r = x1r + x2r; + y11i = x1i + x2i; + y15r = x1r - x2r; + y15i = x1i - x2i; + x1r = y0r + y2r; + x1i = y0i + y2i; + x2r = y1r + y3r; + x2i = y1i + y3i; + a[0] = x1r + x2r; + a[1] = x1i + x2i; + a[2] = x1r - x2r; + a[3] = x1i - x2i; + x1r = y0r - y2r; + x1i = y0i - y2i; + x2r = y1r - y3r; + x2i = y1i - y3i; + a[4] = x1r - x2i; + a[5] = x1i + x2r; + a[6] = x1r + x2i; + a[7] = x1i - x2r; + x1r = y4r - y6i; + x1i = y4i + y6r; + x0r = y5r - y7i; + x0i = y5i + y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[8] = x1r + x2r; + a[9] = x1i + x2i; + a[10] = x1r - x2r; + a[11] = x1i - x2i; + x1r = y4r + y6i; + x1i = y4i - y6r; + x0r = y5r + y7i; + x0i = y5i - y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[12] = x1r - x2i; + a[13] = x1i + x2r; + a[14] = x1r + x2i; + a[15] = x1i - x2r; + x1r = y8r + y10r; + x1i = y8i + y10i; + x2r = y9r - y11r; + x2i = y9i - y11i; + a[16] = x1r + x2r; + a[17] = x1i + x2i; + a[18] = x1r - x2r; + a[19] = x1i - x2i; + x1r = y8r - y10r; + x1i = y8i - y10i; + x2r = y9r + y11r; + x2i = y9i + y11i; + a[20] = x1r - x2i; + a[21] = x1i + x2r; + a[22] = x1r + x2i; + a[23] = x1i - x2r; + x1r = y12r - y14i; + x1i = y12i + y14r; + x0r = y13r + y15i; + x0i = y13i - y15r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[24] = x1r + x2r; + a[25] = x1i + x2i; + a[26] = x1r - x2r; + a[27] = x1i - x2i; + x1r = y12r + y14i; + x1i = y12i - y14r; + x0r = y13r - y15i; + x0i = y13i + y15r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[28] = x1r - x2i; + a[29] = x1i + x2r; + a[30] = x1r + x2i; + a[31] = x1i - x2r; +} + + +void cftf081(double *a, double *w) +{ + double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + wn4r = w[1]; + x0r = a[0] + a[8]; + x0i = a[1] + a[9]; + x1r = a[0] - a[8]; + x1i = a[1] - a[9]; + x2r = a[4] + a[12]; + x2i = a[5] + a[13]; + x3r = a[4] - a[12]; + x3i = a[5] - a[13]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[2] + a[10]; + x0i = a[3] + a[11]; + x1r = a[2] - a[10]; + x1i = a[3] - a[11]; + x2r = a[6] + a[14]; + x2i = a[7] + a[15]; + x3r = a[6] - a[14]; + x3i = a[7] - a[15]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x1i - x3r; + y5r = wn4r * (x0r - x0i); + y5i = wn4r * (x0r + x0i); + y7r = wn4r * (x2r - x2i); + y7i = wn4r * (x2r + x2i); + a[8] = y1r + y5r; + a[9] = y1i + y5i; + a[10] = y1r - y5r; + a[11] = y1i - y5i; + a[12] = y3r - y7i; + a[13] = y3i + y7r; + a[14] = y3r + y7i; + a[15] = y3i - y7r; + a[0] = y0r + y4r; + a[1] = y0i + y4i; + a[2] = y0r - y4r; + a[3] = y0i - y4i; + a[4] = y2r - y6i; + a[5] = y2i + y6r; + a[6] = y2r + y6i; + a[7] = y2i - y6r; +} + + +void cftf082(double *a, double *w) +{ + double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + wn4r = w[1]; + wk1r = w[2]; + wk1i = w[3]; + y0r = a[0] - a[9]; + y0i = a[1] + a[8]; + y1r = a[0] + a[9]; + y1i = a[1] - a[8]; + x0r = a[4] - a[13]; + x0i = a[5] + a[12]; + y2r = wn4r * (x0r - x0i); + y2i = wn4r * (x0i + x0r); + x0r = a[4] + a[13]; + x0i = a[5] - a[12]; + y3r = wn4r * (x0r - x0i); + y3i = wn4r * (x0i + x0r); + x0r = a[2] - a[11]; + x0i = a[3] + a[10]; + y4r = wk1r * x0r - wk1i * x0i; + y4i = wk1r * x0i + wk1i * x0r; + x0r = a[2] + a[11]; + x0i = a[3] - a[10]; + y5r = wk1i * x0r - wk1r * x0i; + y5i = wk1i * x0i + wk1r * x0r; + x0r = a[6] - a[15]; + x0i = a[7] + a[14]; + y6r = wk1i * x0r - wk1r * x0i; + y6i = wk1i * x0i + wk1r * x0r; + x0r = a[6] + a[15]; + x0i = a[7] - a[14]; + y7r = wk1r * x0r - wk1i * x0i; + y7i = wk1r * x0i + wk1i * x0r; + x0r = y0r + y2r; + x0i = y0i + y2i; + x1r = y4r + y6r; + x1i = y4i + y6i; + a[0] = x0r + x1r; + a[1] = x0i + x1i; + a[2] = x0r - x1r; + a[3] = x0i - x1i; + x0r = y0r - y2r; + x0i = y0i - y2i; + x1r = y4r - y6r; + x1i = y4i - y6i; + a[4] = x0r - x1i; + a[5] = x0i + x1r; + a[6] = x0r + x1i; + a[7] = x0i - x1r; + x0r = y1r - y3i; + x0i = y1i + y3r; + x1r = y5r - y7r; + x1i = y5i - y7i; + a[8] = x0r + x1r; + a[9] = x0i + x1i; + a[10] = x0r - x1r; + a[11] = x0i - x1i; + x0r = y1r + y3i; + x0i = y1i - y3r; + x1r = y5r + y7r; + x1i = y5i + y7i; + a[12] = x0r - x1i; + a[13] = x0i + x1r; + a[14] = x0r + x1i; + a[15] = x0i - x1r; +} + + +void cftf040(double *a) +{ + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[4]; + x0i = a[1] + a[5]; + x1r = a[0] - a[4]; + x1i = a[1] - a[5]; + x2r = a[2] + a[6]; + x2i = a[3] + a[7]; + x3r = a[2] - a[6]; + x3i = a[3] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x1r - x3i; + a[3] = x1i + x3r; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[6] = x1r + x3i; + a[7] = x1i - x3r; +} + + +void cftb040(double *a) +{ + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[4]; + x0i = a[1] + a[5]; + x1r = a[0] - a[4]; + x1i = a[1] - a[5]; + x2r = a[2] + a[6]; + x2i = a[3] + a[7]; + x3r = a[2] - a[6]; + x3i = a[3] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x1r + x3i; + a[3] = x1i - x3r; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[6] = x1r - x3i; + a[7] = x1i + x3r; +} + + +void cftx020(double *a) +{ + double x0r, x0i; + + x0r = a[0] - a[2]; + x0i = a[1] - a[3]; + a[0] += a[2]; + a[1] += a[3]; + a[2] = x0r; + a[3] = x0i; +} + + +void rftfsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) { + k = n - j; + kk += ks; + wkr = 0.5 - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } +} + + +void rftbsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) { + k = n - j; + kk += ks; + wkr = 0.5 - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr + wki * xi; + yi = wkr * xi - wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } +} + + +void dctsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for (j = 1; j < m; j++) { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[j] - wkr * a[k]; + a[j] = wkr * a[j] + wki * a[k]; + a[k] = xr; + } + a[m] *= c[0]; +} + + +void dstsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for (j = 1; j < m; j++) { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[k] - wkr * a[j]; + a[k] = wkr * a[k] + wki * a[j]; + a[j] = xr; + } + a[m] *= c[0]; +} +
diff --git a/third_party/fft2d/src/fftsg2d.c b/third_party/fft2d/src/fftsg2d.c new file mode 100644 index 0000000..2ebfa9394 --- /dev/null +++ b/third_party/fft2d/src/fftsg2d.c
@@ -0,0 +1,1190 @@ +/* +Fast Fourier/Cosine/Sine Transform + dimension :two + data length :power of 2 + decimation :frequency + radix :split-radix, row-column + data :inplace + table :use +functions + cdft2d: Complex Discrete Fourier Transform + rdft2d: Real Discrete Fourier Transform + ddct2d: Discrete Cosine Transform + ddst2d: Discrete Sine Transform +function prototypes + void cdft2d(int, int, int, double **, double *, int *, double *); + void rdft2d(int, int, int, double **, double *, int *, double *); + void rdft2dsort(int, int, int, double **); + void ddct2d(int, int, int, double **, double *, int *, double *); + void ddst2d(int, int, int, double **, double *, int *, double *); +necessary package + fftsg.c : 1D-FFT package +macro definitions + USE_FFT2D_PTHREADS : default=not defined + FFT2D_MAX_THREADS : must be 2^N, default=4 + FFT2D_THREADS_BEGIN_N : default=65536 + USE_FFT2D_WINTHREADS : default=not defined + FFT2D_MAX_THREADS : must be 2^N, default=4 + FFT2D_THREADS_BEGIN_N : default=131072 + + +-------- Complex DFT (Discrete Fourier Transform) -------- + [definition] + <case1> + X[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 x[j1][j2] * + exp(2*pi*i*j1*k1/n1) * + exp(2*pi*i*j2*k2/n2), 0<=k1<n1, 0<=k2<n2 + <case2> + X[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 x[j1][j2] * + exp(-2*pi*i*j1*k1/n1) * + exp(-2*pi*i*j2*k2/n2), 0<=k1<n1, 0<=k2<n2 + (notes: sum_j=0^n-1 is a summation from j=0 to n-1) + [usage] + <case1> + ip[0] = 0; // first time only + cdft2d(n1, 2*n2, 1, a, t, ip, w); + <case2> + ip[0] = 0; // first time only + cdft2d(n1, 2*n2, -1, a, t, ip, w); + [parameters] + n1 :data length (int) + n1 >= 1, n1 = power of 2 + 2*n2 :data length (int) + n2 >= 1, n2 = power of 2 + a[0...n1-1][0...2*n2-1] + :input/output data (double **) + input data + a[j1][2*j2] = Re(x[j1][j2]), + a[j1][2*j2+1] = Im(x[j1][j2]), + 0<=j1<n1, 0<=j2<n2 + output data + a[k1][2*k2] = Re(X[k1][k2]), + a[k1][2*k2+1] = Im(X[k1][k2]), + 0<=k1<n1, 0<=k2<n2 + t[0...*] + :work area (double *) + length of t >= 8*n1, if single thread, + length of t >= 8*n1*FFT2D_MAX_THREADS, if multi threads, + t is dynamically allocated, if t == NULL. + ip[0...*] + :work area for bit reversal (int *) + length of ip >= 2+sqrt(n) + (n = max(n1, n2)) + ip[0],ip[1] are pointers of the cos/sin table. + w[0...*] + :cos/sin table (double *) + length of w >= max(n1/2, n2/2) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + cdft2d(n1, 2*n2, -1, a, t, ip, w); + is + cdft2d(n1, 2*n2, 1, a, t, ip, w); + for (j1 = 0; j1 <= n1 - 1; j1++) { + for (j2 = 0; j2 <= 2 * n2 - 1; j2++) { + a[j1][j2] *= 1.0 / n1 / n2; + } + } + . + + +-------- Real DFT / Inverse of Real DFT -------- + [definition] + <case1> RDFT + R[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 a[j1][j2] * + cos(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2), + 0<=k1<n1, 0<=k2<n2 + I[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 a[j1][j2] * + sin(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2), + 0<=k1<n1, 0<=k2<n2 + <case2> IRDFT (excluding scale) + a[k1][k2] = (1/2) * sum_j1=0^n1-1 sum_j2=0^n2-1 + (R[j1][j2] * + cos(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2) + + I[j1][j2] * + sin(2*pi*j1*k1/n1 + 2*pi*j2*k2/n2)), + 0<=k1<n1, 0<=k2<n2 + (notes: R[n1-k1][n2-k2] = R[k1][k2], + I[n1-k1][n2-k2] = -I[k1][k2], + R[n1-k1][0] = R[k1][0], + I[n1-k1][0] = -I[k1][0], + R[0][n2-k2] = R[0][k2], + I[0][n2-k2] = -I[0][k2], + 0<k1<n1, 0<k2<n2) + [usage] + <case1> + ip[0] = 0; // first time only + rdft2d(n1, n2, 1, a, t, ip, w); + <case2> + ip[0] = 0; // first time only + rdft2d(n1, n2, -1, a, t, ip, w); + [parameters] + n1 :data length (int) + n1 >= 2, n1 = power of 2 + n2 :data length (int) + n2 >= 2, n2 = power of 2 + a[0...n1-1][0...n2-1] + :input/output data (double **) + <case1> + output data + a[k1][2*k2] = R[k1][k2] = R[n1-k1][n2-k2], + a[k1][2*k2+1] = I[k1][k2] = -I[n1-k1][n2-k2], + 0<k1<n1, 0<k2<n2/2, + a[0][2*k2] = R[0][k2] = R[0][n2-k2], + a[0][2*k2+1] = I[0][k2] = -I[0][n2-k2], + 0<k2<n2/2, + a[k1][0] = R[k1][0] = R[n1-k1][0], + a[k1][1] = I[k1][0] = -I[n1-k1][0], + a[n1-k1][1] = R[k1][n2/2] = R[n1-k1][n2/2], + a[n1-k1][0] = -I[k1][n2/2] = I[n1-k1][n2/2], + 0<k1<n1/2, + a[0][0] = R[0][0], + a[0][1] = R[0][n2/2], + a[n1/2][0] = R[n1/2][0], + a[n1/2][1] = R[n1/2][n2/2] + <case2> + input data + a[j1][2*j2] = R[j1][j2] = R[n1-j1][n2-j2], + a[j1][2*j2+1] = I[j1][j2] = -I[n1-j1][n2-j2], + 0<j1<n1, 0<j2<n2/2, + a[0][2*j2] = R[0][j2] = R[0][n2-j2], + a[0][2*j2+1] = I[0][j2] = -I[0][n2-j2], + 0<j2<n2/2, + a[j1][0] = R[j1][0] = R[n1-j1][0], + a[j1][1] = I[j1][0] = -I[n1-j1][0], + a[n1-j1][1] = R[j1][n2/2] = R[n1-j1][n2/2], + a[n1-j1][0] = -I[j1][n2/2] = I[n1-j1][n2/2], + 0<j1<n1/2, + a[0][0] = R[0][0], + a[0][1] = R[0][n2/2], + a[n1/2][0] = R[n1/2][0], + a[n1/2][1] = R[n1/2][n2/2] + ---- output ordering ---- + rdft2d(n1, n2, 1, a, t, ip, w); + rdft2dsort(n1, n2, 1, a); + // stored data is a[0...n1-1][0...n2+1]: + // a[k1][2*k2] = R[k1][k2], + // a[k1][2*k2+1] = I[k1][k2], + // 0<=k1<n1, 0<=k2<=n2/2. + // the stored data is larger than the input data! + ---- input ordering ---- + rdft2dsort(n1, n2, -1, a); + rdft2d(n1, n2, -1, a, t, ip, w); + t[0...*] + :work area (double *) + length of t >= 8*n1, if single thread, + length of t >= 8*n1*FFT2D_MAX_THREADS, if multi threads, + t is dynamically allocated, if t == NULL. + ip[0...*] + :work area for bit reversal (int *) + length of ip >= 2+sqrt(n) + (n = max(n1, n2/2)) + ip[0],ip[1] are pointers of the cos/sin table. + w[0...*] + :cos/sin table (double *) + length of w >= max(n1/2, n2/4) + n2/4 + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + rdft2d(n1, n2, 1, a, t, ip, w); + is + rdft2d(n1, n2, -1, a, t, ip, w); + for (j1 = 0; j1 <= n1 - 1; j1++) { + for (j2 = 0; j2 <= n2 - 1; j2++) { + a[j1][j2] *= 2.0 / n1 / n2; + } + } + . + + +-------- DCT (Discrete Cosine Transform) / Inverse of DCT -------- + [definition] + <case1> IDCT (excluding scale) + C[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 a[j1][j2] * + cos(pi*j1*(k1+1/2)/n1) * + cos(pi*j2*(k2+1/2)/n2), + 0<=k1<n1, 0<=k2<n2 + <case2> DCT + C[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 a[j1][j2] * + cos(pi*(j1+1/2)*k1/n1) * + cos(pi*(j2+1/2)*k2/n2), + 0<=k1<n1, 0<=k2<n2 + [usage] + <case1> + ip[0] = 0; // first time only + ddct2d(n1, n2, 1, a, t, ip, w); + <case2> + ip[0] = 0; // first time only + ddct2d(n1, n2, -1, a, t, ip, w); + [parameters] + n1 :data length (int) + n1 >= 2, n1 = power of 2 + n2 :data length (int) + n2 >= 2, n2 = power of 2 + a[0...n1-1][0...n2-1] + :input/output data (double **) + output data + a[k1][k2] = C[k1][k2], 0<=k1<n1, 0<=k2<n2 + t[0...*] + :work area (double *) + length of t >= 4*n1, if single thread, + length of t >= 4*n1*FFT2D_MAX_THREADS, if multi threads, + t is dynamically allocated, if t == NULL. + ip[0...*] + :work area for bit reversal (int *) + length of ip >= 2+sqrt(n) + (n = max(n1/2, n2/2)) + ip[0],ip[1] are pointers of the cos/sin table. + w[0...*] + :cos/sin table (double *) + length of w >= max(n1*3/2, n2*3/2) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddct2d(n1, n2, -1, a, t, ip, w); + is + for (j1 = 0; j1 <= n1 - 1; j1++) { + a[j1][0] *= 0.5; + } + for (j2 = 0; j2 <= n2 - 1; j2++) { + a[0][j2] *= 0.5; + } + ddct2d(n1, n2, 1, a, t, ip, w); + for (j1 = 0; j1 <= n1 - 1; j1++) { + for (j2 = 0; j2 <= n2 - 1; j2++) { + a[j1][j2] *= 4.0 / n1 / n2; + } + } + . + + +-------- DST (Discrete Sine Transform) / Inverse of DST -------- + [definition] + <case1> IDST (excluding scale) + S[k1][k2] = sum_j1=1^n1 sum_j2=1^n2 A[j1][j2] * + sin(pi*j1*(k1+1/2)/n1) * + sin(pi*j2*(k2+1/2)/n2), + 0<=k1<n1, 0<=k2<n2 + <case2> DST + S[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 a[j1][j2] * + sin(pi*(j1+1/2)*k1/n1) * + sin(pi*(j2+1/2)*k2/n2), + 0<k1<=n1, 0<k2<=n2 + [usage] + <case1> + ip[0] = 0; // first time only + ddst2d(n1, n2, 1, a, t, ip, w); + <case2> + ip[0] = 0; // first time only + ddst2d(n1, n2, -1, a, t, ip, w); + [parameters] + n1 :data length (int) + n1 >= 2, n1 = power of 2 + n2 :data length (int) + n2 >= 2, n2 = power of 2 + a[0...n1-1][0...n2-1] + :input/output data (double **) + <case1> + input data + a[j1][j2] = A[j1][j2], 0<j1<n1, 0<j2<n2, + a[j1][0] = A[j1][n2], 0<j1<n1, + a[0][j2] = A[n1][j2], 0<j2<n2, + a[0][0] = A[n1][n2] + (i.e. A[j1][j2] = a[j1 % n1][j2 % n2]) + output data + a[k1][k2] = S[k1][k2], 0<=k1<n1, 0<=k2<n2 + <case2> + output data + a[k1][k2] = S[k1][k2], 0<k1<n1, 0<k2<n2, + a[k1][0] = S[k1][n2], 0<k1<n1, + a[0][k2] = S[n1][k2], 0<k2<n2, + a[0][0] = S[n1][n2] + (i.e. S[k1][k2] = a[k1 % n1][k2 % n2]) + t[0...*] + :work area (double *) + length of t >= 4*n1, if single thread, + length of t >= 4*n1*FFT2D_MAX_THREADS, if multi threads, + t is dynamically allocated, if t == NULL. + ip[0...*] + :work area for bit reversal (int *) + length of ip >= 2+sqrt(n) + (n = max(n1/2, n2/2)) + ip[0],ip[1] are pointers of the cos/sin table. + w[0...*] + :cos/sin table (double *) + length of w >= max(n1*3/2, n2*3/2) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddst2d(n1, n2, -1, a, t, ip, w); + is + for (j1 = 0; j1 <= n1 - 1; j1++) { + a[j1][0] *= 0.5; + } + for (j2 = 0; j2 <= n2 - 1; j2++) { + a[0][j2] *= 0.5; + } + ddst2d(n1, n2, 1, a, t, ip, w); + for (j1 = 0; j1 <= n1 - 1; j1++) { + for (j2 = 0; j2 <= n2 - 1; j2++) { + a[j1][j2] *= 4.0 / n1 / n2; + } + } + . +*/ + + +#include <stdio.h> +#include <stdlib.h> +#define fft2d_alloc_error_check(p) { \ + if ((p) == NULL) { \ + fprintf(stderr, "fft2d memory allocation error\n"); \ + exit(1); \ + } \ +} + + +#ifdef USE_FFT2D_PTHREADS +#define USE_FFT2D_THREADS +#ifndef FFT2D_MAX_THREADS +#define FFT2D_MAX_THREADS 4 +#endif +#ifndef FFT2D_THREADS_BEGIN_N +#define FFT2D_THREADS_BEGIN_N 65536 +#endif +#include <pthread.h> +#define fft2d_thread_t pthread_t +#define fft2d_thread_create(thp,func,argp) { \ + if (pthread_create(thp, NULL, func, (void *) (argp)) != 0) { \ + fprintf(stderr, "fft2d thread error\n"); \ + exit(1); \ + } \ +} +#define fft2d_thread_wait(th) { \ + if (pthread_join(th, NULL) != 0) { \ + fprintf(stderr, "fft2d thread error\n"); \ + exit(1); \ + } \ +} +#endif /* USE_FFT2D_PTHREADS */ + + +#ifdef USE_FFT2D_WINTHREADS +#define USE_FFT2D_THREADS +#ifndef FFT2D_MAX_THREADS +#define FFT2D_MAX_THREADS 4 +#endif +#ifndef FFT2D_THREADS_BEGIN_N +#define FFT2D_THREADS_BEGIN_N 131072 +#endif +#include <windows.h> +#define fft2d_thread_t HANDLE +#define fft2d_thread_create(thp,func,argp) { \ + DWORD thid; \ + *(thp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (func), (LPVOID) (argp), 0, &thid); \ + if (*(thp) == 0) { \ + fprintf(stderr, "fft2d thread error\n"); \ + exit(1); \ + } \ +} +#define fft2d_thread_wait(th) { \ + WaitForSingleObject(th, INFINITE); \ + CloseHandle(th); \ +} +#endif /* USE_FFT2D_WINTHREADS */ + + +void cdft2d(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void cdft(int n, int isgn, double *a, int *ip, double *w); + void cdft2d_sub(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w); +#ifdef USE_FFT2D_THREADS + void xdft2d0_subth(int n1, int n2, int icr, int isgn, double **a, + int *ip, double *w); + void cdft2d_subth(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w); +#endif /* USE_FFT2D_THREADS */ + int n, itnull, nthread, nt, i; + + n = n1 << 1; + if (n < n2) { + n = n2; + } + if (n > (ip[0] << 2)) { + makewt(n >> 2, ip, w); + } + itnull = 0; + if (t == NULL) { + itnull = 1; + nthread = 1; +#ifdef USE_FFT2D_THREADS + nthread = FFT2D_MAX_THREADS; +#endif /* USE_FFT2D_THREADS */ + nt = 8 * nthread * n1; + if (n2 == 4 * nthread) { + nt >>= 1; + } else if (n2 < 4 * nthread) { + nt >>= 2; + } + t = (double *) malloc(sizeof(double) * nt); + fft2d_alloc_error_check(t); + } +#ifdef USE_FFT2D_THREADS + if ((double) n1 * n2 >= (double) FFT2D_THREADS_BEGIN_N) { + xdft2d0_subth(n1, n2, 0, isgn, a, ip, w); + cdft2d_subth(n1, n2, isgn, a, t, ip, w); + } else +#endif /* USE_FFT2D_THREADS */ + { + for (i = 0; i < n1; i++) { + cdft(n2, isgn, a[i], ip, w); + } + cdft2d_sub(n1, n2, isgn, a, t, ip, w); + } + if (itnull != 0) { + free(t); + } +} + + +void rdft2d(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void rdft(int n, int isgn, double *a, int *ip, double *w); + void cdft2d_sub(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w); + void rdft2d_sub(int n1, int n2, int isgn, double **a); +#ifdef USE_FFT2D_THREADS + void xdft2d0_subth(int n1, int n2, int icr, int isgn, double **a, + int *ip, double *w); + void cdft2d_subth(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w); +#endif /* USE_FFT2D_THREADS */ + int n, nw, nc, itnull, nthread, nt, i; + + n = n1 << 1; + if (n < n2) { + n = n2; + } + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n2 > (nc << 2)) { + nc = n2 >> 2; + makect(nc, ip, w + nw); + } + itnull = 0; + if (t == NULL) { + itnull = 1; + nthread = 1; +#ifdef USE_FFT2D_THREADS + nthread = FFT2D_MAX_THREADS; +#endif /* USE_FFT2D_THREADS */ + nt = 8 * nthread * n1; + if (n2 == 4 * nthread) { + nt >>= 1; + } else if (n2 < 4 * nthread) { + nt >>= 2; + } + t = (double *) malloc(sizeof(double) * nt); + fft2d_alloc_error_check(t); + } +#ifdef USE_FFT2D_THREADS + if ((double) n1 * n2 >= (double) FFT2D_THREADS_BEGIN_N) { + if (isgn < 0) { + rdft2d_sub(n1, n2, isgn, a); + cdft2d_subth(n1, n2, isgn, a, t, ip, w); + } + xdft2d0_subth(n1, n2, 1, isgn, a, ip, w); + if (isgn >= 0) { + cdft2d_subth(n1, n2, isgn, a, t, ip, w); + rdft2d_sub(n1, n2, isgn, a); + } + } else +#endif /* USE_FFT2D_THREADS */ + { + if (isgn < 0) { + rdft2d_sub(n1, n2, isgn, a); + cdft2d_sub(n1, n2, isgn, a, t, ip, w); + } + for (i = 0; i < n1; i++) { + rdft(n2, isgn, a[i], ip, w); + } + if (isgn >= 0) { + cdft2d_sub(n1, n2, isgn, a, t, ip, w); + rdft2d_sub(n1, n2, isgn, a); + } + } + if (itnull != 0) { + free(t); + } +} + + +void rdft2dsort(int n1, int n2, int isgn, double **a) +{ + int n1h, i; + double x, y; + + n1h = n1 >> 1; + if (isgn < 0) { + for (i = n1h + 1; i < n1; i++) { + a[i][0] = a[i][n2 + 1]; + a[i][1] = a[i][n2]; + } + a[0][1] = a[0][n2]; + a[n1h][1] = a[n1h][n2]; + } else { + for (i = n1h + 1; i < n1; i++) { + y = a[i][0]; + x = a[i][1]; + a[i][n2] = x; + a[i][n2 + 1] = y; + a[n1 - i][n2] = x; + a[n1 - i][n2 + 1] = -y; + a[i][0] = a[n1 - i][0]; + a[i][1] = -a[n1 - i][1]; + } + a[0][n2] = a[0][1]; + a[0][n2 + 1] = 0; + a[0][1] = 0; + a[n1h][n2] = a[n1h][1]; + a[n1h][n2 + 1] = 0; + a[n1h][1] = 0; + } +} + + +void ddct2d(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void ddct(int n, int isgn, double *a, int *ip, double *w); + void ddxt2d_sub(int n1, int n2, int ics, int isgn, double **a, + double *t, int *ip, double *w); +#ifdef USE_FFT2D_THREADS + void ddxt2d0_subth(int n1, int n2, int ics, int isgn, double **a, + int *ip, double *w); + void ddxt2d_subth(int n1, int n2, int ics, int isgn, double **a, + double *t, int *ip, double *w); +#endif /* USE_FFT2D_THREADS */ + int n, nw, nc, itnull, nthread, nt, i; + + n = n1; + if (n < n2) { + n = n2; + } + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > nc) { + nc = n; + makect(nc, ip, w + nw); + } + itnull = 0; + if (t == NULL) { + itnull = 1; + nthread = 1; +#ifdef USE_FFT2D_THREADS + nthread = FFT2D_MAX_THREADS; +#endif /* USE_FFT2D_THREADS */ + nt = 4 * nthread * n1; + if (n2 == 2 * nthread) { + nt >>= 1; + } else if (n2 < 2 * nthread) { + nt >>= 2; + } + t = (double *) malloc(sizeof(double) * nt); + fft2d_alloc_error_check(t); + } +#ifdef USE_FFT2D_THREADS + if ((double) n1 * n2 >= (double) FFT2D_THREADS_BEGIN_N) { + ddxt2d0_subth(n1, n2, 0, isgn, a, ip, w); + ddxt2d_subth(n1, n2, 0, isgn, a, t, ip, w); + } else +#endif /* USE_FFT2D_THREADS */ + { + for (i = 0; i < n1; i++) { + ddct(n2, isgn, a[i], ip, w); + } + ddxt2d_sub(n1, n2, 0, isgn, a, t, ip, w); + } + if (itnull != 0) { + free(t); + } +} + + +void ddst2d(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w) +{ + void makewt(int nw, int *ip, double *w); + void makect(int nc, int *ip, double *c); + void ddst(int n, int isgn, double *a, int *ip, double *w); + void ddxt2d_sub(int n1, int n2, int ics, int isgn, double **a, + double *t, int *ip, double *w); +#ifdef USE_FFT2D_THREADS + void ddxt2d0_subth(int n1, int n2, int ics, int isgn, double **a, + int *ip, double *w); + void ddxt2d_subth(int n1, int n2, int ics, int isgn, double **a, + double *t, int *ip, double *w); +#endif /* USE_FFT2D_THREADS */ + int n, nw, nc, itnull, nthread, nt, i; + + n = n1; + if (n < n2) { + n = n2; + } + nw = ip[0]; + if (n > (nw << 2)) { + nw = n >> 2; + makewt(nw, ip, w); + } + nc = ip[1]; + if (n > nc) { + nc = n; + makect(nc, ip, w + nw); + } + itnull = 0; + if (t == NULL) { + itnull = 1; + nthread = 1; +#ifdef USE_FFT2D_THREADS + nthread = FFT2D_MAX_THREADS; +#endif /* USE_FFT2D_THREADS */ + nt = 4 * nthread * n1; + if (n2 == 2 * nthread) { + nt >>= 1; + } else if (n2 < 2 * nthread) { + nt >>= 2; + } + t = (double *) malloc(sizeof(double) * nt); + fft2d_alloc_error_check(t); + } +#ifdef USE_FFT2D_THREADS + if ((double) n1 * n2 >= (double) FFT2D_THREADS_BEGIN_N) { + ddxt2d0_subth(n1, n2, 1, isgn, a, ip, w); + ddxt2d_subth(n1, n2, 1, isgn, a, t, ip, w); + } else +#endif /* USE_FFT2D_THREADS */ + { + for (i = 0; i < n1; i++) { + ddst(n2, isgn, a[i], ip, w); + } + ddxt2d_sub(n1, n2, 1, isgn, a, t, ip, w); + } + if (itnull != 0) { + free(t); + } +} + + +/* -------- child routines -------- */ + + +void cdft2d_sub(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w) +{ + void cdft(int n, int isgn, double *a, int *ip, double *w); + int i, j; + + if (n2 > 4) { + for (j = 0; j < n2; j += 8) { + for (i = 0; i < n1; i++) { + t[2 * i] = a[i][j]; + t[2 * i + 1] = a[i][j + 1]; + t[2 * n1 + 2 * i] = a[i][j + 2]; + t[2 * n1 + 2 * i + 1] = a[i][j + 3]; + t[4 * n1 + 2 * i] = a[i][j + 4]; + t[4 * n1 + 2 * i + 1] = a[i][j + 5]; + t[6 * n1 + 2 * i] = a[i][j + 6]; + t[6 * n1 + 2 * i + 1] = a[i][j + 7]; + } + cdft(2 * n1, isgn, t, ip, w); + cdft(2 * n1, isgn, &t[2 * n1], ip, w); + cdft(2 * n1, isgn, &t[4 * n1], ip, w); + cdft(2 * n1, isgn, &t[6 * n1], ip, w); + for (i = 0; i < n1; i++) { + a[i][j] = t[2 * i]; + a[i][j + 1] = t[2 * i + 1]; + a[i][j + 2] = t[2 * n1 + 2 * i]; + a[i][j + 3] = t[2 * n1 + 2 * i + 1]; + a[i][j + 4] = t[4 * n1 + 2 * i]; + a[i][j + 5] = t[4 * n1 + 2 * i + 1]; + a[i][j + 6] = t[6 * n1 + 2 * i]; + a[i][j + 7] = t[6 * n1 + 2 * i + 1]; + } + } + } else if (n2 == 4) { + for (i = 0; i < n1; i++) { + t[2 * i] = a[i][0]; + t[2 * i + 1] = a[i][1]; + t[2 * n1 + 2 * i] = a[i][2]; + t[2 * n1 + 2 * i + 1] = a[i][3]; + } + cdft(2 * n1, isgn, t, ip, w); + cdft(2 * n1, isgn, &t[2 * n1], ip, w); + for (i = 0; i < n1; i++) { + a[i][0] = t[2 * i]; + a[i][1] = t[2 * i + 1]; + a[i][2] = t[2 * n1 + 2 * i]; + a[i][3] = t[2 * n1 + 2 * i + 1]; + } + } else if (n2 == 2) { + for (i = 0; i < n1; i++) { + t[2 * i] = a[i][0]; + t[2 * i + 1] = a[i][1]; + } + cdft(2 * n1, isgn, t, ip, w); + for (i = 0; i < n1; i++) { + a[i][0] = t[2 * i]; + a[i][1] = t[2 * i + 1]; + } + } +} + + +void rdft2d_sub(int n1, int n2, int isgn, double **a) +{ + int n1h, i, j; + double xi; + + n1h = n1 >> 1; + if (isgn < 0) { + for (i = 1; i < n1h; i++) { + j = n1 - i; + xi = a[i][0] - a[j][0]; + a[i][0] += a[j][0]; + a[j][0] = xi; + xi = a[j][1] - a[i][1]; + a[i][1] += a[j][1]; + a[j][1] = xi; + } + } else { + for (i = 1; i < n1h; i++) { + j = n1 - i; + a[j][0] = 0.5 * (a[i][0] - a[j][0]); + a[i][0] -= a[j][0]; + a[j][1] = 0.5 * (a[i][1] + a[j][1]); + a[i][1] -= a[j][1]; + } + } +} + + +void ddxt2d_sub(int n1, int n2, int ics, int isgn, double **a, + double *t, int *ip, double *w) +{ + void ddct(int n, int isgn, double *a, int *ip, double *w); + void ddst(int n, int isgn, double *a, int *ip, double *w); + int i, j; + + if (n2 > 2) { + for (j = 0; j < n2; j += 4) { + for (i = 0; i < n1; i++) { + t[i] = a[i][j]; + t[n1 + i] = a[i][j + 1]; + t[2 * n1 + i] = a[i][j + 2]; + t[3 * n1 + i] = a[i][j + 3]; + } + if (ics == 0) { + ddct(n1, isgn, t, ip, w); + ddct(n1, isgn, &t[n1], ip, w); + ddct(n1, isgn, &t[2 * n1], ip, w); + ddct(n1, isgn, &t[3 * n1], ip, w); + } else { + ddst(n1, isgn, t, ip, w); + ddst(n1, isgn, &t[n1], ip, w); + ddst(n1, isgn, &t[2 * n1], ip, w); + ddst(n1, isgn, &t[3 * n1], ip, w); + } + for (i = 0; i < n1; i++) { + a[i][j] = t[i]; + a[i][j + 1] = t[n1 + i]; + a[i][j + 2] = t[2 * n1 + i]; + a[i][j + 3] = t[3 * n1 + i]; + } + } + } else if (n2 == 2) { + for (i = 0; i < n1; i++) { + t[i] = a[i][0]; + t[n1 + i] = a[i][1]; + } + if (ics == 0) { + ddct(n1, isgn, t, ip, w); + ddct(n1, isgn, &t[n1], ip, w); + } else { + ddst(n1, isgn, t, ip, w); + ddst(n1, isgn, &t[n1], ip, w); + } + for (i = 0; i < n1; i++) { + a[i][0] = t[i]; + a[i][1] = t[n1 + i]; + } + } +} + + +#ifdef USE_FFT2D_THREADS +struct fft2d_arg_st { + int nthread; + int n0; + int n1; + int n2; + int ic; + int isgn; + double **a; + double *t; + int *ip; + double *w; +}; +typedef struct fft2d_arg_st fft2d_arg_t; + + +void xdft2d0_subth(int n1, int n2, int icr, int isgn, double **a, + int *ip, double *w) +{ + void *xdft2d0_th(void *p); + fft2d_thread_t th[FFT2D_MAX_THREADS]; + fft2d_arg_t ag[FFT2D_MAX_THREADS]; + int nthread, i; + + nthread = FFT2D_MAX_THREADS; + if (nthread > n1) { + nthread = n1; + } + for (i = 0; i < nthread; i++) { + ag[i].nthread = nthread; + ag[i].n0 = i; + ag[i].n1 = n1; + ag[i].n2 = n2; + ag[i].ic = icr; + ag[i].isgn = isgn; + ag[i].a = a; + ag[i].ip = ip; + ag[i].w = w; + fft2d_thread_create(&th[i], xdft2d0_th, &ag[i]); + } + for (i = 0; i < nthread; i++) { + fft2d_thread_wait(th[i]); + } +} + + +void cdft2d_subth(int n1, int n2, int isgn, double **a, double *t, + int *ip, double *w) +{ + void *cdft2d_th(void *p); + fft2d_thread_t th[FFT2D_MAX_THREADS]; + fft2d_arg_t ag[FFT2D_MAX_THREADS]; + int nthread, nt, i; + + nthread = FFT2D_MAX_THREADS; + nt = 8 * n1; + if (n2 == 4 * FFT2D_MAX_THREADS) { + nt >>= 1; + } else if (n2 < 4 * FFT2D_MAX_THREADS) { + nthread = n2 >> 1; + nt >>= 2; + } + for (i = 0; i < nthread; i++) { + ag[i].nthread = nthread; + ag[i].n0 = i; + ag[i].n1 = n1; + ag[i].n2 = n2; + ag[i].isgn = isgn; + ag[i].a = a; + ag[i].t = &t[nt * i]; + ag[i].ip = ip; + ag[i].w = w; + fft2d_thread_create(&th[i], cdft2d_th, &ag[i]); + } + for (i = 0; i < nthread; i++) { + fft2d_thread_wait(th[i]); + } +} + + +void ddxt2d0_subth(int n1, int n2, int ics, int isgn, double **a, + int *ip, double *w) +{ + void *ddxt2d0_th(void *p); + fft2d_thread_t th[FFT2D_MAX_THREADS]; + fft2d_arg_t ag[FFT2D_MAX_THREADS]; + int nthread, i; + + nthread = FFT2D_MAX_THREADS; + if (nthread > n1) { + nthread = n1; + } + for (i = 0; i < nthread; i++) { + ag[i].nthread = nthread; + ag[i].n0 = i; + ag[i].n1 = n1; + ag[i].n2 = n2; + ag[i].ic = ics; + ag[i].isgn = isgn; + ag[i].a = a; + ag[i].ip = ip; + ag[i].w = w; + fft2d_thread_create(&th[i], ddxt2d0_th, &ag[i]); + } + for (i = 0; i < nthread; i++) { + fft2d_thread_wait(th[i]); + } +} + + +void ddxt2d_subth(int n1, int n2, int ics, int isgn, double **a, + double *t, int *ip, double *w) +{ + void *ddxt2d_th(void *p); + fft2d_thread_t th[FFT2D_MAX_THREADS]; + fft2d_arg_t ag[FFT2D_MAX_THREADS]; + int nthread, nt, i; + + nthread = FFT2D_MAX_THREADS; + nt = 4 * n1; + if (n2 == 2 * FFT2D_MAX_THREADS) { + nt >>= 1; + } else if (n2 < 2 * FFT2D_MAX_THREADS) { + nthread = n2; + nt >>= 2; + } + for (i = 0; i < nthread; i++) { + ag[i].nthread = nthread; + ag[i].n0 = i; + ag[i].n1 = n1; + ag[i].n2 = n2; + ag[i].ic = ics; + ag[i].isgn = isgn; + ag[i].a = a; + ag[i].t = &t[nt * i]; + ag[i].ip = ip; + ag[i].w = w; + fft2d_thread_create(&th[i], ddxt2d_th, &ag[i]); + } + for (i = 0; i < nthread; i++) { + fft2d_thread_wait(th[i]); + } +} + + +void *xdft2d0_th(void *p) +{ + void cdft(int n, int isgn, double *a, int *ip, double *w); + void rdft(int n, int isgn, double *a, int *ip, double *w); + int nthread, n0, n1, n2, icr, isgn, *ip, i; + double **a, *w; + + nthread = ((fft2d_arg_t *) p)->nthread; + n0 = ((fft2d_arg_t *) p)->n0; + n1 = ((fft2d_arg_t *) p)->n1; + n2 = ((fft2d_arg_t *) p)->n2; + icr = ((fft2d_arg_t *) p)->ic; + isgn = ((fft2d_arg_t *) p)->isgn; + a = ((fft2d_arg_t *) p)->a; + ip = ((fft2d_arg_t *) p)->ip; + w = ((fft2d_arg_t *) p)->w; + if (icr == 0) { + for (i = n0; i < n1; i += nthread) { + cdft(n2, isgn, a[i], ip, w); + } + } else { + for (i = n0; i < n1; i += nthread) { + rdft(n2, isgn, a[i], ip, w); + } + } + return (void *) 0; +} + + +void *cdft2d_th(void *p) +{ + void cdft(int n, int isgn, double *a, int *ip, double *w); + int nthread, n0, n1, n2, isgn, *ip, i, j; + double **a, *t, *w; + + nthread = ((fft2d_arg_t *) p)->nthread; + n0 = ((fft2d_arg_t *) p)->n0; + n1 = ((fft2d_arg_t *) p)->n1; + n2 = ((fft2d_arg_t *) p)->n2; + isgn = ((fft2d_arg_t *) p)->isgn; + a = ((fft2d_arg_t *) p)->a; + t = ((fft2d_arg_t *) p)->t; + ip = ((fft2d_arg_t *) p)->ip; + w = ((fft2d_arg_t *) p)->w; + if (n2 > 4 * nthread) { + for (j = 8 * n0; j < n2; j += 8 * nthread) { + for (i = 0; i < n1; i++) { + t[2 * i] = a[i][j]; + t[2 * i + 1] = a[i][j + 1]; + t[2 * n1 + 2 * i] = a[i][j + 2]; + t[2 * n1 + 2 * i + 1] = a[i][j + 3]; + t[4 * n1 + 2 * i] = a[i][j + 4]; + t[4 * n1 + 2 * i + 1] = a[i][j + 5]; + t[6 * n1 + 2 * i] = a[i][j + 6]; + t[6 * n1 + 2 * i + 1] = a[i][j + 7]; + } + cdft(2 * n1, isgn, t, ip, w); + cdft(2 * n1, isgn, &t[2 * n1], ip, w); + cdft(2 * n1, isgn, &t[4 * n1], ip, w); + cdft(2 * n1, isgn, &t[6 * n1], ip, w); + for (i = 0; i < n1; i++) { + a[i][j] = t[2 * i]; + a[i][j + 1] = t[2 * i + 1]; + a[i][j + 2] = t[2 * n1 + 2 * i]; + a[i][j + 3] = t[2 * n1 + 2 * i + 1]; + a[i][j + 4] = t[4 * n1 + 2 * i]; + a[i][j + 5] = t[4 * n1 + 2 * i + 1]; + a[i][j + 6] = t[6 * n1 + 2 * i]; + a[i][j + 7] = t[6 * n1 + 2 * i + 1]; + } + } + } else if (n2 == 4 * nthread) { + for (i = 0; i < n1; i++) { + t[2 * i] = a[i][4 * n0]; + t[2 * i + 1] = a[i][4 * n0 + 1]; + t[2 * n1 + 2 * i] = a[i][4 * n0 + 2]; + t[2 * n1 + 2 * i + 1] = a[i][4 * n0 + 3]; + } + cdft(2 * n1, isgn, t, ip, w); + cdft(2 * n1, isgn, &t[2 * n1], ip, w); + for (i = 0; i < n1; i++) { + a[i][4 * n0] = t[2 * i]; + a[i][4 * n0 + 1] = t[2 * i + 1]; + a[i][4 * n0 + 2] = t[2 * n1 + 2 * i]; + a[i][4 * n0 + 3] = t[2 * n1 + 2 * i + 1]; + } + } else if (n2 == 2 * nthread) { + for (i = 0; i < n1; i++) { + t[2 * i] = a[i][2 * n0]; + t[2 * i + 1] = a[i][2 * n0 + 1]; + } + cdft(2 * n1, isgn, t, ip, w); + for (i = 0; i < n1; i++) { + a[i][2 * n0] = t[2 * i]; + a[i][2 * n0 + 1] = t[2 * i + 1]; + } + } + return (void *) 0; +} + + +void *ddxt2d0_th(void *p) +{ + void ddct(int n, int isgn, double *a, int *ip, double *w); + void ddst(int n, int isgn, double *a, int *ip, double *w); + int nthread, n0, n1, n2, ics, isgn, *ip, i; + double **a, *w; + + nthread = ((fft2d_arg_t *) p)->nthread; + n0 = ((fft2d_arg_t *) p)->n0; + n1 = ((fft2d_arg_t *) p)->n1; + n2 = ((fft2d_arg_t *) p)->n2; + ics = ((fft2d_arg_t *) p)->ic; + isgn = ((fft2d_arg_t *) p)->isgn; + a = ((fft2d_arg_t *) p)->a; + ip = ((fft2d_arg_t *) p)->ip; + w = ((fft2d_arg_t *) p)->w; + if (ics == 0) { + for (i = n0; i < n1; i += nthread) { + ddct(n2, isgn, a[i], ip, w); + } + } else { + for (i = n0; i < n1; i += nthread) { + ddst(n2, isgn, a[i], ip, w); + } + } + return (void *) 0; +} + + +void *ddxt2d_th(void *p) +{ + void ddct(int n, int isgn, double *a, int *ip, double *w); + void ddst(int n, int isgn, double *a, int *ip, double *w); + int nthread, n0, n1, n2, ics, isgn, *ip, i, j; + double **a, *t, *w; + + nthread = ((fft2d_arg_t *) p)->nthread; + n0 = ((fft2d_arg_t *) p)->n0; + n1 = ((fft2d_arg_t *) p)->n1; + n2 = ((fft2d_arg_t *) p)->n2; + ics = ((fft2d_arg_t *) p)->ic; + isgn = ((fft2d_arg_t *) p)->isgn; + a = ((fft2d_arg_t *) p)->a; + t = ((fft2d_arg_t *) p)->t; + ip = ((fft2d_arg_t *) p)->ip; + w = ((fft2d_arg_t *) p)->w; + if (n2 > 2 * nthread) { + for (j = 4 * n0; j < n2; j += 4 * nthread) { + for (i = 0; i < n1; i++) { + t[i] = a[i][j]; + t[n1 + i] = a[i][j + 1]; + t[2 * n1 + i] = a[i][j + 2]; + t[3 * n1 + i] = a[i][j + 3]; + } + if (ics == 0) { + ddct(n1, isgn, t, ip, w); + ddct(n1, isgn, &t[n1], ip, w); + ddct(n1, isgn, &t[2 * n1], ip, w); + ddct(n1, isgn, &t[3 * n1], ip, w); + } else { + ddst(n1, isgn, t, ip, w); + ddst(n1, isgn, &t[n1], ip, w); + ddst(n1, isgn, &t[2 * n1], ip, w); + ddst(n1, isgn, &t[3 * n1], ip, w); + } + for (i = 0; i < n1; i++) { + a[i][j] = t[i]; + a[i][j + 1] = t[n1 + i]; + a[i][j + 2] = t[2 * n1 + i]; + a[i][j + 3] = t[3 * n1 + i]; + } + } + } else if (n2 == 2 * nthread) { + for (i = 0; i < n1; i++) { + t[i] = a[i][2 * n0]; + t[n1 + i] = a[i][2 * n0 + 1]; + } + if (ics == 0) { + ddct(n1, isgn, t, ip, w); + ddct(n1, isgn, &t[n1], ip, w); + } else { + ddst(n1, isgn, t, ip, w); + ddst(n1, isgn, &t[n1], ip, w); + } + for (i = 0; i < n1; i++) { + a[i][2 * n0] = t[i]; + a[i][2 * n0 + 1] = t[n1 + i]; + } + } else if (n2 == nthread) { + for (i = 0; i < n1; i++) { + t[i] = a[i][n0]; + } + if (ics == 0) { + ddct(n1, isgn, t, ip, w); + } else { + ddst(n1, isgn, t, ip, w); + } + for (i = 0; i < n1; i++) { + a[i][n0] = t[i]; + } + } + return (void *) 0; +} +#endif /* USE_FFT2D_THREADS */ +
diff --git a/third_party/flatbuffers/BUILD.gn b/third_party/flatbuffers/BUILD.gn index fcd6abf..488fa72 100644 --- a/third_party/flatbuffers/BUILD.gn +++ b/third_party/flatbuffers/BUILD.gn
@@ -31,6 +31,21 @@ public_configs = [ ":flatbuffers_config" ] } +# Needed for TFLite support. +source_set("tflite_deps") { + public = [ + "src/include/flatbuffers/flexbuffers.h", + "src/include/flatbuffers/util.h", + ] + + sources = [ "src/src/util.cpp" ] + + public_deps = [ ":flatbuffers" ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] +} + # The complete FlatBuffers library, as required to build the flatc compiler and # some of the tests. source_set("compiler_files") {
diff --git a/third_party/fp16/BUILD.gn b/third_party/fp16/BUILD.gn new file mode 100644 index 0000000..fb0d9c7 --- /dev/null +++ b/third_party/fp16/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("fp16_config") { + include_dirs = [ "src/include" ] +} + +source_set("fp16") { + public = [ "src/include/fp16.h" ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + + public_configs = [ ":fp16_config" ] +}
diff --git a/third_party/fp16/LICENSE b/third_party/fp16/LICENSE new file mode 100644 index 0000000..9a13c79 --- /dev/null +++ b/third_party/fp16/LICENSE
@@ -0,0 +1,12 @@ +The MIT License (MIT) + +Copyright (c) 2017 Facebook Inc. +Copyright (c) 2017 Georgia Institute of Technology +Copyright 2019 Google LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +
diff --git a/third_party/fp16/OWNERS b/third_party/fp16/OWNERS new file mode 100644 index 0000000..f14a8b97 --- /dev/null +++ b/third_party/fp16/OWNERS
@@ -0,0 +1,4 @@ +mcrouse@chromium.org +sophiechang@chromium.org +tbansal@chromium.org +# COMPONENT: Internals>OptimizationGuide
diff --git a/third_party/fp16/README.chromium b/third_party/fp16/README.chromium new file mode 100644 index 0000000..065e16e7 --- /dev/null +++ b/third_party/fp16/README.chromium
@@ -0,0 +1,15 @@ +Name: FP16 +Short Name: fp16 +URL: https://github.com/Maratyszcza/FP16 +Version: febbb1c163726b5db24bed55cc9dc42529068997 +Date: 2018/11/28 +License: MIT +License File: LICENSE +Security Critical: Yes + +Description: +Header-only library for conversion to/from half-precision floating point formats + +Local Modifications: +- Included only the header files in the `include` directory in `src/`. +- Extracted LICENSE file separately.
diff --git a/third_party/gemmlowp/BUILD.gn b/third_party/gemmlowp/BUILD.gn new file mode 100644 index 0000000..e4b9e474 --- /dev/null +++ b/third_party/gemmlowp/BUILD.gn
@@ -0,0 +1,17 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("gemmlowp_include") { + include_dirs = [ "src" ] +} +source_set("gemmlowp") { + public = [ + "src/fixedpoint/fixedpoint.h", + "src/public/bit_depth.h", + "src/public/gemmlowp.h", + "src/public/map.h", + "src/public/output_stages.h", + ] + public_configs = [ ":gemmlowp_include" ] +}
diff --git a/third_party/gemmlowp/LICENSE b/third_party/gemmlowp/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/third_party/gemmlowp/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/third_party/gemmlowp/OWNERS b/third_party/gemmlowp/OWNERS new file mode 100644 index 0000000..f14a8b97 --- /dev/null +++ b/third_party/gemmlowp/OWNERS
@@ -0,0 +1,4 @@ +mcrouse@chromium.org +sophiechang@chromium.org +tbansal@chromium.org +# COMPONENT: Internals>OptimizationGuide
diff --git a/third_party/gemmlowp/README.chromium b/third_party/gemmlowp/README.chromium new file mode 100644 index 0000000..34f8ab5 --- /dev/null +++ b/third_party/gemmlowp/README.chromium
@@ -0,0 +1,11 @@ +Name: gemmlowp +Short Name: gemmlowp +URL: https://github.com/google/gemmlowp +Version: fda83bdc38b118cc6b56753bd540caa49e570745 +Date: 2020/05/06 +License: Apache 2 +License File: LICENSE +Security Critical: Yes + +Description: +gemmlowp: a small self-contained low-precision GEMM library.
diff --git a/third_party/grpc/BUILD.gn b/third_party/grpc/BUILD.gn index 1358ba54..86cc1b7e 100644 --- a/third_party/grpc/BUILD.gn +++ b/third_party/grpc/BUILD.gn
@@ -1,168 +1,897 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# GRPC Chromium GN build file -import("//testing/libfuzzer/fuzzer_test.gni") +# This file has been automatically generated from a template file. +# Please look at the templates directory instead. +# See //third_party/grpc/README.chromium for more information. + +declare_args() { + # Compiles with ares. + enable_grpc_ares = false +} + +if (is_android) { + import("//build/config/android/config.gni") +} config("grpc_config") { - include_dirs = [ "src/include" ] - defines = [ - "GRPC_ALLOW_EXCEPTIONS=0", - "GRPC_USE_PROTO_LITE", + include_dirs = [ + "src/include", + "src", + "src/src/core/ext/upb-generated", + "src/src/core/ext/upbdefs-generated", + "src/third_party/cares", + "//third_party/cares", + "src/third_party/upb", + "//third_party/abseil-cpp", ] -} -config("grpc_internal_config") { - visibility = [ ":*" ] - include_dirs = [ "src" ] + defines = [ + "GRPC_USE_PROTO_LITE", + "HAVE_CONFIG_H", + "PB_FIELD_16BIT", + "GRPC_NO_XDS", + ] + cflags = [ "-Wno-implicit-fallthrough", - "-Wno-constant-conversion", ] - defines = [ "GRPC_ARES=0" ] -} -config("nanopb_config") { - include_dirs = [ "src/third_party/nanopb" ] - defines = [ "PB_FIELD_32BIT=1" ] - if (is_apple) { - defines += [ "PB_NO_PACKED_STRUCTS=1" ] + if (is_android) { + libs = [ "log" ] # For __android_log_write + } + + if (is_android) { + include_dirs += [ "src/third_party/cares/config_android" ] + } else if (is_fuchsia) { + include_dirs += [ "third_party/cares/config_fuchsia" ] + } else { + include_dirs += [ "src/third_party/cares/config_linux" ] + } + + if (is_fuchsia) { + defines += [ + # Allows zircon sockets to use file descriptors with gRPC. + "GPR_SUPPORT_CHANNELS_FROM_FD", + ] + } + + if (!enable_grpc_ares) { + defines += [ + # Disable c-ares since it doesn't currently support Fuchsia + "GRPC_ARES=0", + ] } } -# The gRPC library. Note that server side code will not be built. You probably -# want to use cc_grpc_library() from grpc_library.gni directly. -static_library("grpcpp") { - # This is currently only used by chromecast and libassistant. - # NOTE: Using gRPC in Chrome may have security concerns and other - # complications when building the binary. Please contact - # chrome-security-reviews@ first before you decide to use gRPC. - visibility = [ - "//chromecast/*", - "//chromeos/assistant/internal/*", - "//chromeos/services/assistant/*", +config("grpc_config_private") { + cflags = [ + "-Wno-implicit-fallthrough", + "-std=c99", + "-Wno-sign-compare", + "-Wno-unreachable-code", + "-Wno-extra-semi", + "-Wno-macro-redefined", + "-Wno-ignored-qualifiers", + "-Wno-string-concatenation", ] - sources = [ - "src/src/cpp/client/channel_cc.cc", - "src/src/cpp/client/client_context.cc", - "src/src/cpp/client/client_interceptor.cc", - "src/src/cpp/client/create_channel.cc", - "src/src/cpp/client/create_channel_internal.cc", - "src/src/cpp/client/create_channel_posix.cc", - "src/src/cpp/client/credentials_cc.cc", - "src/src/cpp/client/generic_stub.cc", - "src/src/cpp/client/insecure_credentials.cc", - "src/src/cpp/client/secure_credentials.cc", - "src/src/cpp/codegen/codegen_init.cc", - "src/src/cpp/common/alarm.cc", - "src/src/cpp/common/auth_property_iterator.cc", - "src/src/cpp/common/channel_arguments.cc", - "src/src/cpp/common/channel_filter.cc", - "src/src/cpp/common/completion_queue_cc.cc", - "src/src/cpp/common/core_codegen.cc", - "src/src/cpp/common/resource_quota_cc.cc", - "src/src/cpp/common/rpc_method.cc", - "src/src/cpp/common/secure_auth_context.cc", - "src/src/cpp/common/secure_channel_arguments.cc", - "src/src/cpp/common/secure_create_auth_context.cc", - "src/src/cpp/common/version_cc.cc", - "src/src/cpp/server/async_generic_service.cc", - "src/src/cpp/server/channel_argument_option.cc", - "src/src/cpp/server/create_default_thread_pool.cc", - "src/src/cpp/server/dynamic_thread_pool.cc", - "src/src/cpp/server/external_connection_acceptor_impl.cc", - "src/src/cpp/server/health/default_health_check_service.cc", - "src/src/cpp/server/health/health_check_service.cc", - "src/src/cpp/server/health/health_check_service_server_builder_option.cc", - "src/src/cpp/server/insecure_server_credentials.cc", - "src/src/cpp/server/secure_server_credentials.cc", - "src/src/cpp/server/server_builder.cc", - "src/src/cpp/server/server_cc.cc", - "src/src/cpp/server/server_context.cc", - "src/src/cpp/server/server_credentials.cc", - "src/src/cpp/server/server_posix.cc", - "src/src/cpp/thread_manager/thread_manager.cc", - "src/src/cpp/util/byte_buffer_cc.cc", - "src/src/cpp/util/status.cc", - "src/src/cpp/util/string_ref.cc", - "src/src/cpp/util/time_cc.cc", - ] - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - public_configs = [ ":grpc_config" ] +} + +template("grpc_so") { + # TODO(169395837): Somehow gRPC symbols cannot be found on Android. + # Keep using static linking for now. + if (is_android) { + source_set(target_name) { + forward_variables_from(invoker, "*") + } + } else { + shared_library(target_name) { + forward_variables_from(invoker, "*") + inputs = [ "./grpc_shared_lib.map" ] + ldflags = [ "-Wl,--version-script=" + rebase_path("./grpc_shared_lib.map", root_build_dir) ] + } + } +} + +grpc_so("grpc++") { deps = [ - ":grpc_core", - ":nanopb", - "//third_party/protobuf:protobuf_lite", + ":grpc++_cc", + ":grpc++_repeated", + ] + public_deps = [ + ":grpc++_h", ] } +# There are some .cc files that are in multiple places. GN doesn't like +# that. Moving them to another target. +source_set("grpc++_h") { + sources = [ + "src/include/grpc++/alarm.h", + "src/include/grpc++/channel.h", + "src/include/grpc++/client_context.h", + "src/include/grpc++/completion_queue.h", + "src/include/grpc++/create_channel.h", + "src/include/grpc++/create_channel_posix.h", + "src/include/grpc++/ext/health_check_service_server_builder_option.h", + "src/include/grpc++/generic/async_generic_service.h", + "src/include/grpc++/generic/generic_stub.h", + "src/include/grpc++/grpc++.h", + "src/include/grpc++/health_check_service_interface.h", + "src/include/grpc++/impl/call.h", + "src/include/grpc++/impl/channel_argument_option.h", + "src/include/grpc++/impl/client_unary_call.h", + "src/include/grpc++/impl/codegen/async_stream.h", + "src/include/grpc++/impl/codegen/async_unary_call.h", + "src/include/grpc++/impl/codegen/byte_buffer.h", + "src/include/grpc++/impl/codegen/call.h", + "src/include/grpc++/impl/codegen/call_hook.h", + "src/include/grpc++/impl/codegen/channel_interface.h", + "src/include/grpc++/impl/codegen/client_context.h", + "src/include/grpc++/impl/codegen/client_unary_call.h", + "src/include/grpc++/impl/codegen/completion_queue.h", + "src/include/grpc++/impl/codegen/completion_queue_tag.h", + "src/include/grpc++/impl/codegen/config.h", + "src/include/grpc++/impl/codegen/config_protobuf.h", + "src/include/grpc++/impl/codegen/core_codegen.h", + "src/include/grpc++/impl/codegen/core_codegen_interface.h", + "src/include/grpc++/impl/codegen/create_auth_context.h", + "src/include/grpc++/impl/codegen/grpc_library.h", + "src/include/grpc++/impl/codegen/metadata_map.h", + "src/include/grpc++/impl/codegen/method_handler_impl.h", + "src/include/grpc++/impl/codegen/proto_utils.h", + "src/include/grpc++/impl/codegen/rpc_method.h", + "src/include/grpc++/impl/codegen/rpc_service_method.h", + "src/include/grpc++/impl/codegen/security/auth_context.h", + "src/include/grpc++/impl/codegen/serialization_traits.h", + "src/include/grpc++/impl/codegen/server_context.h", + "src/include/grpc++/impl/codegen/server_interface.h", + "src/include/grpc++/impl/codegen/service_type.h", + "src/include/grpc++/impl/codegen/slice.h", + "src/include/grpc++/impl/codegen/status.h", + "src/include/grpc++/impl/codegen/status_code_enum.h", + "src/include/grpc++/impl/codegen/string_ref.h", + "src/include/grpc++/impl/codegen/stub_options.h", + "src/include/grpc++/impl/codegen/sync_stream.h", + "src/include/grpc++/impl/codegen/time.h", + "src/include/grpc++/impl/grpc_library.h", + "src/include/grpc++/impl/method_handler_impl.h", + "src/include/grpc++/impl/rpc_method.h", + "src/include/grpc++/impl/rpc_service_method.h", + "src/include/grpc++/impl/serialization_traits.h", + "src/include/grpc++/impl/server_builder_option.h", + "src/include/grpc++/impl/server_builder_plugin.h", + "src/include/grpc++/impl/server_initializer.h", + "src/include/grpc++/impl/service_type.h", + "src/include/grpc++/resource_quota.h", + "src/include/grpc++/security/auth_context.h", + "src/include/grpc++/security/auth_metadata_processor.h", + "src/include/grpc++/security/credentials.h", + "src/include/grpc++/security/server_credentials.h", + "src/include/grpc++/server.h", + "src/include/grpc++/server_builder.h", + "src/include/grpc++/server_context.h", + "src/include/grpc++/server_posix.h", + "src/include/grpc++/support/async_stream.h", + "src/include/grpc++/support/async_unary_call.h", + "src/include/grpc++/support/byte_buffer.h", + "src/include/grpc++/support/channel_arguments.h", + "src/include/grpc++/support/config.h", + "src/include/grpc++/support/slice.h", + "src/include/grpc++/support/status.h", + "src/include/grpc++/support/status_code_enum.h", + "src/include/grpc++/support/string_ref.h", + "src/include/grpc++/support/stub_options.h", + "src/include/grpc++/support/sync_stream.h", + "src/include/grpc++/support/time.h", + "src/include/grpc/byte_buffer.h", + "src/include/grpc/byte_buffer_reader.h", + "src/include/grpc/census.h", + "src/include/grpc/compression.h", + "src/include/grpc/fork.h", + "src/include/grpc/grpc.h", + "src/include/grpc/grpc_posix.h", + "src/include/grpc/grpc_security.h", + "src/include/grpc/grpc_security_constants.h", + "src/include/grpc/impl/codegen/atm.h", + "src/include/grpc/impl/codegen/atm_gcc_atomic.h", + "src/include/grpc/impl/codegen/atm_gcc_sync.h", + "src/include/grpc/impl/codegen/atm_windows.h", + "src/include/grpc/impl/codegen/byte_buffer.h", + "src/include/grpc/impl/codegen/byte_buffer_reader.h", + "src/include/grpc/impl/codegen/compression_types.h", + "src/include/grpc/impl/codegen/connectivity_state.h", + "src/include/grpc/impl/codegen/fork.h", + "src/include/grpc/impl/codegen/gpr_slice.h", + "src/include/grpc/impl/codegen/gpr_types.h", + "src/include/grpc/impl/codegen/grpc_types.h", + "src/include/grpc/impl/codegen/log.h", + "src/include/grpc/impl/codegen/port_platform.h", + "src/include/grpc/impl/codegen/propagation_bits.h", + "src/include/grpc/impl/codegen/slice.h", + "src/include/grpc/impl/codegen/status.h", + "src/include/grpc/impl/codegen/sync.h", + "src/include/grpc/impl/codegen/sync_abseil.h", + "src/include/grpc/impl/codegen/sync_custom.h", + "src/include/grpc/impl/codegen/sync_generic.h", + "src/include/grpc/impl/codegen/sync_posix.h", + "src/include/grpc/impl/codegen/sync_windows.h", + "src/include/grpc/load_reporting.h", + "src/include/grpc/slice.h", + "src/include/grpc/slice_buffer.h", + "src/include/grpc/status.h", + "src/include/grpc/support/alloc.h", + "src/include/grpc/support/atm.h", + "src/include/grpc/support/atm_gcc_atomic.h", + "src/include/grpc/support/atm_gcc_sync.h", + "src/include/grpc/support/atm_windows.h", + "src/include/grpc/support/cpu.h", + "src/include/grpc/support/log.h", + "src/include/grpc/support/log_windows.h", + "src/include/grpc/support/port_platform.h", + "src/include/grpc/support/string_util.h", + "src/include/grpc/support/sync.h", + "src/include/grpc/support/sync_abseil.h", + "src/include/grpc/support/sync_custom.h", + "src/include/grpc/support/sync_generic.h", + "src/include/grpc/support/sync_posix.h", + "src/include/grpc/support/sync_windows.h", + "src/include/grpc/support/thd_id.h", + "src/include/grpc/support/time.h", + "src/include/grpc/support/workaround_list.h", + "src/include/grpcpp/alarm.h", + "src/include/grpcpp/channel.h", + "src/include/grpcpp/client_context.h", + "src/include/grpcpp/completion_queue.h", + "src/include/grpcpp/create_channel.h", + "src/include/grpcpp/create_channel_posix.h", + "src/include/grpcpp/ext/health_check_service_server_builder_option.h", + "src/include/grpcpp/generic/async_generic_service.h", + "src/include/grpcpp/generic/generic_stub.h", + "src/include/grpcpp/grpcpp.h", + "src/include/grpcpp/health_check_service_interface.h", + "src/include/grpcpp/impl/call.h", + "src/include/grpcpp/impl/channel_argument_option.h", + "src/include/grpcpp/impl/client_unary_call.h", + "src/include/grpcpp/impl/codegen/async_generic_service.h", + "src/include/grpcpp/impl/codegen/async_stream.h", + "src/include/grpcpp/impl/codegen/async_unary_call.h", + "src/include/grpcpp/impl/codegen/byte_buffer.h", + "src/include/grpcpp/impl/codegen/call.h", + "src/include/grpcpp/impl/codegen/call_hook.h", + "src/include/grpcpp/impl/codegen/call_op_set.h", + "src/include/grpcpp/impl/codegen/call_op_set_interface.h", + "src/include/grpcpp/impl/codegen/callback_common.h", + "src/include/grpcpp/impl/codegen/channel_interface.h", + "src/include/grpcpp/impl/codegen/client_callback.h", + "src/include/grpcpp/impl/codegen/client_context.h", + "src/include/grpcpp/impl/codegen/client_interceptor.h", + "src/include/grpcpp/impl/codegen/client_unary_call.h", + "src/include/grpcpp/impl/codegen/completion_queue.h", + "src/include/grpcpp/impl/codegen/completion_queue_tag.h", + "src/include/grpcpp/impl/codegen/config.h", + "src/include/grpcpp/impl/codegen/config_protobuf.h", + "src/include/grpcpp/impl/codegen/core_codegen.h", + "src/include/grpcpp/impl/codegen/core_codegen_interface.h", + "src/include/grpcpp/impl/codegen/create_auth_context.h", + "src/include/grpcpp/impl/codegen/delegating_channel.h", + "src/include/grpcpp/impl/codegen/grpc_library.h", + "src/include/grpcpp/impl/codegen/intercepted_channel.h", + "src/include/grpcpp/impl/codegen/interceptor.h", + "src/include/grpcpp/impl/codegen/interceptor_common.h", + "src/include/grpcpp/impl/codegen/message_allocator.h", + "src/include/grpcpp/impl/codegen/metadata_map.h", + "src/include/grpcpp/impl/codegen/method_handler.h", + "src/include/grpcpp/impl/codegen/proto_buffer_reader.h", + "src/include/grpcpp/impl/codegen/proto_buffer_writer.h", + "src/include/grpcpp/impl/codegen/proto_utils.h", + "src/include/grpcpp/impl/codegen/rpc_method.h", + "src/include/grpcpp/impl/codegen/rpc_service_method.h", + "src/include/grpcpp/impl/codegen/security/auth_context.h", + "src/include/grpcpp/impl/codegen/serialization_traits.h", + "src/include/grpcpp/impl/codegen/server_callback.h", + "src/include/grpcpp/impl/codegen/server_callback_handlers.h", + "src/include/grpcpp/impl/codegen/server_context.h", + "src/include/grpcpp/impl/codegen/server_interceptor.h", + "src/include/grpcpp/impl/codegen/server_interface.h", + "src/include/grpcpp/impl/codegen/service_type.h", + "src/include/grpcpp/impl/codegen/slice.h", + "src/include/grpcpp/impl/codegen/status.h", + "src/include/grpcpp/impl/codegen/status_code_enum.h", + "src/include/grpcpp/impl/codegen/string_ref.h", + "src/include/grpcpp/impl/codegen/stub_options.h", + "src/include/grpcpp/impl/codegen/sync.h", + "src/include/grpcpp/impl/codegen/sync_stream.h", + "src/include/grpcpp/impl/codegen/time.h", + "src/include/grpcpp/impl/grpc_library.h", + "src/include/grpcpp/impl/method_handler_impl.h", + "src/include/grpcpp/impl/rpc_method.h", + "src/include/grpcpp/impl/rpc_service_method.h", + "src/include/grpcpp/impl/serialization_traits.h", + "src/include/grpcpp/impl/server_builder_option.h", + "src/include/grpcpp/impl/server_builder_plugin.h", + "src/include/grpcpp/impl/server_initializer.h", + "src/include/grpcpp/impl/service_type.h", + "src/include/grpcpp/resource_quota.h", + "src/include/grpcpp/security/auth_context.h", + "src/include/grpcpp/security/auth_metadata_processor.h", + "src/include/grpcpp/security/credentials.h", + "src/include/grpcpp/security/server_credentials.h", + "src/include/grpcpp/security/tls_certificate_provider.h", + "src/include/grpcpp/security/tls_credentials_options.h", + "src/include/grpcpp/server.h", + "src/include/grpcpp/server_builder.h", + "src/include/grpcpp/server_context.h", + "src/include/grpcpp/server_posix.h", + "src/include/grpcpp/support/async_stream.h", + "src/include/grpcpp/support/async_unary_call.h", + "src/include/grpcpp/support/byte_buffer.h", + "src/include/grpcpp/support/channel_arguments.h", + "src/include/grpcpp/support/client_callback.h", + "src/include/grpcpp/support/client_interceptor.h", + "src/include/grpcpp/support/config.h", + "src/include/grpcpp/support/interceptor.h", + "src/include/grpcpp/support/message_allocator.h", + "src/include/grpcpp/support/method_handler.h", + "src/include/grpcpp/support/proto_buffer_reader.h", + "src/include/grpcpp/support/proto_buffer_writer.h", + "src/include/grpcpp/support/server_callback.h", + "src/include/grpcpp/support/server_interceptor.h", + "src/include/grpcpp/support/slice.h", + "src/include/grpcpp/support/status.h", + "src/include/grpcpp/support/status_code_enum.h", + "src/include/grpcpp/support/string_ref.h", + "src/include/grpcpp/support/stub_options.h", + "src/include/grpcpp/support/sync_stream.h", + "src/include/grpcpp/support/time.h", + "src/include/grpcpp/support/validate_service_config.h", + "src/src/core/ext/filters/client_channel/backend_metric.h", + "src/src/core/ext/filters/client_channel/backup_poller.h", + "src/src/core/ext/filters/client_channel/client_channel.h", + "src/src/core/ext/filters/client_channel/client_channel_channelz.h", + "src/src/core/ext/filters/client_channel/client_channel_factory.h", + "src/src/core/ext/filters/client_channel/config_selector.h", + "src/src/core/ext/filters/client_channel/connector.h", + "src/src/core/ext/filters/client_channel/global_subchannel_pool.h", + "src/src/core/ext/filters/client_channel/health/health_check_client.h", + "src/src/core/ext/filters/client_channel/http_connect_handshaker.h", + "src/src/core/ext/filters/client_channel/http_proxy.h", + "src/src/core/ext/filters/client_channel/lb_policy.h", + "src/src/core/ext/filters/client_channel/lb_policy/address_filtering.h", + "src/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h", + "src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h", + "src/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h", + "src/src/core/ext/filters/client_channel/lb_policy_factory.h", + "src/src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/src/core/ext/filters/client_channel/local_subchannel_pool.h", + "src/src/core/ext/filters/client_channel/proxy_mapper.h", + "src/src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/src/core/ext/filters/client_channel/resolver.h", + "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", + "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", + "src/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", + "src/src/core/ext/filters/client_channel/resolver_factory.h", + "src/src/core/ext/filters/client_channel/resolver_registry.h", + "src/src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/src/core/ext/filters/client_channel/resolving_lb_policy.h", + "src/src/core/ext/filters/client_channel/retry_throttle.h", + "src/src/core/ext/filters/client_channel/server_address.h", + "src/src/core/ext/filters/client_channel/service_config.h", + "src/src/core/ext/filters/client_channel/service_config_call_data.h", + "src/src/core/ext/filters/client_channel/service_config_parser.h", + "src/src/core/ext/filters/client_channel/subchannel.h", + "src/src/core/ext/filters/client_channel/subchannel_interface.h", + "src/src/core/ext/filters/client_channel/subchannel_pool_interface.h", + "src/src/core/ext/filters/deadline/deadline_filter.h", + "src/src/core/ext/filters/http/client/http_client_filter.h", + "src/src/core/ext/filters/http/client_authority_filter.h", + "src/src/core/ext/filters/http/message_compress/message_compress_filter.h", + "src/src/core/ext/filters/http/message_compress/message_decompress_filter.h", + "src/src/core/ext/filters/http/server/http_server_filter.h", + "src/src/core/ext/filters/max_age/max_age_filter.h", + "src/src/core/ext/filters/message_size/message_size_filter.h", + "src/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h", + "src/src/core/ext/filters/workarounds/workaround_utils.h", + "src/src/core/ext/transport/chttp2/alpn/alpn.h", + "src/src/core/ext/transport/chttp2/client/authority.h", + "src/src/core/ext/transport/chttp2/client/chttp2_connector.h", + "src/src/core/ext/transport/chttp2/server/chttp2_server.h", + "src/src/core/ext/transport/chttp2/transport/bin_decoder.h", + "src/src/core/ext/transport/chttp2/transport/bin_encoder.h", + "src/src/core/ext/transport/chttp2/transport/chttp2_transport.h", + "src/src/core/ext/transport/chttp2/transport/context_list.h", + "src/src/core/ext/transport/chttp2/transport/flow_control.h", + "src/src/core/ext/transport/chttp2/transport/frame.h", + "src/src/core/ext/transport/chttp2/transport/frame_data.h", + "src/src/core/ext/transport/chttp2/transport/frame_goaway.h", + "src/src/core/ext/transport/chttp2/transport/frame_ping.h", + "src/src/core/ext/transport/chttp2/transport/frame_rst_stream.h", + "src/src/core/ext/transport/chttp2/transport/frame_settings.h", + "src/src/core/ext/transport/chttp2/transport/frame_window_update.h", + "src/src/core/ext/transport/chttp2/transport/hpack_encoder.h", + "src/src/core/ext/transport/chttp2/transport/hpack_parser.h", + "src/src/core/ext/transport/chttp2/transport/hpack_table.h", + "src/src/core/ext/transport/chttp2/transport/http2_settings.h", + "src/src/core/ext/transport/chttp2/transport/huffsyms.h", + "src/src/core/ext/transport/chttp2/transport/incoming_metadata.h", + "src/src/core/ext/transport/chttp2/transport/internal.h", + "src/src/core/ext/transport/chttp2/transport/stream_map.h", + "src/src/core/ext/transport/chttp2/transport/varint.h", + "src/src/core/ext/transport/inproc/inproc_transport.h", + "src/src/core/ext/upb-generated/envoy/annotations/deprecation.upb.h", + "src/src/core/ext/upb-generated/envoy/annotations/resource.upb.h", + "src/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.h", + "src/src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.h", + "src/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h", + "src/src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.h", + "src/src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.h", + "src/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.h", + "src/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.h", + "src/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.h", + "src/src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.h", + "src/src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.h", + "src/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h", + "src/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h", + "src/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.h", + "src/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h", + "src/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h", + "src/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h", + "src/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h", + "src/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h", + "src/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h", + "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h", + "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h", + "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h", + "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h", + "src/src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.h", + "src/src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.h", + "src/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h", + "src/src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.h", + "src/src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.h", + "src/src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.h", + "src/src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.h", + "src/src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.h", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.h", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.h", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.h", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.h", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.h", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.h", + "src/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.h", + "src/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.h", + "src/src/core/ext/upb-generated/envoy/type/v3/http.upb.h", + "src/src/core/ext/upb-generated/envoy/type/v3/percent.upb.h", + "src/src/core/ext/upb-generated/envoy/type/v3/range.upb.h", + "src/src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.h", + "src/src/core/ext/upb-generated/google/api/annotations.upb.h", + "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.h", + "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.h", + "src/src/core/ext/upb-generated/google/api/http.upb.h", + "src/src/core/ext/upb-generated/google/rpc/status.upb.h", + "src/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h", + "src/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h", + "src/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h", + "src/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h", + "src/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h", + "src/src/core/ext/upb-generated/udpa/annotations/migrate.upb.h", + "src/src/core/ext/upb-generated/udpa/annotations/security.upb.h", + "src/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h", + "src/src/core/ext/upb-generated/udpa/annotations/status.upb.h", + "src/src/core/ext/upb-generated/udpa/annotations/versioning.upb.h", + "src/src/core/ext/upb-generated/udpa/core/v1/authority.upb.h", + "src/src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.h", + "src/src/core/ext/upb-generated/udpa/core/v1/context_params.upb.h", + "src/src/core/ext/upb-generated/udpa/core/v1/resource.upb.h", + "src/src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.h", + "src/src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.h", + "src/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h", + "src/src/core/ext/upb-generated/validate/validate.upb.h", + "src/src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/service/cluster/v3/cds.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/service/endpoint/v3/eds.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/service/listener/v3/lds.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/service/route/v3/rds.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/service/route/v3/srds.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.h", + "src/src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/api/http.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/authority.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/collection_entry.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/context_params.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/resource.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/resource_locator.upbdefs.h", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/resource_name.upbdefs.h", + "src/src/core/ext/upbdefs-generated/validate/validate.upbdefs.h", + "src/src/core/lib/avl/avl.h", + "src/src/core/lib/backoff/backoff.h", + "src/src/core/lib/channel/channel_args.h", + "src/src/core/lib/channel/channel_stack.h", + "src/src/core/lib/channel/channel_stack_builder.h", + "src/src/core/lib/channel/channel_trace.h", + "src/src/core/lib/channel/channelz.h", + "src/src/core/lib/channel/channelz_registry.h", + "src/src/core/lib/channel/connected_channel.h", + "src/src/core/lib/channel/context.h", + "src/src/core/lib/channel/handshaker.h", + "src/src/core/lib/channel/handshaker_factory.h", + "src/src/core/lib/channel/handshaker_registry.h", + "src/src/core/lib/channel/status_util.h", + "src/src/core/lib/compression/algorithm_metadata.h", + "src/src/core/lib/compression/compression_args.h", + "src/src/core/lib/compression/compression_internal.h", + "src/src/core/lib/compression/message_compress.h", + "src/src/core/lib/compression/stream_compression.h", + "src/src/core/lib/compression/stream_compression_gzip.h", + "src/src/core/lib/compression/stream_compression_identity.h", + "src/src/core/lib/debug/stats.h", + "src/src/core/lib/debug/stats_data.h", + "src/src/core/lib/debug/trace.h", + "src/src/core/lib/gpr/alloc.h", + "src/src/core/lib/gpr/arena.h", + "src/src/core/lib/gpr/env.h", + "src/src/core/lib/gpr/murmur_hash.h", + "src/src/core/lib/gpr/spinlock.h", + "src/src/core/lib/gpr/string.h", + "src/src/core/lib/gpr/string_windows.h", + "src/src/core/lib/gpr/time_precise.h", + "src/src/core/lib/gpr/tls.h", + "src/src/core/lib/gpr/tls_gcc.h", + "src/src/core/lib/gpr/tls_msvc.h", + "src/src/core/lib/gpr/tls_pthread.h", + "src/src/core/lib/gpr/tls_stdcpp.h", + "src/src/core/lib/gpr/tmpfile.h", + "src/src/core/lib/gpr/useful.h", + "src/src/core/lib/gprpp/arena.h", + "src/src/core/lib/gprpp/atomic.h", + "src/src/core/lib/gprpp/debug_location.h", + "src/src/core/lib/gprpp/dual_ref_counted.h", + "src/src/core/lib/gprpp/examine_stack.h", + "src/src/core/lib/gprpp/fork.h", + "src/src/core/lib/gprpp/global_config.h", + "src/src/core/lib/gprpp/global_config_custom.h", + "src/src/core/lib/gprpp/global_config_env.h", + "src/src/core/lib/gprpp/global_config_generic.h", + "src/src/core/lib/gprpp/host_port.h", + "src/src/core/lib/gprpp/manual_constructor.h", + "src/src/core/lib/gprpp/map.h", + "src/src/core/lib/gprpp/memory.h", + "src/src/core/lib/gprpp/mpscq.h", + "src/src/core/lib/gprpp/orphanable.h", + "src/src/core/lib/gprpp/ref_counted.h", + "src/src/core/lib/gprpp/ref_counted_ptr.h", + "src/src/core/lib/gprpp/stat.h", + "src/src/core/lib/gprpp/sync.h", + "src/src/core/lib/gprpp/thd.h", + "src/src/core/lib/http/format_request.h", + "src/src/core/lib/http/httpcli.h", + "src/src/core/lib/http/parser.h", + "src/src/core/lib/iomgr/block_annotate.h", + "src/src/core/lib/iomgr/buffer_list.h", + "src/src/core/lib/iomgr/call_combiner.h", + "src/src/core/lib/iomgr/cfstream_handle.h", + "src/src/core/lib/iomgr/closure.h", + "src/src/core/lib/iomgr/combiner.h", + "src/src/core/lib/iomgr/dynamic_annotations.h", + "src/src/core/lib/iomgr/endpoint.h", + "src/src/core/lib/iomgr/endpoint_cfstream.h", + "src/src/core/lib/iomgr/endpoint_pair.h", + "src/src/core/lib/iomgr/error.h", + "src/src/core/lib/iomgr/error_cfstream.h", + "src/src/core/lib/iomgr/error_internal.h", + "src/src/core/lib/iomgr/ev_apple.h", + "src/src/core/lib/iomgr/ev_epoll1_linux.h", + "src/src/core/lib/iomgr/ev_epollex_linux.h", + "src/src/core/lib/iomgr/ev_poll_posix.h", + "src/src/core/lib/iomgr/ev_posix.h", + "src/src/core/lib/iomgr/exec_ctx.h", + "src/src/core/lib/iomgr/executor.h", + "src/src/core/lib/iomgr/executor/mpmcqueue.h", + "src/src/core/lib/iomgr/executor/threadpool.h", + "src/src/core/lib/iomgr/gethostname.h", + "src/src/core/lib/iomgr/grpc_if_nametoindex.h", + "src/src/core/lib/iomgr/internal_errqueue.h", + "src/src/core/lib/iomgr/iocp_windows.h", + "src/src/core/lib/iomgr/iomgr.h", + "src/src/core/lib/iomgr/iomgr_custom.h", + "src/src/core/lib/iomgr/iomgr_internal.h", + "src/src/core/lib/iomgr/iomgr_posix.h", + "src/src/core/lib/iomgr/is_epollexclusive_available.h", + "src/src/core/lib/iomgr/load_file.h", + "src/src/core/lib/iomgr/lockfree_event.h", + "src/src/core/lib/iomgr/nameser.h", + "src/src/core/lib/iomgr/parse_address.h", + "src/src/core/lib/iomgr/poller/eventmanager_libuv.h", + "src/src/core/lib/iomgr/polling_entity.h", + "src/src/core/lib/iomgr/pollset.h", + "src/src/core/lib/iomgr/pollset_custom.h", + "src/src/core/lib/iomgr/pollset_set.h", + "src/src/core/lib/iomgr/pollset_set_custom.h", + "src/src/core/lib/iomgr/pollset_set_windows.h", + "src/src/core/lib/iomgr/pollset_uv.h", + "src/src/core/lib/iomgr/pollset_windows.h", + "src/src/core/lib/iomgr/port.h", + "src/src/core/lib/iomgr/python_util.h", + "src/src/core/lib/iomgr/resolve_address.h", + "src/src/core/lib/iomgr/resolve_address_custom.h", + "src/src/core/lib/iomgr/resource_quota.h", + "src/src/core/lib/iomgr/sockaddr.h", + "src/src/core/lib/iomgr/sockaddr_custom.h", + "src/src/core/lib/iomgr/sockaddr_posix.h", + "src/src/core/lib/iomgr/sockaddr_utils.h", + "src/src/core/lib/iomgr/sockaddr_windows.h", + "src/src/core/lib/iomgr/socket_factory_posix.h", + "src/src/core/lib/iomgr/socket_mutator.h", + "src/src/core/lib/iomgr/socket_utils.h", + "src/src/core/lib/iomgr/socket_utils_posix.h", + "src/src/core/lib/iomgr/socket_windows.h", + "src/src/core/lib/iomgr/sys_epoll_wrapper.h", + "src/src/core/lib/iomgr/tcp_client.h", + "src/src/core/lib/iomgr/tcp_client_posix.h", + "src/src/core/lib/iomgr/tcp_custom.h", + "src/src/core/lib/iomgr/tcp_posix.h", + "src/src/core/lib/iomgr/tcp_server.h", + "src/src/core/lib/iomgr/tcp_server_utils_posix.h", + "src/src/core/lib/iomgr/tcp_windows.h", + "src/src/core/lib/iomgr/time_averaged_stats.h", + "src/src/core/lib/iomgr/timer.h", + "src/src/core/lib/iomgr/timer_custom.h", + "src/src/core/lib/iomgr/timer_generic.h", + "src/src/core/lib/iomgr/timer_heap.h", + "src/src/core/lib/iomgr/timer_manager.h", + "src/src/core/lib/iomgr/udp_server.h", + "src/src/core/lib/iomgr/unix_sockets_posix.h", + "src/src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/src/core/lib/iomgr/wakeup_fd_posix.h", + "src/src/core/lib/iomgr/work_serializer.h", + "src/src/core/lib/json/json.h", + "src/src/core/lib/json/json_util.h", + "src/src/core/lib/profiling/timers.h", + "src/src/core/lib/security/authorization/authorization_engine.h", + "src/src/core/lib/security/authorization/evaluate_args.h", + "src/src/core/lib/security/authorization/mock_cel/activation.h", + "src/src/core/lib/security/authorization/mock_cel/cel_expr_builder_factory.h", + "src/src/core/lib/security/authorization/mock_cel/cel_expression.h", + "src/src/core/lib/security/authorization/mock_cel/cel_value.h", + "src/src/core/lib/security/authorization/mock_cel/evaluator_core.h", + "src/src/core/lib/security/authorization/mock_cel/flat_expr_builder.h", + "src/src/core/lib/security/context/security_context.h", + "src/src/core/lib/security/credentials/alts/alts_credentials.h", + "src/src/core/lib/security/credentials/alts/check_gcp_environment.h", + "src/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h", + "src/src/core/lib/security/credentials/composite/composite_credentials.h", + "src/src/core/lib/security/credentials/credentials.h", + "src/src/core/lib/security/credentials/external/external_account_credentials.h", + "src/src/core/lib/security/credentials/external/file_external_account_credentials.h", + "src/src/core/lib/security/credentials/external/url_external_account_credentials.h", + "src/src/core/lib/security/credentials/fake/fake_credentials.h", + "src/src/core/lib/security/credentials/google_default/google_default_credentials.h", + "src/src/core/lib/security/credentials/iam/iam_credentials.h", + "src/src/core/lib/security/credentials/jwt/json_token.h", + "src/src/core/lib/security/credentials/jwt/jwt_credentials.h", + "src/src/core/lib/security/credentials/jwt/jwt_verifier.h", + "src/src/core/lib/security/credentials/local/local_credentials.h", + "src/src/core/lib/security/credentials/oauth2/oauth2_credentials.h", + "src/src/core/lib/security/credentials/plugin/plugin_credentials.h", + "src/src/core/lib/security/credentials/ssl/ssl_credentials.h", + "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h", + "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h", + "src/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", + "src/src/core/lib/security/credentials/tls/tls_credentials.h", + "src/src/core/lib/security/credentials/xds/xds_credentials.h", + "src/src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/src/core/lib/security/security_connector/fake/fake_security_connector.h", + "src/src/core/lib/security/security_connector/insecure/insecure_security_connector.h", + "src/src/core/lib/security/security_connector/load_system_roots.h", + "src/src/core/lib/security/security_connector/load_system_roots_linux.h", + "src/src/core/lib/security/security_connector/local/local_security_connector.h", + "src/src/core/lib/security/security_connector/security_connector.h", + "src/src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/src/core/lib/security/security_connector/ssl_utils.h", + "src/src/core/lib/security/security_connector/ssl_utils_config.h", + "src/src/core/lib/security/security_connector/tls/tls_security_connector.h", + "src/src/core/lib/security/transport/auth_filters.h", + "src/src/core/lib/security/transport/secure_endpoint.h", + "src/src/core/lib/security/transport/security_handshaker.h", + "src/src/core/lib/security/transport/tsi_error.h", + "src/src/core/lib/security/util/json_util.h", + "src/src/core/lib/slice/b64.h", + "src/src/core/lib/slice/percent_encoding.h", + "src/src/core/lib/slice/slice_internal.h", + "src/src/core/lib/slice/slice_string_helpers.h", + "src/src/core/lib/slice/slice_utils.h", + "src/src/core/lib/surface/api_trace.h", + "src/src/core/lib/surface/call.h", + "src/src/core/lib/surface/call_test_only.h", + "src/src/core/lib/surface/channel.h", + "src/src/core/lib/surface/channel_init.h", + "src/src/core/lib/surface/channel_stack_type.h", + "src/src/core/lib/surface/completion_queue.h", + "src/src/core/lib/surface/completion_queue_factory.h", + "src/src/core/lib/surface/event_string.h", + "src/src/core/lib/surface/init.h", + "src/src/core/lib/surface/lame_client.h", + "src/src/core/lib/surface/server.h", + "src/src/core/lib/surface/validate_metadata.h", + "src/src/core/lib/transport/authority_override.h", + "src/src/core/lib/transport/bdp_estimator.h", + "src/src/core/lib/transport/byte_stream.h", + "src/src/core/lib/transport/connectivity_state.h", + "src/src/core/lib/transport/error_utils.h", + "src/src/core/lib/transport/http2_errors.h", + "src/src/core/lib/transport/metadata.h", + "src/src/core/lib/transport/metadata_batch.h", + "src/src/core/lib/transport/pid_controller.h", + "src/src/core/lib/transport/static_metadata.h", + "src/src/core/lib/transport/status_conversion.h", + "src/src/core/lib/transport/status_metadata.h", + "src/src/core/lib/transport/timeout_encoding.h", + "src/src/core/lib/transport/transport.h", + "src/src/core/lib/transport/transport_impl.h", + "src/src/core/lib/uri/uri_parser.h", + "src/src/core/tsi/alts/crypt/gsec.h", + "src/src/core/tsi/alts/frame_protector/alts_counter.h", + "src/src/core/tsi/alts/frame_protector/alts_crypter.h", + "src/src/core/tsi/alts/frame_protector/alts_frame_protector.h", + "src/src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h", + "src/src/core/tsi/alts/frame_protector/frame_handler.h", + "src/src/core/tsi/alts/handshaker/alts_handshaker_client.h", + "src/src/core/tsi/alts/handshaker/alts_shared_resource.h", + "src/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h", + "src/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h", + "src/src/core/tsi/alts/handshaker/alts_tsi_utils.h", + "src/src/core/tsi/alts/handshaker/transport_security_common_api.h", + "src/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h", + "src/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h", + "src/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h", + "src/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h", + "src/src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h", + "src/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h", + "src/src/core/tsi/fake_transport_security.h", + "src/src/core/tsi/local_transport_security.h", + "src/src/core/tsi/ssl/session_cache/ssl_session.h", + "src/src/core/tsi/ssl/session_cache/ssl_session_cache.h", + "src/src/core/tsi/ssl_transport_security.h", + "src/src/core/tsi/ssl_types.h", + "src/src/core/tsi/transport_security.h", + "src/src/core/tsi/transport_security_grpc.h", + "src/src/core/tsi/transport_security_interface.h", + "src/src/cpp/client/create_channel_internal.h", + "src/src/cpp/client/secure_credentials.h", + "src/src/cpp/common/channel_filter.h", + "src/src/cpp/common/secure_auth_context.h", + "src/src/cpp/common/tls_credentials_options_util.h", + "src/src/cpp/server/dynamic_thread_pool.h", + "src/src/cpp/server/external_connection_acceptor_impl.h", + "src/src/cpp/server/health/default_health_check_service.h", + "src/src/cpp/server/secure_server_credentials.h", + "src/src/cpp/server/thread_pool_interface.h", + "src/src/cpp/thread_manager/thread_manager.h", + ] -# Only compile the protobuf plugin for the host architecture. -if (current_toolchain == host_toolchain) { - # The protobuf plugin for building gRPC interface from protobuf, used by - # cc_grpc_library(). - executable("grpc_cpp_plugin") { - sources = [ - "src/src/compiler/cpp_generator.cc", - "src/src/compiler/cpp_plugin.cc", - ] - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - public_configs = [ ":grpc_config" ] - deps = [ "//third_party/protobuf:protoc_lib" ] + deps = [ + ":address_sorting", + ":cares", + ":upb", + "//third_party/abseil-cpp:absl", + "//third_party/boringssl", + "//third_party/protobuf:protobuf_lite", + "//third_party/zlib", + ] + public_configs = [ + ":grpc_config", + ] + configs += [ + ":grpc_config_private", + ] + include_dirs = [ + ":cares", + "src/third_party/address_sorting/include", + ] + visibility = [ "./*" ] + if (!is_win) { + configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] + configs += [ "//build/config/gcc:symbol_visibility_default" ] } } -static_library("grpc_core") { - visibility = [ ":*" ] - +source_set("grpc++_cc") { sources = [ "src/src/core/ext/filters/census/grpc_context.cc", + "src/src/core/ext/filters/client_channel/backend_metric.cc", "src/src/core/ext/filters/client_channel/backup_poller.cc", "src/src/core/ext/filters/client_channel/channel_connectivity.cc", "src/src/core/ext/filters/client_channel/client_channel.cc", "src/src/core/ext/filters/client_channel/client_channel_channelz.cc", "src/src/core/ext/filters/client_channel/client_channel_factory.cc", "src/src/core/ext/filters/client_channel/client_channel_plugin.cc", - "src/src/core/ext/filters/client_channel/connector.cc", + "src/src/core/ext/filters/client_channel/config_selector.cc", "src/src/core/ext/filters/client_channel/global_subchannel_pool.cc", - "src/src/core/ext/filters/client_channel/health/health.pb.c", "src/src/core/ext/filters/client_channel/health/health_check_client.cc", "src/src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/src/core/ext/filters/client_channel/http_proxy.cc", "src/src/core/ext/filters/client_channel/lb_policy.cc", - "src/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc", - "src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc", - "src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc", - "src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc", - "src/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc", - "src/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", + "src/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc", + "src/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc", + "src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc", "src/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc", - "src/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc", - "src/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc", - "src/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc", - "src/src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc", - "src/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc", "src/src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/src/core/ext/filters/client_channel/local_subchannel_pool.cc", - "src/src/core/ext/filters/client_channel/parse_address.cc", - "src/src/core/ext/filters/client_channel/proxy_mapper.cc", "src/src/core/ext/filters/client_channel/proxy_mapper_registry.cc", "src/src/core/ext/filters/client_channel/resolver.cc", "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc", "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc", + "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", + "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", "src/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", @@ -175,13 +904,17 @@ "src/src/core/ext/filters/client_channel/retry_throttle.cc", "src/src/core/ext/filters/client_channel/server_address.cc", "src/src/core/ext/filters/client_channel/service_config.cc", + "src/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc", + "src/src/core/ext/filters/client_channel/service_config_parser.cc", "src/src/core/ext/filters/client_channel/subchannel.cc", "src/src/core/ext/filters/client_channel/subchannel_pool_interface.cc", + "src/src/core/ext/filters/client_idle/client_idle_filter.cc", "src/src/core/ext/filters/deadline/deadline_filter.cc", "src/src/core/ext/filters/http/client/http_client_filter.cc", "src/src/core/ext/filters/http/client_authority_filter.cc", "src/src/core/ext/filters/http/http_filters_plugin.cc", "src/src/core/ext/filters/http/message_compress/message_compress_filter.cc", + "src/src/core/ext/filters/http/message_compress/message_decompress_filter.cc", "src/src/core/ext/filters/http/server/http_server_filter.cc", "src/src/core/ext/filters/max_age/max_age_filter.cc", "src/src/core/ext/filters/message_size/message_size_filter.cc", @@ -222,6 +955,149 @@ "src/src/core/ext/transport/chttp2/transport/writing.cc", "src/src/core/ext/transport/inproc/inproc_plugin.cc", "src/src/core/ext/transport/inproc/inproc_transport.cc", + "src/src/core/ext/upb-generated/envoy/annotations/deprecation.upb.c", + "src/src/core/ext/upb-generated/envoy/annotations/resource.upb.c", + "src/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c", + "src/src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c", + "src/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c", + "src/src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c", + "src/src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c", + "src/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c", + "src/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c", + "src/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c", + "src/src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c", + "src/src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c", + "src/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c", + "src/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c", + "src/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c", + "src/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c", + "src/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c", + "src/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c", + "src/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c", + "src/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c", + "src/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c", + "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c", + "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c", + "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c", + "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c", + "src/src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.c", + "src/src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c", + "src/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c", + "src/src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.c", + "src/src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.c", + "src/src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c", + "src/src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.c", + "src/src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.c", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c", + "src/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c", + "src/src/core/ext/upb-generated/envoy/type/v3/http.upb.c", + "src/src/core/ext/upb-generated/envoy/type/v3/percent.upb.c", + "src/src/core/ext/upb-generated/envoy/type/v3/range.upb.c", + "src/src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c", + "src/src/core/ext/upb-generated/google/api/annotations.upb.c", + "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c", + "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c", + "src/src/core/ext/upb-generated/google/rpc/status.upb.c", + "src/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c", + "src/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c", + "src/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c", + "src/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c", + "src/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c", + "src/src/core/ext/upb-generated/udpa/annotations/migrate.upb.c", + "src/src/core/ext/upb-generated/udpa/annotations/security.upb.c", + "src/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c", + "src/src/core/ext/upb-generated/udpa/annotations/versioning.upb.c", + "src/src/core/ext/upb-generated/udpa/core/v1/authority.upb.c", + "src/src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.c", + "src/src/core/ext/upb-generated/udpa/core/v1/context_params.upb.c", + "src/src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.c", + "src/src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.c", + "src/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c", + "src/src/core/ext/upb-generated/validate/validate.upb.c", + "src/src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/service/cluster/v3/cds.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/service/endpoint/v3/eds.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/service/listener/v3/lds.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/service/route/v3/rds.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/service/route/v3/srds.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/authority.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/collection_entry.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/context_params.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/resource_locator.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/resource_name.upbdefs.c", + "src/src/core/ext/upbdefs-generated/validate/validate.upbdefs.c", "src/src/core/lib/avl/avl.cc", "src/src/core/lib/backoff/backoff.cc", "src/src/core/lib/channel/channel_args.cc", @@ -258,13 +1134,13 @@ "src/src/core/lib/gpr/log_linux.cc", "src/src/core/lib/gpr/log_posix.cc", "src/src/core/lib/gpr/log_windows.cc", - "src/src/core/lib/gpr/mpscq.cc", "src/src/core/lib/gpr/murmur_hash.cc", "src/src/core/lib/gpr/string.cc", "src/src/core/lib/gpr/string_posix.cc", "src/src/core/lib/gpr/string_util_windows.cc", "src/src/core/lib/gpr/string_windows.cc", "src/src/core/lib/gpr/sync.cc", + "src/src/core/lib/gpr/sync_abseil.cc", "src/src/core/lib/gpr/sync_posix.cc", "src/src/core/lib/gpr/sync_windows.cc", "src/src/core/lib/gpr/time.cc", @@ -275,10 +1151,17 @@ "src/src/core/lib/gpr/tmpfile_msys.cc", "src/src/core/lib/gpr/tmpfile_posix.cc", "src/src/core/lib/gpr/tmpfile_windows.cc", + # gRPC memcpy wrapping logic isn't useful here. + # See https://crbug.com/661171 + # "src/src/core/lib/gpr/wrap_memcpy.cc", "src/src/core/lib/gprpp/arena.cc", + "src/src/core/lib/gprpp/examine_stack.cc", "src/src/core/lib/gprpp/fork.cc", "src/src/core/lib/gprpp/global_config_env.cc", "src/src/core/lib/gprpp/host_port.cc", + "src/src/core/lib/gprpp/mpscq.cc", + "src/src/core/lib/gprpp/stat_posix.cc", + "src/src/core/lib/gprpp/stat_windows.cc", "src/src/core/lib/gprpp/thd_posix.cc", "src/src/core/lib/gprpp/thd_windows.cc", "src/src/core/lib/http/format_request.cc", @@ -289,6 +1172,7 @@ "src/src/core/lib/iomgr/call_combiner.cc", "src/src/core/lib/iomgr/cfstream_handle.cc", "src/src/core/lib/iomgr/combiner.cc", + "src/src/core/lib/iomgr/dualstack_socket_posix.cc", "src/src/core/lib/iomgr/endpoint.cc", "src/src/core/lib/iomgr/endpoint_cfstream.cc", "src/src/core/lib/iomgr/endpoint_pair_posix.cc", @@ -296,6 +1180,7 @@ "src/src/core/lib/iomgr/endpoint_pair_windows.cc", "src/src/core/lib/iomgr/error.cc", "src/src/core/lib/iomgr/error_cfstream.cc", + "src/src/core/lib/iomgr/ev_apple.cc", "src/src/core/lib/iomgr/ev_epoll1_linux.cc", "src/src/core/lib/iomgr/ev_epollex_linux.cc", "src/src/core/lib/iomgr/ev_poll_posix.cc", @@ -303,6 +1188,8 @@ "src/src/core/lib/iomgr/ev_windows.cc", "src/src/core/lib/iomgr/exec_ctx.cc", "src/src/core/lib/iomgr/executor.cc", + "src/src/core/lib/iomgr/executor/mpmcqueue.cc", + "src/src/core/lib/iomgr/executor/threadpool.cc", "src/src/core/lib/iomgr/fork_posix.cc", "src/src/core/lib/iomgr/fork_windows.cc", "src/src/core/lib/iomgr/gethostname_fallback.cc", @@ -322,6 +1209,8 @@ "src/src/core/lib/iomgr/is_epollexclusive_available.cc", "src/src/core/lib/iomgr/load_file.cc", "src/src/core/lib/iomgr/lockfree_event.cc", + "src/src/core/lib/iomgr/parse_address.cc", + "src/src/core/lib/iomgr/poller/eventmanager_libuv.cc", "src/src/core/lib/iomgr/polling_entity.cc", "src/src/core/lib/iomgr/pollset.cc", "src/src/core/lib/iomgr/pollset_custom.cc", @@ -374,12 +1263,14 @@ "src/src/core/lib/iomgr/wakeup_fd_nospecial.cc", "src/src/core/lib/iomgr/wakeup_fd_pipe.cc", "src/src/core/lib/iomgr/wakeup_fd_posix.cc", - "src/src/core/lib/json/json.cc", + "src/src/core/lib/iomgr/work_serializer.cc", "src/src/core/lib/json/json_reader.cc", - "src/src/core/lib/json/json_string.cc", + "src/src/core/lib/json/json_util.cc", "src/src/core/lib/json/json_writer.cc", "src/src/core/lib/profiling/basic_timers.cc", "src/src/core/lib/profiling/stap_timers.cc", + "src/src/core/lib/security/authorization/authorization_engine.cc", + "src/src/core/lib/security/authorization/evaluate_args.cc", "src/src/core/lib/security/context/security_context.cc", "src/src/core/lib/security/credentials/alts/alts_credentials.cc", "src/src/core/lib/security/credentials/alts/check_gcp_environment.cc", @@ -392,10 +1283,14 @@ "src/src/core/lib/security/credentials/composite/composite_credentials.cc", "src/src/core/lib/security/credentials/credentials.cc", "src/src/core/lib/security/credentials/credentials_metadata.cc", + "src/src/core/lib/security/credentials/external/external_account_credentials.cc", + "src/src/core/lib/security/credentials/external/file_external_account_credentials.cc", + "src/src/core/lib/security/credentials/external/url_external_account_credentials.cc", "src/src/core/lib/security/credentials/fake/fake_credentials.cc", "src/src/core/lib/security/credentials/google_default/credentials_generic.cc", "src/src/core/lib/security/credentials/google_default/google_default_credentials.cc", "src/src/core/lib/security/credentials/iam/iam_credentials.cc", + "src/src/core/lib/security/credentials/insecure/insecure_credentials.cc", "src/src/core/lib/security/credentials/jwt/json_token.cc", "src/src/core/lib/security/credentials/jwt/jwt_credentials.cc", "src/src/core/lib/security/credentials/jwt/jwt_verifier.cc", @@ -403,22 +1298,27 @@ "src/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc", "src/src/core/lib/security/credentials/plugin/plugin_credentials.cc", "src/src/core/lib/security/credentials/ssl/ssl_credentials.cc", + "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc", + "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc", "src/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", + "src/src/core/lib/security/credentials/tls/tls_credentials.cc", + "src/src/core/lib/security/credentials/xds/xds_credentials.cc", "src/src/core/lib/security/security_connector/alts/alts_security_connector.cc", "src/src/core/lib/security/security_connector/fake/fake_security_connector.cc", + "src/src/core/lib/security/security_connector/insecure/insecure_security_connector.cc", "src/src/core/lib/security/security_connector/load_system_roots_fallback.cc", "src/src/core/lib/security/security_connector/load_system_roots_linux.cc", "src/src/core/lib/security/security_connector/local/local_security_connector.cc", "src/src/core/lib/security/security_connector/security_connector.cc", "src/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", "src/src/core/lib/security/security_connector/ssl_utils.cc", + "src/src/core/lib/security/security_connector/ssl_utils_config.cc", + "src/src/core/lib/security/security_connector/tls/tls_security_connector.cc", "src/src/core/lib/security/transport/client_auth_filter.cc", "src/src/core/lib/security/transport/secure_endpoint.cc", "src/src/core/lib/security/transport/security_handshaker.cc", "src/src/core/lib/security/transport/server_auth_filter.cc", - "src/src/core/lib/security/transport/target_authority_table.cc", "src/src/core/lib/security/transport/tsi_error.cc", - "src/src/core/lib/security/util/json_util.cc", "src/src/core/lib/slice/b64.cc", "src/src/core/lib/slice/percent_encoding.cc", "src/src/core/lib/slice/slice.cc", @@ -445,6 +1345,7 @@ "src/src/core/lib/surface/server.cc", "src/src/core/lib/surface/validate_metadata.cc", "src/src/core/lib/surface/version.cc", + "src/src/core/lib/transport/authority_override.cc", "src/src/core/lib/transport/bdp_estimator.cc", "src/src/core/lib/transport/byte_stream.cc", "src/src/core/lib/transport/connectivity_state.cc", @@ -459,7 +1360,9 @@ "src/src/core/lib/transport/transport.cc", "src/src/core/lib/transport/transport_op_string.cc", "src/src/core/lib/uri/uri_parser.cc", - "src/src/core/plugin_registry/grpc_plugin_registry.cc", + # Disabling some default plugins. + # "src/src/core/plugin_registry/grpc_plugin_registry.cc", + "plugin_registry/grpc_plugin_registry.cc", "src/src/core/tsi/alts/crypt/aes_gcm.cc", "src/src/core/tsi/alts/crypt/gsec.cc", "src/src/core/tsi/alts/frame_protector/alts_counter.cc", @@ -470,14 +1373,9 @@ "src/src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc", "src/src/core/tsi/alts/frame_protector/frame_handler.cc", "src/src/core/tsi/alts/handshaker/alts_handshaker_client.cc", - "src/src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc", - "src/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc", "src/src/core/tsi/alts/handshaker/alts_shared_resource.cc", "src/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc", "src/src/core/tsi/alts/handshaker/alts_tsi_utils.cc", - "src/src/core/tsi/alts/handshaker/altscontext.pb.c", - "src/src/core/tsi/alts/handshaker/handshaker.pb.c", - "src/src/core/tsi/alts/handshaker/transport_security_common.pb.c", "src/src/core/tsi/alts/handshaker/transport_security_common_api.cc", "src/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc", "src/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc", @@ -492,301 +1390,369 @@ "src/src/core/tsi/ssl_transport_security.cc", "src/src/core/tsi/transport_security.cc", "src/src/core/tsi/transport_security_grpc.cc", + "src/src/cpp/client/channel_cc.cc", + "src/src/cpp/client/client_callback.cc", + "src/src/cpp/client/client_context.cc", + "src/src/cpp/client/client_interceptor.cc", + "src/src/cpp/client/create_channel.cc", + "src/src/cpp/client/create_channel_internal.cc", + "src/src/cpp/client/create_channel_posix.cc", + "src/src/cpp/client/credentials_cc.cc", + "src/src/cpp/client/secure_credentials.cc", + "src/src/cpp/codegen/codegen_init.cc", + "src/src/cpp/common/alarm.cc", + "src/src/cpp/common/auth_property_iterator.cc", + "src/src/cpp/common/channel_arguments.cc", + "src/src/cpp/common/channel_filter.cc", + "src/src/cpp/common/completion_queue_cc.cc", + "src/src/cpp/common/core_codegen.cc", + "src/src/cpp/common/resource_quota_cc.cc", + "src/src/cpp/common/rpc_method.cc", + "src/src/cpp/common/secure_auth_context.cc", + "src/src/cpp/common/secure_channel_arguments.cc", + "src/src/cpp/common/secure_create_auth_context.cc", + "src/src/cpp/common/tls_certificate_provider.cc", + "src/src/cpp/common/tls_credentials_options.cc", + "src/src/cpp/common/tls_credentials_options_util.cc", + "src/src/cpp/common/validate_service_config.cc", + "src/src/cpp/common/version_cc.cc", + "src/src/cpp/server/async_generic_service.cc", + "src/src/cpp/server/channel_argument_option.cc", + "src/src/cpp/server/create_default_thread_pool.cc", + "src/src/cpp/server/dynamic_thread_pool.cc", + "src/src/cpp/server/external_connection_acceptor_impl.cc", + "src/src/cpp/server/health/default_health_check_service.cc", + "src/src/cpp/server/health/health_check_service.cc", + "src/src/cpp/server/health/health_check_service_server_builder_option.cc", + "src/src/cpp/server/insecure_server_credentials.cc", + "src/src/cpp/server/secure_server_credentials.cc", + "src/src/cpp/server/server_builder.cc", + "src/src/cpp/server/server_callback.cc", + "src/src/cpp/server/server_cc.cc", + "src/src/cpp/server/server_context.cc", + "src/src/cpp/server/server_credentials.cc", + "src/src/cpp/server/server_posix.cc", + "src/src/cpp/thread_manager/thread_manager.cc", + "src/src/cpp/util/byte_buffer_cc.cc", + "src/src/cpp/util/status.cc", + "src/src/cpp/util/string_ref.cc", + "src/src/cpp/util/time_cc.cc", ] - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] deps = [ - ":nanopb", + ":address_sorting", + ":cares", + ":grpc++_h", + ":upb", + "//third_party/abseil-cpp:absl", + "//third_party/boringssl", + "//third_party/protobuf:protobuf_lite", + "//third_party/zlib", + ] + public_configs = [ + ":grpc_config", + ] + configs += [ + ":grpc_config_private", + ] + include_dirs = [ + ":cares", + "src/third_party/address_sorting/include", + ] + visibility = [ "./*" ] + if (!is_win) { + configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] + configs += [ "//build/config/gcc:symbol_visibility_default" ] + } +} + +source_set("grpc++_repeated") { + sources = [ + "src/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c", + "src/src/core/ext/upb-generated/google/api/http.upb.c", + "src/src/core/ext/upb-generated/udpa/annotations/status.upb.c", + "src/src/core/ext/upb-generated/udpa/core/v1/resource.upb.c", + "src/src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/api/http.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c", + "src/src/core/ext/upbdefs-generated/udpa/core/v1/resource.upbdefs.c", + "src/src/core/lib/security/util/json_util.cc", + "src/src/cpp/client/insecure_credentials.cc", + "src/src/cpp/client/xds_credentials.cc", + ] + + deps = [ + ":address_sorting", + ":cares", + ":grpc++_h", + ":upb", + "//third_party/abseil-cpp:absl", + "//third_party/boringssl", + "//third_party/protobuf:protobuf_lite", + "//third_party/zlib", + ] + public_configs = [ + ":grpc_config", + ] + configs += [ + ":grpc_config_private", + ] + visibility = [ "./*" ] + if (!is_win) { + configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] + configs += [ "//build/config/gcc:symbol_visibility_default" ] + } +} + +source_set("address_sorting") { + sources = [ + "src/third_party/address_sorting/address_sorting.c", + "src/third_party/address_sorting/address_sorting_internal.h", + "src/third_party/address_sorting/address_sorting_posix.c", + "src/third_party/address_sorting/address_sorting_windows.c", + "src/third_party/address_sorting/include/address_sorting/address_sorting.h", + ] + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "src/third_party/address_sorting/include", + ] + visibility = [ "./*" ] + if (!is_win) { + configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] + configs += [ "//build/config/gcc:symbol_visibility_default" ] + } +} + +# Only compile the plugin for the host architecture. +if (current_toolchain == host_toolchain) { + source_set("grpc_plugin_support") { + sources = [ + "src/include/grpc++/impl/codegen/config_protobuf.h", + "src/include/grpcpp/impl/codegen/config_protobuf.h", + "src/src/compiler/config.h", + "src/src/compiler/config_protobuf.h", + "src/src/compiler/cpp_generator.cc", + "src/src/compiler/cpp_generator.h", + "src/src/compiler/cpp_generator_helpers.h", + "src/src/compiler/cpp_plugin.h", + "src/src/compiler/csharp_generator.cc", + "src/src/compiler/csharp_generator.h", + "src/src/compiler/csharp_generator_helpers.h", + "src/src/compiler/generator_helpers.h", + "src/src/compiler/node_generator.cc", + "src/src/compiler/node_generator.h", + "src/src/compiler/node_generator_helpers.h", + "src/src/compiler/objective_c_generator.cc", + "src/src/compiler/objective_c_generator.h", + "src/src/compiler/objective_c_generator_helpers.h", + "src/src/compiler/php_generator.cc", + "src/src/compiler/php_generator.h", + "src/src/compiler/php_generator_helpers.h", + "src/src/compiler/protobuf_plugin.h", + "src/src/compiler/python_generator.cc", + "src/src/compiler/python_generator.h", + "src/src/compiler/python_generator_helpers.h", + "src/src/compiler/python_private_generator.h", + "src/src/compiler/schema_interface.h", + ] + + deps = [ + "//third_party/protobuf:protoc_lib", + ] + public_configs = [ + ":grpc_config", + ] + } + +} +source_set("upb") { + sources = [ + "src/src/core/ext/upb-generated/google/protobuf/any.upb.c", + "src/src/core/ext/upb-generated/google/protobuf/any.upb.h", + "src/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c", + "src/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h", + "src/src/core/ext/upb-generated/google/protobuf/duration.upb.c", + "src/src/core/ext/upb-generated/google/protobuf/duration.upb.h", + "src/src/core/ext/upb-generated/google/protobuf/empty.upb.c", + "src/src/core/ext/upb-generated/google/protobuf/empty.upb.h", + "src/src/core/ext/upb-generated/google/protobuf/struct.upb.c", + "src/src/core/ext/upb-generated/google/protobuf/struct.upb.h", + "src/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", + "src/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h", + "src/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", + "src/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h", + "src/src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.h", + "src/src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.h", + "src/third_party/upb/upb/decode.c", + "src/third_party/upb/upb/decode.h", + "src/third_party/upb/upb/def.c", + "src/third_party/upb/upb/def.h", + "src/third_party/upb/upb/def.hpp", + "src/third_party/upb/upb/encode.c", + "src/third_party/upb/upb/encode.h", + "src/third_party/upb/upb/msg.c", + "src/third_party/upb/upb/msg.h", + "src/third_party/upb/upb/port.c", + "src/third_party/upb/upb/port_def.inc", + "src/third_party/upb/upb/port_undef.inc", + "src/third_party/upb/upb/reflection.c", + "src/third_party/upb/upb/reflection.h", + "src/third_party/upb/upb/table.c", + "src/third_party/upb/upb/table.int.h", + "src/third_party/upb/upb/text_encode.c", + "src/third_party/upb/upb/text_encode.h", + "src/third_party/upb/upb/upb.c", + "src/third_party/upb/upb/upb.h", + "src/third_party/upb/upb/upb.hpp", + ] + public_configs = [ + ":grpc_config", + ] + visibility = [ "./*" ] + if (!is_win) { + configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] + configs += [ "//build/config/gcc:symbol_visibility_default" ] + } +} + +# Only compile the plugin for the host architecture. +if (current_toolchain == host_toolchain) { + executable("grpc_cpp_plugin") { + sources = [ + "src/src/compiler/cpp_plugin.cc", + ] + deps = [ + ":grpc_plugin_support", + "//third_party/protobuf:protoc_lib", + ] + configs += [ + "//third_party/protobuf:protobuf_config", + ] + public_configs = [ ":grpc_config" ] + } +} + +config("cares_config") { + cflags = [ + "-Wno-macro-redefined", + "-Wno-unused-variable", + ] +} + +source_set("cares") { + sources = [ + "src/third_party/cares/ares_build.h", + ] + + if (enable_grpc_ares) { + sources += [ + "//third_party/cares/ares.h", + "//third_party/cares/ares__close_sockets.c", + "//third_party/cares/ares__get_hostent.c", + "//third_party/cares/ares__read_line.c", + "//third_party/cares/ares__timeval.c", + "//third_party/cares/ares_android.c", + "//third_party/cares/ares_android.h", + "//third_party/cares/ares_cancel.c", + "//third_party/cares/ares_create_query.c", + "//third_party/cares/ares_data.c", + "//third_party/cares/ares_data.h", + "//third_party/cares/ares_destroy.c", + "//third_party/cares/ares_dns.h", + "//third_party/cares/ares_expand_name.c", + "//third_party/cares/ares_expand_string.c", + "//third_party/cares/ares_fds.c", + "//third_party/cares/ares_free_hostent.c", + "//third_party/cares/ares_free_string.c", + "//third_party/cares/ares_getenv.c", + "//third_party/cares/ares_getenv.h", + "//third_party/cares/ares_gethostbyaddr.c", + "//third_party/cares/ares_gethostbyname.c", + "//third_party/cares/ares_getnameinfo.c", + "//third_party/cares/ares_getopt.c", + "//third_party/cares/ares_getopt.h", + "//third_party/cares/ares_getsock.c", + "//third_party/cares/ares_inet_net_pton.h", + "//third_party/cares/ares_init.c", + "//third_party/cares/ares_iphlpapi.h", + "//third_party/cares/ares_ipv6.h", + "//third_party/cares/ares_library_init.c", + "//third_party/cares/ares_library_init.h", + "//third_party/cares/ares_llist.c", + "//third_party/cares/ares_llist.h", + "//third_party/cares/ares_mkquery.c", + "//third_party/cares/ares_nowarn.c", + "//third_party/cares/ares_nowarn.h", + "//third_party/cares/ares_options.c", + "//third_party/cares/ares_parse_a_reply.c", + "//third_party/cares/ares_parse_aaaa_reply.c", + "//third_party/cares/ares_parse_mx_reply.c", + "//third_party/cares/ares_parse_naptr_reply.c", + "//third_party/cares/ares_parse_ns_reply.c", + "//third_party/cares/ares_parse_ptr_reply.c", + "//third_party/cares/ares_parse_soa_reply.c", + "//third_party/cares/ares_parse_srv_reply.c", + "//third_party/cares/ares_parse_txt_reply.c", + "//third_party/cares/ares_platform.c", + "//third_party/cares/ares_platform.h", + "//third_party/cares/ares_private.h", + "//third_party/cares/ares_process.c", + "//third_party/cares/ares_query.c", + "//third_party/cares/ares_rules.h", + "//third_party/cares/ares_search.c", + "//third_party/cares/ares_send.c", + "//third_party/cares/ares_setup.h", + "//third_party/cares/ares_strcasecmp.c", + "//third_party/cares/ares_strcasecmp.h", + "//third_party/cares/ares_strdup.c", + "//third_party/cares/ares_strdup.h", + "//third_party/cares/ares_strerror.c", + "//third_party/cares/ares_strsplit.c", + "//third_party/cares/ares_strsplit.h", + "//third_party/cares/ares_timeout.c", + "//third_party/cares/ares_version.c", + "//third_party/cares/ares_version.h", + "//third_party/cares/ares_writev.c", + "//third_party/cares/ares_writev.h", + "//third_party/cares/bitncmp.c", + "//third_party/cares/bitncmp.h", + "//third_party/cares/config-dos.h", + "//third_party/cares/config-win32.h", + "//third_party/cares/inet_net_pton.c", + "//third_party/cares/inet_ntop.c", + "//third_party/cares/nameser.h", + "//third_party/cares/setup_once.h", + "//third_party/cares/windows_port.c", + ] + } + + if (is_android) { + sources += [ "src/third_party/cares/config_android/ares_config.h" ] + configs += [ ":cares_config" ] + } else if (is_fuchsia) { + sources += [ "third_party/cares/config_fuchsia/ares_config.h" ] + } else { + sources += [ "src/third_party/cares/config_linux/ares_config.h" ] + } + deps = [ "//third_party/boringssl", ] - public_deps = [ "//third_party/zlib" ] + + public_configs = [ ":grpc_config" ] } -static_library("nanopb") { - visibility = [ ":*" ] - sources = [ - "src/third_party/nanopb/pb_common.c", - "src/third_party/nanopb/pb_decode.c", - "src/third_party/nanopb/pb_encode.c", - ] - public_configs = [ ":nanopb_config" ] -} - -static_library("grpc_test_util") { - visibility = [ ":*" ] - sources = [ - "src/test/core/end2end/cq_verifier.cc", - "src/test/core/end2end/data/client_certs.cc", - "src/test/core/end2end/data/server1_cert.cc", - "src/test/core/end2end/data/server1_key.cc", - "src/test/core/end2end/data/test_root_cert.cc", - "src/test/core/end2end/fixtures/http_proxy_fixture.cc", - "src/test/core/end2end/fixtures/local_util.cc", - "src/test/core/end2end/fixtures/proxy.cc", - "src/test/core/iomgr/endpoint_tests.cc", - "src/test/core/security/oauth2_utils.cc", - "src/test/core/util/cmdline.cc", - "src/test/core/util/debugger_macros.cc", - "src/test/core/util/fuzzer_util.cc", - "src/test/core/util/grpc_profiler.cc", - "src/test/core/util/histogram.cc", - "src/test/core/util/memory_counters.cc", - "src/test/core/util/mock_endpoint.cc", - "src/test/core/util/parse_hexstring.cc", - "src/test/core/util/passthru_endpoint.cc", - "src/test/core/util/port.cc", - "src/test/core/util/port_isolated_runtime_environment.cc", - "src/test/core/util/port_server_client.cc", - "src/test/core/util/slice_splitter.cc", - "src/test/core/util/subprocess_posix.cc", - "src/test/core/util/subprocess_windows.cc", - "src/test/core/util/test_lb_policies.cc", - "src/test/core/util/tracer_util.cc", - "src/test/core/util/trickle_endpoint.cc", - ] - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - deps = [ - ":grpc_core", - ":nanopb", - ] -} - -# A dummy group which is needed to make the fuzz targets discoverable. -group("fuzzers") { -} - -fuzzer_test("grpc_alts_credentials_fuzzer") { - sources = [ "src/test/core/security/alts_credentials_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/security/corpus/alts_credentials_corpus" -} - -fuzzer_test("grpc_api_fuzzer") { - sources = [ "src/test/core/end2end/fuzzers/api_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/end2end/fuzzers/api_fuzzer_corpus" - dict = "src/test/core/end2end/fuzzers/api_fuzzer.dictionary" -} - -fuzzer_test("grpc_client_fuzzer") { - sources = [ "src/test/core/end2end/fuzzers/client_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/end2end/fuzzers/client_fuzzer_corpus" - dict = "src/test/core/end2end/fuzzers/hpack.dictionary" -} - -fuzzer_test("grpc_hpack_parser_fuzzer_test") { - sources = [ "src/test/core/transport/chttp2/hpack_parser_fuzzer_test.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/transport/chttp2/hpack_parser_corpus" -} - -fuzzer_test("grpc_request_fuzzer") { - sources = [ "src/test/core/http/request_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/http/request_corpus" -} - -fuzzer_test("grpc_response_fuzzer") { - sources = [ "src/test/core/http/response_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/http/response_corpus" -} - -fuzzer_test("grpc_json_fuzzer") { - sources = [ "src/test/core/json/fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/json/corpus" -} - -fuzzer_test("grpc_nanopb_fuzzer_response") { - sources = [ "src/test/core/nanopb/fuzzer_response.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/nanopb/corpus_response" -} - -fuzzer_test("grpc_nanopb_fuzzer_serverlist") { - sources = [ "src/test/core/nanopb/fuzzer_serverlist.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/nanopb/corpus_serverlist" -} - -fuzzer_test("grpc_percent_decode_fuzzer") { - sources = [ "src/test/core/slice/percent_decode_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/slice/percent_decode_corpus" -} - -fuzzer_test("grpc_percent_encode_fuzzer") { - sources = [ "src/test/core/slice/percent_encode_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/slice/percent_encode_corpus" -} - -fuzzer_test("grpc_server_fuzzer") { - sources = [ "src/test/core/end2end/fuzzers/server_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/end2end/fuzzers/server_fuzzer_corpus" -} - -fuzzer_test("grpc_ssl_server_fuzzer") { - sources = [ "src/test/core/security/ssl_server_fuzzer.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/security/corpus/ssl_server_corpus" -} - -fuzzer_test("grpc_uri_fuzzer_test") { - sources = [ "src/test/core/client_channel/uri_fuzzer_test.cc" ] - deps = [ - ":grpc_core", - ":grpc_test_util", - ":nanopb", - ] - additional_configs = [ - ":grpc_config", - ":grpc_internal_config", - "//build/config/compiler:no_chromium_code", - ] - suppressed_configs = [ "//build/config/compiler:chromium_code" ] - seed_corpus = "src/test/core/client_channel/uri_corpus" -} +group("fuzzers") {}
diff --git a/third_party/grpc/README.chromium b/third_party/grpc/README.chromium index 7dd35c0a..095dd2b 100644 --- a/third_party/grpc/README.chromium +++ b/third_party/grpc/README.chromium
@@ -1,16 +1,21 @@ -Name: gRPC +Name: grpc URL: https://github.com/grpc/grpc -Version: 0 -Date: Jul 16, 2019 -Revision: 74b981a6a3d9ba17f3acae1d72b9109325ef656d License: Apache 2.0 -License File: LICENSE +Version: v1.33.0+ +Revision: 4ac9c6f755463a2321f84b0cb2d631e1828faedb Security Critical: yes -Description: -gRPC is a library to make remote procedure calls (RPC) between server and client -applications. This is currently used by Chrome Remote Desktop during the -signaling process. - -Local Modifications: -None +Steps to upgrade to a new version of GRPC: +1. Merge origin/grpc/master into eureka/master branch. +2. Update revision and version information in this file. +4. Checkout GRPC submodules with: git submodule update --init +5. Copy template/BUILD.chromium.gn.template to src/templates +6. Rebuild BUILD.gn by running tools/buildgen/generate_projects.sh + (make sure mako_templates python module is installed in your system) + and then running gn format BUILD.gn. This will use the template in + templates/BUILD.chromium.gn.template to generate BUILD.chromium.gn file. +4. Do: + mv third_party/grpc/src/BUILD.chromium.gn BUILD.gn +6. Update plugin_register. Ensure xds_resolver and all lb_policies are +disabled except first_pick. +5. Run 'gn format --in-place BUILD.gn'
diff --git a/third_party/grpc/grpc_library.gni b/third_party/grpc/grpc_library.gni index 8e09753..38eeddd 100644 --- a/third_party/grpc/grpc_library.gni +++ b/third_party/grpc/grpc_library.gni
@@ -1,45 +1,51 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. +# Copyright 2019 Google Inc. All Rights Reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# Compile a grpc service. +# +# Example: +# grpc_library("mylib") { +# sources = [ +# "foo.proto", +# ] +# } + +import("//build/config/sanitizers/sanitizers.gni") import("//third_party/protobuf/proto_library.gni") -# Compiles a protocol buffer into gRPC C++ interface. -# -# Example -# cc_grpc_library("mylib") { -# sources = [ -# "foo.proto", -# ] -# } -template("cc_grpc_library") { - proto_library_name = "${target_name}_proto_lib" - proto_library(proto_library_name) { +template("grpc_library") { + assert(defined(invoker.sources), "Need sources for proto_library") + proto_library(target_name) { forward_variables_from(invoker, [ - "defines", - "deps", - "sources", - "use_protobuf_full", + "cc_include", + "extra_configs", + "generator_plugin_label", + "generator_plugin_suffix", + "generate_python", "import_dirs", + "link_deps", "proto_in_dir", + "proto_out_dir", + "sources", + "testonly", + "visibility", + "deps", + "proto_deps", ]) - remove_configs = [ "//build/config/compiler:chromium_code" ] - extra_configs = [ - "//build/config/compiler:no_chromium_code", - "//third_party/grpc:grpc_config", - ] - generate_python = false + + if (defined(invoker.use_protobuf_full)) { + use_protobuf_full = invoker.use_protobuf_full + } else { + cc_generator_options = "lite" + } + + extra_configs = ["//third_party/grpc:grpc_config"] + + generate_cc = true + generator_plugin_label = "//third_party/grpc:grpc_cpp_plugin" generator_plugin_suffix = ".grpc.pb" } - - # This group forces caller to depend on grpcpp, which is required when using - # the compiled gRPC library. - group(target_name) { - public_deps = [ - ":${proto_library_name}", - "//third_party/grpc:grpcpp", - ] - } }
diff --git a/third_party/grpc/grpc_shared_lib.map b/third_party/grpc/grpc_shared_lib.map new file mode 100644 index 0000000..1d51a2e6 --- /dev/null +++ b/third_party/grpc/grpc_shared_lib.map
@@ -0,0 +1,12 @@ +{ + global: + gpr_*; + extern "C++" { + grpc::*; + grpc_*; + tsi_*; + vtable*grpc::*; + }; + local: + *; +};
diff --git a/third_party/grpc/plugin_registry/grpc_plugin_registry.cc b/third_party/grpc/plugin_registry/grpc_plugin_registry.cc new file mode 100644 index 0000000..e6a8fa5 --- /dev/null +++ b/third_party/grpc/plugin_registry/grpc_plugin_registry.cc
@@ -0,0 +1,130 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/grpc.h> +#include <grpc/support/port_platform.h> + +void grpc_http_filters_init(void); +void grpc_http_filters_shutdown(void); +void grpc_chttp2_plugin_init(void); +void grpc_chttp2_plugin_shutdown(void); +void grpc_deadline_filter_init(void); +void grpc_deadline_filter_shutdown(void); +void grpc_client_channel_init(void); +void grpc_client_channel_shutdown(void); +void grpc_inproc_plugin_init(void); +void grpc_inproc_plugin_shutdown(void); +void grpc_resolver_fake_init(void); +void grpc_resolver_fake_shutdown(void); +void grpc_lb_policy_grpclb_init(void); +void grpc_lb_policy_grpclb_shutdown(void); +void grpc_lb_policy_priority_init(void); +void grpc_lb_policy_priority_shutdown(void); +void grpc_lb_policy_weighted_target_init(void); +void grpc_lb_policy_weighted_target_shutdown(void); +void grpc_lb_policy_pick_first_init(void); +void grpc_lb_policy_pick_first_shutdown(void); +void grpc_lb_policy_round_robin_init(void); +void grpc_lb_policy_round_robin_shutdown(void); +void grpc_resolver_dns_ares_init(void); +void grpc_resolver_dns_ares_shutdown(void); +void grpc_resolver_dns_native_init(void); +void grpc_resolver_dns_native_shutdown(void); +void grpc_resolver_sockaddr_init(void); +void grpc_resolver_sockaddr_shutdown(void); +void grpc_client_idle_filter_init(void); +void grpc_client_idle_filter_shutdown(void); +void grpc_max_age_filter_init(void); +void grpc_max_age_filter_shutdown(void); +void grpc_message_size_filter_init(void); +void grpc_message_size_filter_shutdown(void); +void grpc_service_config_channel_arg_filter_init(void); +void grpc_service_config_channel_arg_filter_shutdown(void); +void grpc_client_authority_filter_init(void); +void grpc_client_authority_filter_shutdown(void); +void grpc_workaround_cronet_compression_filter_init(void); +void grpc_workaround_cronet_compression_filter_shutdown(void); + +#ifndef GRPC_NO_XDS +namespace grpc_core { +void XdsClientGlobalInit(); +void XdsClientGlobalShutdown(); +} // namespace grpc_core +void grpc_certificate_provider_registry_init(void); +void grpc_certificate_provider_registry_shutdown(void); +void grpc_lb_policy_cds_init(void); +void grpc_lb_policy_cds_shutdown(void); +void grpc_lb_policy_eds_init(void); +void grpc_lb_policy_eds_shutdown(void); +void grpc_lb_policy_xds_cluster_impl_init(void); +void grpc_lb_policy_xds_cluster_impl_shutdown(void); +void grpc_lb_policy_xds_cluster_manager_init(void); +void grpc_lb_policy_xds_cluster_manager_shutdown(void); +void grpc_resolver_xds_init(void); +void grpc_resolver_xds_shutdown(void); +#endif + +void grpc_register_built_in_plugins(void) { + grpc_register_plugin(grpc_http_filters_init, grpc_http_filters_shutdown); + grpc_register_plugin(grpc_chttp2_plugin_init, grpc_chttp2_plugin_shutdown); + grpc_register_plugin(grpc_deadline_filter_init, + grpc_deadline_filter_shutdown); + grpc_register_plugin(grpc_client_channel_init, grpc_client_channel_shutdown); + grpc_register_plugin(grpc_inproc_plugin_init, grpc_inproc_plugin_shutdown); + grpc_register_plugin(grpc_resolver_fake_init, grpc_resolver_fake_shutdown); + // grpc_register_plugin(grpc_lb_policy_grpclb_init, + // grpc_lb_policy_grpclb_shutdown); + // grpc_register_plugin(grpc_lb_policy_priority_init, + // grpc_lb_policy_priority_shutdown); + // grpc_register_plugin(grpc_lb_policy_weighted_target_init, + // grpc_lb_policy_weighted_target_shutdown); + grpc_register_plugin(grpc_lb_policy_pick_first_init, + grpc_lb_policy_pick_first_shutdown); + // grpc_register_plugin(grpc_lb_policy_round_robin_init, + // grpc_lb_policy_round_robin_shutdown); + grpc_register_plugin(grpc_resolver_dns_ares_init, + grpc_resolver_dns_ares_shutdown); + grpc_register_plugin(grpc_resolver_dns_native_init, + grpc_resolver_dns_native_shutdown); + grpc_register_plugin(grpc_resolver_sockaddr_init, + grpc_resolver_sockaddr_shutdown); + grpc_register_plugin(grpc_client_idle_filter_init, + grpc_client_idle_filter_shutdown); + grpc_register_plugin(grpc_max_age_filter_init, grpc_max_age_filter_shutdown); + grpc_register_plugin(grpc_message_size_filter_init, + grpc_message_size_filter_shutdown); + grpc_register_plugin(grpc_service_config_channel_arg_filter_init, + grpc_service_config_channel_arg_filter_shutdown); + grpc_register_plugin(grpc_client_authority_filter_init, + grpc_client_authority_filter_shutdown); + grpc_register_plugin(grpc_workaround_cronet_compression_filter_init, + grpc_workaround_cronet_compression_filter_shutdown); +#ifndef GRPC_NO_XDS + grpc_register_plugin(grpc_core::XdsClientGlobalInit, + grpc_core::XdsClientGlobalShutdown); + grpc_register_plugin(grpc_certificate_provider_registry_init, + grpc_certificate_provider_registry_shutdown); + grpc_register_plugin(grpc_lb_policy_cds_init, grpc_lb_policy_cds_shutdown); + grpc_register_plugin(grpc_lb_policy_eds_init, grpc_lb_policy_eds_shutdown); + grpc_register_plugin(grpc_lb_policy_xds_cluster_impl_init, + grpc_lb_policy_xds_cluster_impl_shutdown); + grpc_register_plugin(grpc_lb_policy_xds_cluster_manager_init, + grpc_lb_policy_xds_cluster_manager_shutdown); + grpc_register_plugin(grpc_resolver_xds_init, grpc_resolver_xds_shutdown); +#endif +}
diff --git a/third_party/grpc/template/BUILD.chromium.gn.template b/third_party/grpc/template/BUILD.chromium.gn.template new file mode 100644 index 0000000..3d3523551e --- /dev/null +++ b/third_party/grpc/template/BUILD.chromium.gn.template
@@ -0,0 +1,497 @@ +%YAML 1.2 +--- | + <%doc> + Header piece + </%doc>\ + # GRPC Chromium GN build file + + # This file has been automatically generated from a template file. + # Please look at the templates directory instead. + # See //third_party/grpc/README.chromium for more information. + + declare_args() { + # Compiles with ares. + enable_grpc_ares = false + } + + if (is_android) { + import("//build/config/android/config.gni") + } + + config("grpc_config") { + include_dirs = [ + "src/include", + "src", + "src/src/core/ext/upb-generated", + "src/src/core/ext/upbdefs-generated", + "src/third_party/cares", + "//third_party/cares", + "src/third_party/upb", + "//third_party/abseil-cpp", + ] + + defines = [ + "GRPC_USE_PROTO_LITE", + "HAVE_CONFIG_H", + "PB_FIELD_16BIT", + "GRPC_NO_XDS", + ] + + cflags = [ + "-Wno-implicit-fallthrough", + ] + + if (is_android) { + libs = [ "log" ] # For __android_log_write + } + + if (is_android) { + include_dirs += [ "src/third_party/cares/config_android" ] + } else if (is_fuchsia) { + include_dirs += [ "third_party/cares/config_fuchsia" ] + } else { + include_dirs += [ "src/third_party/cares/config_linux" ] + } + + if (is_fuchsia) { + defines += [ + # Allows zircon sockets to use file descriptors with gRPC. + "GPR_SUPPORT_CHANNELS_FROM_FD", + ] + } + + if (!enable_grpc_ares) { + defines += [ + # Disable c-ares since it doesn't currently support Fuchsia + "GRPC_ARES=0", + ] + } + } + + config("grpc_config_private") { + cflags = [ + "-Wno-implicit-fallthrough", + "-std=c99", + "-Wno-sign-compare", + "-Wno-unreachable-code", + "-Wno-extra-semi", + "-Wno-macro-redefined", + "-Wno-ignored-qualifiers", + "-Wno-string-concatenation", + ] + } + + template("grpc_so") { + # TODO(169395837): Somehow gRPC symbols cannot be found on Android. + # Keep using static linking for now. + if (is_android) { + source_set(target_name) { + forward_variables_from(invoker, "*") + } + } else { + shared_library(target_name) { + forward_variables_from(invoker, "*") + inputs = [ "./grpc_shared_lib.map" ] + ldflags = [ "-Wl,--version-script=" + rebase_path("./grpc_shared_lib.map", root_build_dir) ] + } + } + } + <%doc> + Python convenience functions. + </%doc> + <%! + import os + import re + import glob + + # Sort list of sources or dependencies in a GN target. + def gn_sort(l): + new_l = [] + l = set(l) + for i in l: + if i.startswith(':'): + new_l.append('1_{}'.format(i)) + elif i.startswith('//'): + new_l.append('3_{}'.format(i)) + else: + new_l.append('2_{}'.format(i)) + new_l.sort() + return [i[2:] for i in new_l] + + # Find repeated basenames to avoid conflicts in GN. + def find_repeated(sources): + out_sources = [] + repeated = [] + basenames = set() + for s in sources: + basename = os.path.basename(s) + ext = os.path.splitext(basename) + if (len(ext) > 1) and (ext[1] == '.h') and not re.search('ext/upb', s): + out_sources.append(s) + continue + if basename in basenames: + repeated.append(s) + else: + basenames.add(basename) + out_sources.append(s) + return (gn_sort(out_sources), gn_sort(repeated)) + + # Add comments for some files. + def get_commented_sources(sources): + out_sources = [] + for s in sources: + if s=='src/src/core/lib/gpr/wrap_memcpy.cc': + out_sources.append('# gRPC memcpy wrapping logic isn\'t useful here.') + out_sources.append('# See https://crbug.com/661171') + out_sources.append('# "{}",'.format(s)) + elif s=='src/src/core/plugin_registry/grpc_plugin_registry.cc': + out_sources.append('# Disabling some default plugins.') + out_sources.append('# "{}",'.format(s)) + out_sources.append('"plugin_registry/grpc_plugin_registry.cc",') + else: + out_sources.append('"{}",'.format(s)) + return out_sources + + # Get dependencies for a target. + def get_deps_from_target(target_dict): + deps = set() + if target_dict.get("secure", False): + deps.add("//third_party/boringssl") + if target_dict.get("build", None) == "protoc": + deps.add("//third_party/protobuf:protoc_lib") + name = target_dict.get("name", None) + if name in ("grpc++", "grpc++_codegen_lib"): + deps.add("//third_party/protobuf:protobuf_lite") + elif name in ("grpc", "grpc_unsecure"): + deps.add("//third_party/zlib") + add_absl = False + for d in target_dict.get("deps", []): + if d.startswith('absl'): + add_absl = True + elif d.startswith(("//", ":")): + deps.add(d) + else: + deps.add(":%s" % d) + if add_absl: + deps.add("//third_party/abseil-cpp:absl") + return list(deps) + + # Get dependencies for a list of sources. + def get_deps_from_sources(sources): + deps = set() + if needs_ares(sources): + deps.add(":cares") + deps.add(":address_sorting") + if needs_re(sources): + deps.add("//third_party/re") + return list(deps) + + def needs_re(srcs): + return any("/resolver/xds/" in f for f in srcs) if srcs else False + + def needs_ares(srcs): + return any("/c_ares/" in f for f in srcs) if srcs else False + + def needs_address_sorting(sources): + return needs_ares(sources) or any("address_sorting" in s for s in sources) + + def get_include_dirs(sources): + dirs = [] + if needs_ares(sources): + dirs = [":cares"] + if needs_address_sorting(sources): + dirs.append("src/third_party/address_sorting/include") + return dirs + + def get_extra_stuff(): + extra_stuff = [] + extra_stuff.append('visibility = [ "./*" ]') + extra_stuff.append('if (!is_win) {') + extra_stuff.append(' configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]') + extra_stuff.append(' configs += [ "//build/config/gcc:symbol_visibility_default" ]') + extra_stuff.append('}') + return extra_stuff + + + def strip_sources(sources): + exceptions = [ + "src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h", + "src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc", + "src/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc", + ] + + return [f for f in sources + if "ruby_generator" not in f + and not (re.match("src/src/core/ext/filters/client_channel/lb_policy/.*/.*",f) + and not f in exceptions) + and not re.match("src/src/core/ext/filters/client_channel/resolver/xds/.*",f) + and not re.match("src/src/core/ext/xds/.*",f) ] + + def adjust_srcs(sources): + return ["src/" + f for f in sources] + + def get_sources(target): + sources = ((target.public_headers or []) + + (target.headers or []) + + (target.src or [])) + return adjust_srcs(sources) + + def in_main_lib(lib): + main_libs = ("gpr", "grpc", "grpc++") + return lib.name in main_libs + + def wanted_lib(lib): + wanted_libs = ("grpc_plugin_support", "address_sorting", "upb") + return lib.build in ("all", "protoc") and lib.get("name", "") in wanted_libs + + def wanted_binary(tgt): + wanted_binaries = ("grpc_cpp_plugin",) + return tgt.build == "protoc" and tgt.get("name", "") in wanted_binaries + + def only_on_host_toolchain(tgt): + return tgt.get("name", "") in ("grpc_plugin_support", "grpc_cpp_plugin") + + def find_sources(path): + sources = [] + for (root, ds, fs) in os.walk(path): + for f in fs: + ext = os.path.splitext(f) + if (len(ext) > 1) and (ext[1] in ('.h', '.c')): + sources.append(os.path.join(root, f)) + return ["src/" + s for s in sources] + + cares_sources = glob.glob('third_party/cares/cares/*.h')+ \ + glob.glob('third_party/cares/cares/*.c') + cares_sources = gn_sort(["//third_party/cares/" + os.path.basename(s) for s in cares_sources]) + cares_sources = [s for s in cares_sources if s not in ( + '//third_party/cares/ahost.c', + '//third_party/cares/adig.c', + '//third_party/cares/acountry.c')] + + %>\ + <%doc> + Body of GN file + </%doc>\ + ${cc_main_library(libs)} + % for lib in libs: + % if wanted_lib(lib): + % if only_on_host_toolchain(lib): + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + ${cc_library(lib, " ", True)} + } + % else: + ${cc_library(lib, "", False)} + % endif + % endif + % endfor + % for tgt in targets: + % if wanted_binary(tgt): + % if only_on_host_toolchain(tgt): + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) {${cc_binary(tgt, " ")}} + % else: + ${cc_binary(tgt, "")} + % endif + % endif + % endfor + <%doc> + Template Functions + </%doc>\ + <%def name="cc_main_library(libs)">\ + <% + extra_configs = [':grpc_config_private'] + sources = [] + headers = [] + deps = [] + upb_sources = [] + for lib in libs: + if lib.name == 'upb': + upb_sources = get_sources(lib) + for lib in libs: + if in_main_lib(lib): + if lib.src: + sources += lib.src + if lib.headers: + headers += lib.headers + if lib.public_headers: + headers += lib.public_headers + deps += get_deps_from_target(lib) + headers = adjust_srcs(headers) + headers = [f for f in headers if f not in upb_sources] + headers = strip_sources(headers) + sources = adjust_srcs(sources) + sources = [f for f in sources if f not in upb_sources] + sources = strip_sources(sources) + (sources, repeated) = find_repeated(sources) + deps = [d for d in deps if d not in (':gpr', ':grpc')] + cc_lib_name = 'grpc++_cc' + h_lib_name = 'grpc++_h' + repeated_lib_name = 'grpc++_repeated' + other_deps = deps[:] + other_deps.append(":{}".format(h_lib_name)) + deps_so = [ + ':{}'.format(cc_lib_name), + ':{}'.format(repeated_lib_name), + ] + public_deps_so = [ + ':{}'.format(h_lib_name), + ] + extra_stuff = get_extra_stuff() + %>\ + grpc_so("grpc++") { + deps = [ + % for dep in deps_so: + "${dep}", + % endfor + ] + public_deps = [ + % for dep in public_deps_so: + "${dep}", + % endfor + ] + } + # There are some .cc files that are in multiple places. GN doesn't like + # that. Moving them to another target. + ${cc_library_internal(h_lib_name, '', headers, deps, extra_stuff, extra_configs)} + + ${cc_library_internal(cc_lib_name, '', sources, other_deps, extra_stuff, extra_configs)} + + ${cc_library_internal(repeated_lib_name, '', repeated, other_deps, extra_stuff, extra_configs)} + </%def>\ + <%def name="cc_library(lib, indent, is_host)">\ + <% + sources = get_sources(lib) + sources = strip_sources(sources) + repeated_lib_name = "{}_repeated".format(lib.name) + (sources, repeated) = find_repeated(sources) + extra_configs = [':grpc_config_private'] + extra_stuff = [] + target_type = 'source_set' + if not is_host: + extra_stuff = get_extra_stuff() + deps = get_deps_from_target(lib) + repeated_deps = deps[:] + if repeated: + deps.append(":{}".format(repeated_lib_name)) + %>\ + ${cc_library_internal(lib.name, indent, sources, deps, extra_stuff, [])} + % if repeated: + + # There are some .cc files that are in multiple places. GN doesn't like + # that. Moving them to another target. + ${cc_library_internal(repeated_lib_name, indent, repeated, repeated_deps, extra_stuff, [])} + % endif + </%def>\ + <%def name="cc_library_internal(name, indent, sources, lib_deps, extra_stuff, extra_configs)">\ + <% + include_dirs = get_include_dirs(sources) + lib_deps += get_deps_from_sources(sources) + lib_deps = gn_sort(lib_deps) + sources = gn_sort(sources) + sources = get_commented_sources(sources) + %>\ + ${indent}source_set("${name}") { + % if sources: + ${indent} sources = [ + % for src in sources: + ${indent} ${src} + % endfor + ${indent} ] + % endif + % if lib_deps: + + ${indent} deps = [ + % for dep in lib_deps: + ${indent} "${dep}", + % endfor + ${indent} ] + % endif + ${indent} public_configs = [ + ${indent} ":grpc_config", + ${indent} ] + % if extra_configs: + ${indent} configs += [ + % for config in extra_configs: + ${indent} "${config}", + % endfor + ${indent} ] + % endif + % if include_dirs: + ${indent} include_dirs = [ + % for d in include_dirs: + ${indent} "${d}", + % endfor + ${indent} ] + % endif + % if extra_stuff: + % for e in extra_stuff: + ${indent} ${e} + % endfor + % endif + ${indent}}\ + </%def> + <%def name="cc_binary(tgt, indent)">\ + <% + sources = ["src/"+s for s in tgt.src] + sources = gn_sort(sources) + deps = get_deps_from_target(tgt) + get_deps_from_sources(sources) + deps = gn_sort(deps) + %> + ${indent}executable("${tgt.name}") { + ${indent} sources = [ + % for src in sources: + ${indent} "${src}", + % endfor + ${indent} ] + ${indent} deps = [ + % for dep in deps: + ${indent} "${dep}", + % endfor + ${indent} ] + ${indent} configs += [ + ${indent} "//third_party/protobuf:protobuf_config", + ${indent} ] + ${indent} public_configs = [ ":grpc_config" ] + ${indent}} + </%def><%! + %>\ + <%doc> + Manual targets + </%doc>\ + config("cares_config") { + cflags = [ + "-Wno-macro-redefined", + "-Wno-unused-variable", + ] + } + + source_set("cares") { + sources = [ + "src/third_party/cares/ares_build.h", + ] + + if (enable_grpc_ares) { + sources += [ + % for src in cares_sources: + "${src}", + % endfor + ] + } + + if (is_android) { + sources += [ "src/third_party/cares/config_android/ares_config.h" ] + configs += [ ":cares_config" ] + } else if (is_fuchsia) { + sources += [ "third_party/cares/config_fuchsia/ares_config.h" ] + } else { + sources += [ "src/third_party/cares/config_linux/ares_config.h" ] + } + deps = [ + "//third_party/boringssl", + ] + + public_configs = [ ":grpc_config" ] + } + + group("fuzzers") {}
diff --git a/third_party/grpc/third_party/cares/config_fuchsia/ares_config.h b/third_party/grpc/third_party/cares/config_fuchsia/ares_config.h new file mode 100644 index 0000000..f8fe094b --- /dev/null +++ b/third_party/grpc/third_party/cares/config_fuchsia/ares_config.h
@@ -0,0 +1,513 @@ +/* ares_config.h. Generated from ares_config.h.in by configure. */ +/* ares_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* define this if ares is built for a big endian system */ +/* #undef ARES_BIG_ENDIAN */ + +/* when building as static part of libcurl */ +/* #undef BUILDING_LIBCURL */ + +/* Defined for build that exposes internal static functions for testing. */ +/* #undef CARES_EXPOSE_STATICS */ + +/* Defined for build with symbol hiding. */ +#define CARES_SYMBOL_HIDING 1 + +/* Definition to make a library symbol externally visible. */ +#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((__visibility__ ("default"))) + +/* the signed version of size_t */ +#define CARES_TYPEOF_ARES_SSIZE_T ssize_t + +/* Use resolver library to configure cares */ +/* #undef CARES_USE_LIBRESOLV */ + +/* if a /etc/inet dir is being used */ +/* #undef ETC_INET */ + +/* Define to the type of arg 2 for gethostname. */ +#define GETHOSTNAME_TYPE_ARG2 size_t + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 const + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 socklen_t + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 socklen_t + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 int + +/* Specifies the number of arguments to getservbyport_r */ +#define GETSERVBYPORT_R_ARGS 6 + +/* Specifies the size of the buffer to pass to getservbyport_r */ +#define GETSERVBYPORT_R_BUFSIZE 4096 + +/* Define to 1 if you have AF_INET6. */ +#define HAVE_AF_INET6 1 + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */ +#define HAVE_ARPA_NAMESER_COMPAT_H 1 + +/* Define to 1 if you have the <arpa/nameser.h> header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define to 1 if you have the <assert.h> header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `bitncmp' function. */ +/* #undef HAVE_BITNCMP */ + +/* Define to 1 if bool is an available type. */ +#define HAVE_BOOL_T 1 + +/* Define to 1 if you have the clock_gettime function and monotonic timer. */ +#define HAVE_CLOCK_GETTIME_MONOTONIC 1 + +/* Define to 1 if you have the closesocket function. */ +/* #undef HAVE_CLOSESOCKET */ + +/* Define to 1 if you have the CloseSocket camel case function. */ +/* #undef HAVE_CLOSESOCKET_CAMEL */ + +/* Define to 1 if you have the connect function. */ +#define HAVE_CONNECT 1 + +/* define if the compiler supports basic C++11 syntax */ +#define HAVE_CXX11 1 + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the <errno.h> header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#define HAVE_FCNTL_O_NONBLOCK 1 + +/* Define to 1 if you have the freeaddrinfo function. */ +#define HAVE_FREEADDRINFO 1 + +/* Define to 1 if you have a working getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if the getaddrinfo function is threadsafe. */ +#define HAVE_GETADDRINFO_THREADSAFE 1 + +/* Define to 1 if you have the getenv function. */ +#define HAVE_GETENV 1 + +/* Define to 1 if you have the gethostbyaddr function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* Define to 1 if you have the gethostbyname function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define to 1 if you have the getnameinfo function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the getservbyport_r function. */ +#define HAVE_GETSERVBYPORT_R 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `if_indextoname' function. */ +#define HAVE_IF_INDEXTONAME 1 + +/* Define to 1 if you have a IPv6 capable working inet_net_pton function. */ +/* #undef HAVE_INET_NET_PTON */ + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +#define HAVE_INET_NTOP 1 + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +#define HAVE_INET_PTON 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the ioctl function. */ +#define HAVE_IOCTL 1 + +/* Define to 1 if you have the ioctlsocket function. */ +/* #undef HAVE_IOCTLSOCKET */ + +/* Define to 1 if you have the IoctlSocket camel case function. */ +/* #undef HAVE_IOCTLSOCKET_CAMEL */ + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. + */ +/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +/* #undef HAVE_IOCTLSOCKET_FIONBIO */ + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#define HAVE_IOCTL_FIONBIO 1 + +/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ +#define HAVE_IOCTL_SIOCGIFADDR 1 + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +/* #undef HAVE_LIBRESOLVE */ + +/* Define to 1 if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* if your compiler supports LL */ +#define HAVE_LL 1 + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#define HAVE_LONGLONG 1 + +/* Define to 1 if you have the malloc.h header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the memory.h header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the MSG_NOSIGNAL flag. */ +/* #undef HAVE_MSG_NOSIGNAL 1 */ + +/* Define to 1 if you have the <netdb.h> header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the <netinet/tcp.h> header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the <net/if.h> header file. */ +#define HAVE_NET_IF_H 1 + +/* Define to 1 if you have PF_INET6. */ +#define HAVE_PF_INET6 1 + +/* Define to 1 if you have the recv function. */ +#define HAVE_RECV 1 + +/* Define to 1 if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 + +/* Define to 1 if you have the send function. */ +#define HAVE_SEND 1 + +/* Define to 1 if you have the setsockopt function. */ +#define HAVE_SETSOCKOPT 1 + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ + +/* Define to 1 if you have the <signal.h> header file. */ +#define HAVE_SIGNAL_H 0 + +/* Define to 1 if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T 1 + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ + +/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* Define to 1 if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the <socket.h> header file. */ +/* #undef HAVE_SOCKET_H */ + +/* Define to 1 if you have the <stdbool.h> header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the strcmpi function. */ +/* #undef HAVE_STRCMPI */ + +/* Define to 1 if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the stricmp function. */ +/* #undef HAVE_STRICMP */ + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the strncasecmp function. */ +#define HAVE_STRNCASECMP 1 + +/* Define to 1 if you have the strncmpi function. */ +/* #undef HAVE_STRNCMPI */ + +/* Define to 1 if you have the strnicmp function. */ +/* #undef HAVE_STRNICMP */ + +/* Define to 1 if you have the <stropts.h> header file. */ +#define HAVE_STROPTS_H 1 + +/* Define to 1 if you have struct addrinfo. */ +#define HAVE_STRUCT_ADDRINFO 1 + +/* Define to 1 if you have struct in6_addr. */ +#define HAVE_STRUCT_IN6_ADDR 1 + +/* Define to 1 if you have struct sockaddr_in6. */ +#define HAVE_STRUCT_SOCKADDR_IN6 1 + +/* if struct sockaddr_storage is defined */ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if you have the timeval struct. */ +#define HAVE_STRUCT_TIMEVAL 1 + +/* Define to 1 if you have the <sys/ioctl.h> header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the <sys/param.h> header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the <sys/select.h> header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <sys/uio.h> header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the <time.h> header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the windows.h header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the winsock2.h header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if you have the winsock.h header file. */ +/* #undef HAVE_WINSOCK_H */ + +/* Define to 1 if you have the writev function. */ +#define HAVE_WRITEV 1 + +/* Define to 1 if you have the ws2tcpip.h header file. */ +/* #undef HAVE_WS2TCPIP_H */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +/* #undef NEED_MALLOC_H */ + +/* Define to 1 if you need the memory.h header file even with stdlib.h */ +/* #undef NEED_MEMORY_H */ + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +/* #undef NEED_REENTRANT */ + +/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ +/* #undef NEED_THREAD_SAFE */ + +/* cpu-machine-OS */ +#if defined(__Fuchsia__) +#if defined(__aarch64__) +#define OS "aarch64-unknown-fuchsia" +#elif defined(__x86_64__) +#define OS "x86_64-unknown-fuchsia" +#else +#error Unsupported architecture +#endif +#else +#error Unsupported OS +#endif + +/* Name of package */ +#define PACKAGE "c-ares" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "c-ares" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "c-ares -" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "c-ares" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "-" + +/* a suitable file/device to read random data from */ +#define RANDOM_FILE "/dev/urandom" + +/* Define to the type qualifier pointed by arg 5 for recvfrom. */ +#define RECVFROM_QUAL_ARG5 + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 int + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 void + +/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ +#define RECVFROM_TYPE_ARG2_IS_VOID 1 + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 int + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 struct sockaddr + +/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ +/* #undef RECVFROM_TYPE_ARG5_IS_VOID */ + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 socklen_t + +/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ +/* #undef RECVFROM_TYPE_ARG6_IS_VOID */ + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV ssize_t + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 int + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 void * + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV ssize_t + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 const + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 int + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 void * + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 int + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV ssize_t + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to disable non-blocking sockets. */ +/* #undef USE_BLOCKING_SOCKETS */ + +/* Version number of package */ +#define VERSION "-" + +/* Define to avoid automatic inclusion of winsock.h */ +/* #undef WIN32_LEAN_AND_MEAN */ + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define to 1 if OS is AIX. */ +#ifndef _ALL_SOURCE +/* # undef _ALL_SOURCE */ +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Type to use in place of in_addr_t when system does not provide it. */ +/* #undef in_addr_t */ + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +/* #undef size_t */
diff --git a/third_party/neon_2_sse/BUILD.gn b/third_party/neon_2_sse/BUILD.gn new file mode 100644 index 0000000..3700dc4 --- /dev/null +++ b/third_party/neon_2_sse/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("neon_2_sse_include") { + include_dirs = [ "src" ] +} + +source_set("neon_2_sse") { + public = [ "src/NEON_2_SSE.h" ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + + public_configs = [ ":neon_2_sse_include" ] +}
diff --git a/third_party/neon_2_sse/LICENSE b/third_party/neon_2_sse/LICENSE new file mode 100644 index 0000000..d04faef --- /dev/null +++ b/third_party/neon_2_sse/LICENSE
@@ -0,0 +1,29 @@ +created by Victoria Zhislina, the Senior Application Engineer, Intel Corporation, victoria.zhislina@intel.com + +*** Copyright (C) 2012-2020 Intel Corporation. All rights reserved. + +IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + +By downloading, copying, installing or using the software you agree to this license. +If you do not agree to this license, do not download, install, copy or use the software. + + License Agreement +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. + + * The name of the copyright holders may not 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 Intel Corporation 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.
diff --git a/third_party/neon_2_sse/OWNERS b/third_party/neon_2_sse/OWNERS new file mode 100644 index 0000000..f14a8b97 --- /dev/null +++ b/third_party/neon_2_sse/OWNERS
@@ -0,0 +1,4 @@ +mcrouse@chromium.org +sophiechang@chromium.org +tbansal@chromium.org +# COMPONENT: Internals>OptimizationGuide
diff --git a/third_party/neon_2_sse/README.chromium b/third_party/neon_2_sse/README.chromium new file mode 100644 index 0000000..55b19cbe --- /dev/null +++ b/third_party/neon_2_sse/README.chromium
@@ -0,0 +1,18 @@ +Name: ARM_NEON_2_x86_SSE +Short Name: neon_2_sse +URL: https://github.com/intel/ARM_NEON_2_x86_SSE +Version: 42b2bebacee25452e150095ef4480b3fa26e30f5 +Date: 2020/06/22 +License: Custom +License File: LICENSE +Security Critical: Yes +License Android Compatible: Yes + +Description: +The NEON_2_SSE.h file is intended to simplify ARM->IA32 porting. It makes the +correspondence (or a real porting) of ARM NEON intrinsics as defined in +"arm_neon.h" header and x86 SSE (up to SSE4.2) intrinsic functions as defined +in corresponding x86 compilers headers files. + +Local Modifications: +- Included only the NEON_2_SSE.h file.
diff --git a/third_party/ruy/BUILD.gn b/third_party/ruy/BUILD.gn new file mode 100644 index 0000000..53d2914 --- /dev/null +++ b/third_party/ruy/BUILD.gn
@@ -0,0 +1,96 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config("ruy_includes") { + include_dirs = [ "src" ] +} + +source_set("ruy") { + sources = [ + "src/ruy/allocator.cc", + "src/ruy/allocator.h", + "src/ruy/apply_multiplier.cc", + "src/ruy/apply_multiplier.h", + "src/ruy/block_map.cc", + "src/ruy/block_map.h", + "src/ruy/blocking_counter.cc", + "src/ruy/blocking_counter.h", + "src/ruy/check_macros.h", + "src/ruy/common.h", + "src/ruy/context.cc", + "src/ruy/context.h", + "src/ruy/context_get_ctx.cc", + "src/ruy/context_get_ctx.h", + "src/ruy/cpu_cache_params.h", + "src/ruy/cpuinfo.cc", + "src/ruy/cpuinfo.h", + "src/ruy/create_trmul_params.cc", + "src/ruy/create_trmul_params.h", + "src/ruy/ctx.cc", + "src/ruy/ctx.h", + "src/ruy/ctx_impl.h", + "src/ruy/dispatch.h", + "src/ruy/have_built_path_for.h", + "src/ruy/have_built_path_for_avx2.cc", + "src/ruy/have_built_path_for_avx512.cc", + "src/ruy/have_built_path_for_avxvnni.cc", + "src/ruy/have_built_path_for_sse42.cc", + "src/ruy/kernel.h", + "src/ruy/kernel_arm.h", + "src/ruy/kernel_arm32.cc", + "src/ruy/kernel_arm64.cc", + "src/ruy/kernel_avx2.cc", + "src/ruy/kernel_avx512.cc", + "src/ruy/kernel_avxvnni.cc", + "src/ruy/kernel_common.h", + "src/ruy/kernel_sse42.cc", + "src/ruy/kernel_x86.h", + "src/ruy/mat.h", + "src/ruy/matrix.h", + "src/ruy/mul_params.h", + "src/ruy/opt_set.h", + "src/ruy/pack.h", + "src/ruy/pack_arm.cc", + "src/ruy/pack_arm.h", + "src/ruy/pack_avx2.cc", + "src/ruy/pack_avx512.cc", + "src/ruy/pack_avxvnni.cc", + "src/ruy/pack_common.h", + "src/ruy/pack_sse42.cc", + "src/ruy/pack_x86.h", + "src/ruy/path.h", + "src/ruy/platform.h", + "src/ruy/pmu.cc", + "src/ruy/pmu.h", + "src/ruy/prepacked_cache.cc", + "src/ruy/prepacked_cache.h", + "src/ruy/profiler/instrumentation.cc", + "src/ruy/profiler/instrumentation.h", + "src/ruy/profiler/profiler.cc", + "src/ruy/profiler/profiler.h", + "src/ruy/profiler/treeview.cc", + "src/ruy/profiler/treeview.h", + "src/ruy/reference_mul.h", + "src/ruy/ruy.h", + "src/ruy/side_pair.h", + "src/ruy/size_util.h", + "src/ruy/system_aligned_alloc.cc", + "src/ruy/system_aligned_alloc.h", + "src/ruy/thread_pool.cc", + "src/ruy/thread_pool.h", + "src/ruy/time.h", + "src/ruy/trmul.cc", + "src/ruy/trmul.h", + "src/ruy/trmul_params.h", + "src/ruy/tune.cc", + "src/ruy/tune.h", + "src/ruy/wait.cc", + "src/ruy/wait.h", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + + public_configs = [ ":ruy_includes" ] +}
diff --git a/third_party/ruy/LICENSE b/third_party/ruy/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/third_party/ruy/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/third_party/ruy/OWNERS b/third_party/ruy/OWNERS new file mode 100644 index 0000000..f14a8b97 --- /dev/null +++ b/third_party/ruy/OWNERS
@@ -0,0 +1,4 @@ +mcrouse@chromium.org +sophiechang@chromium.org +tbansal@chromium.org +# COMPONENT: Internals>OptimizationGuide
diff --git a/third_party/ruy/README.chromium b/third_party/ruy/README.chromium new file mode 100644 index 0000000..96f7eb1 --- /dev/null +++ b/third_party/ruy/README.chromium
@@ -0,0 +1,17 @@ +Name: The ruy matrix multiplication library +Short Name: ruy +URL: https://github.com/google/ruy +Version: 34ea9f4993955fa1ff4eb58e504421806b7f2e8f +Date: 2020/06/11 +License: Apache 2 +License File: LICENSE +Security Critical: Yes +CPEPrefix: unknown + +Description: +ruy is a matrix multiplication library. Its focus is to cover the matrix +multiplication needs of neural network inference engines. Its initial user +has been TensorFlow Lite, where it is used by default on the ARM CPU +architecture. + +ruy supports both floating-point and 8bit-integer-quantized matrices.
diff --git a/third_party/tflite/BUILD.gn b/third_party/tflite/BUILD.gn new file mode 100644 index 0000000..be87702 --- /dev/null +++ b/third_party/tflite/BUILD.gn
@@ -0,0 +1,479 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/sanitizers/sanitizers.gni") + +config("tflite_config") { + include_dirs = [ "src" ] +} + +config("tflite_flags") { + cflags = [ + "-Wno-comment", + "-Wno-extern-c-compat", + + # TODO(crbug.com/1147556): Try to clean/remove no-sign-compare if possible. + "-Wno-sign-compare", + ] + + defines = [ + "TFLITE_WITHOUT_XNNPACK", + "FARMHASH_NO_CXX_STRING", + ] + + if (is_win) { + cflags += [ + "/DTFL_COMPILE_LIBRARY", + "/wd4018", + ] + } + + if (is_android) { + defines += [ "TFLITE_WITH_RUY" ] + } + + if (is_linux) { + defines += [ "GEMMLOWP_ALLOW_SLOW_SCALAR_FALLBACK" ] + } +} + +source_set("tflite_public_headers") { + public = [ + "src/tensorflow/lite/allocation.h", + "src/tensorflow/lite/arena_planner.h", + "src/tensorflow/lite/c/builtin_op_data.h", + "src/tensorflow/lite/c/c_api.h", + "src/tensorflow/lite/c/c_api_experimental.h", + "src/tensorflow/lite/c/common.h", + "src/tensorflow/lite/context.h", + "src/tensorflow/lite/context_util.h", + "src/tensorflow/lite/core/macros.h", + "src/tensorflow/lite/core/subgraph.h", + "src/tensorflow/lite/error_reporter.h", + "src/tensorflow/lite/graph_info.h", + "src/tensorflow/lite/interpreter.h", + "src/tensorflow/lite/interpreter_builder.h", + "src/tensorflow/lite/kernels/register.h", + "src/tensorflow/lite/model.h", + "src/tensorflow/lite/model_builder.h", + "src/tensorflow/lite/mutable_op_resolver.h", + "src/tensorflow/lite/op_resolver.h", + "src/tensorflow/lite/optional_debug_tools.h", + "src/tensorflow/lite/schema/schema_generated.h", + "src/tensorflow/lite/stderr_reporter.h", + "src/tensorflow/lite/string_type.h", + "src/tensorflow/lite/string_util.h", + "src/tensorflow/lite/util.h", + ] + + configs += [ ":tflite_flags" ] +} + +source_set("tflite_kernel_common_headers") { + public = [ + "src/tensorflow/lite/experimental/resource/resource_variable.h", + "src/tensorflow/lite/external_cpu_backend_context.h", + "src/tensorflow/lite/kernels/cpu_backend_context.h", + "src/tensorflow/lite/kernels/cpu_backend_gemm.h", + "src/tensorflow/lite/kernels/cpu_backend_gemm_params.h", + "src/tensorflow/lite/kernels/cpu_backend_threadpool.h", + "src/tensorflow/lite/kernels/internal/compatibility.h", + "src/tensorflow/lite/kernels/internal/tensor_ctypes.h", + "src/tensorflow/lite/kernels/op_macros.h", + "src/tensorflow/lite/tools/optimize/sparsity/format_converter.h", + ] + + configs += [ ":tflite_flags" ] + + visibility = [ ":*" ] +} + +source_set("fft2d_deps") { + public = [ + "src/third_party/fft2d/fft.h", + "src/third_party/fft2d/fft2d.h", + ] + + deps = [ "//third_party/fft2d" ] + visibility = [ ":*" ] +} + +source_set("tflite_kernel_internals") { + sources = [ + "src/tensorflow/lite/kernels/internal/common.h", + "src/tensorflow/lite/kernels/internal/cppmath.h", + "src/tensorflow/lite/kernels/internal/kernel_utils.cc", + "src/tensorflow/lite/kernels/internal/kernel_utils.h", + "src/tensorflow/lite/kernels/internal/max.h", + "src/tensorflow/lite/kernels/internal/mfcc.cc", + "src/tensorflow/lite/kernels/internal/mfcc.h", + "src/tensorflow/lite/kernels/internal/mfcc_dct.cc", + "src/tensorflow/lite/kernels/internal/mfcc_dct.h", + "src/tensorflow/lite/kernels/internal/mfcc_mel_filterbank.cc", + "src/tensorflow/lite/kernels/internal/mfcc_mel_filterbank.h", + "src/tensorflow/lite/kernels/internal/min.h", + "src/tensorflow/lite/kernels/internal/optimized/batch_matmul.h", + "src/tensorflow/lite/kernels/internal/optimized/cpu_check.cc", + "src/tensorflow/lite/kernels/internal/optimized/cpu_check.h", + "src/tensorflow/lite/kernels/internal/optimized/depthwiseconv_3x3_filter_common.h", + "src/tensorflow/lite/kernels/internal/optimized/depthwiseconv_float.h", + "src/tensorflow/lite/kernels/internal/optimized/depthwiseconv_multithread.h", + "src/tensorflow/lite/kernels/internal/optimized/depthwiseconv_uint8.h", + "src/tensorflow/lite/kernels/internal/optimized/depthwiseconv_uint8_3x3_filter.h", + "src/tensorflow/lite/kernels/internal/optimized/eigen_spatial_convolutions.h", + "src/tensorflow/lite/kernels/internal/optimized/eigen_tensor_reduced_instantiations_oss.h", + "src/tensorflow/lite/kernels/internal/optimized/im2col_utils.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/add.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/conv.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/depthwise_conv.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/depthwise_conv_3x3_filter.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/depthwise_conv_hybrid.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/depthwise_conv_hybrid_3x3_filter.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/fully_connected.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/mean.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/mul.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/pooling.h", + "src/tensorflow/lite/kernels/internal/optimized/integer_ops/transpose_conv.h", + "src/tensorflow/lite/kernels/internal/optimized/multithreaded_conv.h", + "src/tensorflow/lite/kernels/internal/optimized/neon_check.h", + "src/tensorflow/lite/kernels/internal/optimized/neon_tensor_utils.cc", + "src/tensorflow/lite/kernels/internal/optimized/neon_tensor_utils_impl.h", + "src/tensorflow/lite/kernels/internal/optimized/optimized_ops.h", + "src/tensorflow/lite/kernels/internal/optimized/sparse_ops/fully_connected.h", + "src/tensorflow/lite/kernels/internal/optimized/sse_tensor_utils.cc", + "src/tensorflow/lite/kernels/internal/optimized/sse_tensor_utils_impl.h", + "src/tensorflow/lite/kernels/internal/quantization_util.cc", + "src/tensorflow/lite/kernels/internal/quantization_util.h", + "src/tensorflow/lite/kernels/internal/reference/add.h", + "src/tensorflow/lite/kernels/internal/reference/arg_min_max.h", + "src/tensorflow/lite/kernels/internal/reference/batch_matmul.h", + "src/tensorflow/lite/kernels/internal/reference/binary_function.h", + "src/tensorflow/lite/kernels/internal/reference/ceil.h", + "src/tensorflow/lite/kernels/internal/reference/comparisons.h", + "src/tensorflow/lite/kernels/internal/reference/concatenation.h", + "src/tensorflow/lite/kernels/internal/reference/conv.h", + "src/tensorflow/lite/kernels/internal/reference/densify.h", + "src/tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h", + "src/tensorflow/lite/kernels/internal/reference/depthwiseconv_uint8.h", + "src/tensorflow/lite/kernels/internal/reference/dequantize.h", + "src/tensorflow/lite/kernels/internal/reference/floor.h", + "src/tensorflow/lite/kernels/internal/reference/fully_connected.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/add.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/conv.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/depthwise_conv.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/dequantize.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/fully_connected.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/l2normalization.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/log_softmax.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/logistic.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/mean.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/mul.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/tanh.h", + "src/tensorflow/lite/kernels/internal/reference/integer_ops/transpose_conv.h", + "src/tensorflow/lite/kernels/internal/reference/l2normalization.h", + "src/tensorflow/lite/kernels/internal/reference/logistic.h", + "src/tensorflow/lite/kernels/internal/reference/maximum_minimum.h", + "src/tensorflow/lite/kernels/internal/reference/mul.h", + "src/tensorflow/lite/kernels/internal/reference/neg.h", + "src/tensorflow/lite/kernels/internal/reference/non_max_suppression.h", + "src/tensorflow/lite/kernels/internal/reference/pad.h", + "src/tensorflow/lite/kernels/internal/reference/pooling.h", + "src/tensorflow/lite/kernels/internal/reference/portable_tensor_utils.cc", + "src/tensorflow/lite/kernels/internal/reference/portable_tensor_utils.h", + "src/tensorflow/lite/kernels/internal/reference/portable_tensor_utils_impl.h", + "src/tensorflow/lite/kernels/internal/reference/prelu.h", + "src/tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h", + "src/tensorflow/lite/kernels/internal/reference/quantize.h", + "src/tensorflow/lite/kernels/internal/reference/reduce.h", + "src/tensorflow/lite/kernels/internal/reference/reference_ops.h", + "src/tensorflow/lite/kernels/internal/reference/requantize.h", + "src/tensorflow/lite/kernels/internal/reference/resize_nearest_neighbor.h", + "src/tensorflow/lite/kernels/internal/reference/round.h", + "src/tensorflow/lite/kernels/internal/reference/softmax.h", + "src/tensorflow/lite/kernels/internal/reference/sparse_ops/fully_connected.h", + "src/tensorflow/lite/kernels/internal/reference/strided_slice.h", + "src/tensorflow/lite/kernels/internal/reference/sub.h", + "src/tensorflow/lite/kernels/internal/reference/svdf.h", + "src/tensorflow/lite/kernels/internal/reference/tanh.h", + "src/tensorflow/lite/kernels/internal/spectrogram.cc", + "src/tensorflow/lite/kernels/internal/spectrogram.h", + "src/tensorflow/lite/kernels/internal/strided_slice_logic.h", + "src/tensorflow/lite/kernels/internal/tensor.h", + "src/tensorflow/lite/kernels/internal/tensor_utils.cc", + "src/tensorflow/lite/kernels/internal/tensor_utils.h", + "src/tensorflow/lite/kernels/internal/transpose_utils.cc", + "src/tensorflow/lite/kernels/internal/transpose_utils.h", + "src/tensorflow/lite/kernels/internal/types.h", + ] + + deps = [ + ":fft2d_deps", + ":tflite_kernel_common_headers", + ":tflite_public_headers", + "//third_party/abseil-cpp:absl", + "//third_party/farmhash", + "//third_party/flatbuffers:tflite_deps", + "//third_party/fp16", + "//third_party/gemmlowp", + "//third_party/neon_2_sse", + "//third_party/ruy", + ] + + configs += [ + ":tflite_config", + ":tflite_flags", + "//third_party/eigen3:eigen_includes", + ] + + visibility = [ ":*" ] +} + +source_set("tflite_kernels") { + sources = [ + "src/tensorflow/lite/kernels/activations.cc", + "src/tensorflow/lite/kernels/add.cc", + "src/tensorflow/lite/kernels/add_n.cc", + "src/tensorflow/lite/kernels/arg_min_max.cc", + "src/tensorflow/lite/kernels/assign_variable.cc", + "src/tensorflow/lite/kernels/audio_spectrogram.cc", + "src/tensorflow/lite/kernels/basic_rnn.cc", + "src/tensorflow/lite/kernels/batch_matmul.cc", + "src/tensorflow/lite/kernels/batch_to_space_nd.cc", + "src/tensorflow/lite/kernels/bidirectional_sequence_lstm.cc", + "src/tensorflow/lite/kernels/bidirectional_sequence_rnn.cc", + "src/tensorflow/lite/kernels/builtin_op_kernels.h", + "src/tensorflow/lite/kernels/cast.cc", + "src/tensorflow/lite/kernels/ceil.cc", + "src/tensorflow/lite/kernels/comparisons.cc", + "src/tensorflow/lite/kernels/concatenation.cc", + "src/tensorflow/lite/kernels/conv.cc", + "src/tensorflow/lite/kernels/cpu_backend_context.cc", + "src/tensorflow/lite/kernels/cpu_backend_gemm_custom_gemv.h", + "src/tensorflow/lite/kernels/cpu_backend_gemm_eigen.cc", + "src/tensorflow/lite/kernels/cpu_backend_gemm_eigen.h", + "src/tensorflow/lite/kernels/cpu_backend_gemm_gemmlowp.h", + "src/tensorflow/lite/kernels/cpu_backend_gemm_ruy.h", + "src/tensorflow/lite/kernels/densify.cc", + "src/tensorflow/lite/kernels/depth_to_space.cc", + "src/tensorflow/lite/kernels/depthwise_conv.cc", + "src/tensorflow/lite/kernels/dequantize.cc", + "src/tensorflow/lite/kernels/dequantize.h", + "src/tensorflow/lite/kernels/detection_postprocess.cc", + "src/tensorflow/lite/kernels/div.cc", + "src/tensorflow/lite/kernels/eigen_support.cc", + "src/tensorflow/lite/kernels/eigen_support.h", + "src/tensorflow/lite/kernels/elementwise.cc", + "src/tensorflow/lite/kernels/embedding_lookup.cc", + "src/tensorflow/lite/kernels/embedding_lookup_sparse.cc", + "src/tensorflow/lite/kernels/exp.cc", + "src/tensorflow/lite/kernels/expand_dims.cc", + "src/tensorflow/lite/kernels/fake_quant.cc", + "src/tensorflow/lite/kernels/fill.cc", + "src/tensorflow/lite/kernels/floor.cc", + "src/tensorflow/lite/kernels/floor_div.cc", + "src/tensorflow/lite/kernels/floor_mod.cc", + "src/tensorflow/lite/kernels/fully_connected.cc", + "src/tensorflow/lite/kernels/gather.cc", + "src/tensorflow/lite/kernels/gather_nd.cc", + "src/tensorflow/lite/kernels/hashtable_lookup.cc", + "src/tensorflow/lite/kernels/if.cc", + "src/tensorflow/lite/kernels/kernel_util.cc", + "src/tensorflow/lite/kernels/kernel_util.h", + "src/tensorflow/lite/kernels/l2norm.cc", + "src/tensorflow/lite/kernels/local_response_norm.cc", + "src/tensorflow/lite/kernels/logical.cc", + "src/tensorflow/lite/kernels/lsh_projection.cc", + "src/tensorflow/lite/kernels/lstm.cc", + "src/tensorflow/lite/kernels/lstm_eval.cc", + "src/tensorflow/lite/kernels/lstm_eval.h", + "src/tensorflow/lite/kernels/lstm_shared.h", + "src/tensorflow/lite/kernels/matrix_diag.cc", + "src/tensorflow/lite/kernels/matrix_set_diag.cc", + "src/tensorflow/lite/kernels/maximum_minimum.cc", + "src/tensorflow/lite/kernels/mfcc.cc", + "src/tensorflow/lite/kernels/mirror_pad.cc", + "src/tensorflow/lite/kernels/mul.cc", + "src/tensorflow/lite/kernels/neg.cc", + "src/tensorflow/lite/kernels/non_max_suppression.cc", + "src/tensorflow/lite/kernels/numeric_verify.cc", + "src/tensorflow/lite/kernels/one_hot.cc", + "src/tensorflow/lite/kernels/pack.cc", + "src/tensorflow/lite/kernels/pad.cc", + "src/tensorflow/lite/kernels/padding.h", + "src/tensorflow/lite/kernels/pooling.cc", + "src/tensorflow/lite/kernels/pow.cc", + "src/tensorflow/lite/kernels/quantize.cc", + "src/tensorflow/lite/kernels/range.cc", + "src/tensorflow/lite/kernels/rank.cc", + "src/tensorflow/lite/kernels/read_variable.cc", + "src/tensorflow/lite/kernels/reduce.cc", + "src/tensorflow/lite/kernels/register.cc", + "src/tensorflow/lite/kernels/register_ref.cc", + "src/tensorflow/lite/kernels/register_ref.h", + "src/tensorflow/lite/kernels/reshape.cc", + "src/tensorflow/lite/kernels/resize_bilinear.cc", + "src/tensorflow/lite/kernels/resize_nearest_neighbor.cc", + "src/tensorflow/lite/kernels/reverse.cc", + "src/tensorflow/lite/kernels/reverse_sequence.cc", + "src/tensorflow/lite/kernels/rfft2d.cc", + "src/tensorflow/lite/kernels/round.cc", + "src/tensorflow/lite/kernels/scatter_nd.cc", + "src/tensorflow/lite/kernels/segment_sum.cc", + "src/tensorflow/lite/kernels/select.cc", + "src/tensorflow/lite/kernels/shape.cc", + "src/tensorflow/lite/kernels/skip_gram.cc", + "src/tensorflow/lite/kernels/slice.cc", + "src/tensorflow/lite/kernels/space_to_batch_nd.cc", + "src/tensorflow/lite/kernels/space_to_depth.cc", + "src/tensorflow/lite/kernels/sparse_to_dense.cc", + "src/tensorflow/lite/kernels/split.cc", + "src/tensorflow/lite/kernels/split_v.cc", + "src/tensorflow/lite/kernels/squared_difference.cc", + "src/tensorflow/lite/kernels/squeeze.cc", + "src/tensorflow/lite/kernels/strided_slice.cc", + "src/tensorflow/lite/kernels/sub.cc", + "src/tensorflow/lite/kernels/svdf.cc", + "src/tensorflow/lite/kernels/tile.cc", + "src/tensorflow/lite/kernels/topk_v2.cc", + "src/tensorflow/lite/kernels/transpose.cc", + "src/tensorflow/lite/kernels/transpose_conv.cc", + "src/tensorflow/lite/kernels/unidirectional_sequence_lstm.cc", + "src/tensorflow/lite/kernels/unidirectional_sequence_rnn.cc", + "src/tensorflow/lite/kernels/unique.cc", + "src/tensorflow/lite/kernels/unpack.cc", + "src/tensorflow/lite/kernels/where.cc", + "src/tensorflow/lite/kernels/while.cc", + "src/tensorflow/lite/kernels/zeros_like.cc", + ] + + deps = [ + ":fft2d_deps", + ":tflite_kernel_common_headers", + ":tflite_kernel_internals", + ":tflite_public_headers", + "//third_party/abseil-cpp:absl", + "//third_party/farmhash", + "//third_party/flatbuffers:tflite_deps", + "//third_party/fp16", + "//third_party/gemmlowp", + "//third_party/neon_2_sse", + "//third_party/ruy", + ] + + configs += [ + ":tflite_config", + ":tflite_flags", + "//third_party/eigen3:eigen_includes", + ] + visibility = [ ":*" ] +} + +# TODO(crbug.com/1147996): Update to a component build. Will require updating the +# tflite version. +static_library("tflite") { + sources = [ + "src/tensorflow/lite/allocation.cc", + "src/tensorflow/lite/arena_planner.cc", + "src/tensorflow/lite/builtin_ops.h", + "src/tensorflow/lite/c/c_api.cc", + "src/tensorflow/lite/c/c_api_experimental.cc", + "src/tensorflow/lite/c/c_api_internal.h", + "src/tensorflow/lite/c/common.c", + "src/tensorflow/lite/core/api/error_reporter.cc", + "src/tensorflow/lite/core/api/error_reporter.h", + "src/tensorflow/lite/core/api/flatbuffer_conversions.cc", + "src/tensorflow/lite/core/api/flatbuffer_conversions.h", + "src/tensorflow/lite/core/api/op_resolver.cc", + "src/tensorflow/lite/core/api/profiler.h", + "src/tensorflow/lite/core/api/tensor_utils.cc", + "src/tensorflow/lite/core/api/tensor_utils.h", + "src/tensorflow/lite/core/subgraph.cc", + "src/tensorflow/lite/delegates/nnapi/nnapi_delegate.h", + "src/tensorflow/lite/delegates/nnapi/nnapi_delegate_disabled.cc", + "src/tensorflow/lite/delegates/status.h", + "src/tensorflow/lite/experimental/resource/lookup_interfaces.h", + "src/tensorflow/lite/experimental/resource/lookup_util.h", + "src/tensorflow/lite/experimental/resource/resource_base.h", + "src/tensorflow/lite/experimental/resource/resource_variable.cc", + "src/tensorflow/lite/experimental/resource/static_hashtable.cc", + "src/tensorflow/lite/experimental/resource/static_hashtable.h", + "src/tensorflow/lite/external_cpu_backend_context.cc", + "src/tensorflow/lite/graph_info.cc", + "src/tensorflow/lite/interpreter.cc", + "src/tensorflow/lite/interpreter_builder.cc", + "src/tensorflow/lite/memory_planner.h", + "src/tensorflow/lite/minimal_logging.cc", + "src/tensorflow/lite/minimal_logging.h", + "src/tensorflow/lite/model.h", + "src/tensorflow/lite/model_builder.cc", + "src/tensorflow/lite/model_builder.h", + "src/tensorflow/lite/mutable_op_resolver.cc", + "src/tensorflow/lite/nnapi/NeuralNetworksTypes.h", + "src/tensorflow/lite/nnapi/nnapi_implementation.h", + "src/tensorflow/lite/nnapi/nnapi_implementation_disabled.cc", + "src/tensorflow/lite/optional_debug_tools.cc", + "src/tensorflow/lite/profiling/memory_info.cc", + "src/tensorflow/lite/profiling/memory_info.h", + "src/tensorflow/lite/profiling/platform_profiler.cc", + "src/tensorflow/lite/profiling/platform_profiler.h", + "src/tensorflow/lite/profiling/time.cc", + "src/tensorflow/lite/profiling/time.h", + "src/tensorflow/lite/simple_memory_arena.cc", + "src/tensorflow/lite/simple_memory_arena.h", + "src/tensorflow/lite/stderr_reporter.cc", + "src/tensorflow/lite/stderr_reporter.h", + "src/tensorflow/lite/string_util.cc", + "src/tensorflow/lite/tflite_with_xnnpack_optional.cc", + "src/tensorflow/lite/tflite_with_xnnpack_optional.h", + "src/tensorflow/lite/tools/command_line_flags.h", + "src/tensorflow/lite/tools/delegates/delegate_provider.h", + "src/tensorflow/lite/tools/logging.h", + "src/tensorflow/lite/tools/optimize/sparsity/format_converter.cc", + "src/tensorflow/lite/tools/tool_params.h", + "src/tensorflow/lite/type_to_tflitetype.h", + "src/tensorflow/lite/util.cc", + "src/tensorflow/lite/version.h", + ] + + if (is_win) { + sources += [ "src/tensorflow/lite/mmap_allocation_disabled.cc" ] + } else { + sources += [ "src/tensorflow/lite/mmap_allocation.cc" ] + } + + if (is_ios) { + sources += [ "src/tensorflow/lite/minimal_logging_ios.cc" ] + } else if (is_android) { + sources += [ "src/tensorflow/lite/minimal_logging_android.cc" ] + } else { + sources += [ "src/tensorflow/lite/minimal_logging_default.cc" ] + } + + deps = [ + ":tflite_kernel_common_headers", + ":tflite_kernels", + "//third_party/abseil-cpp:absl", + "//third_party/farmhash", + "//third_party/fft2d", + "//third_party/fp16", + "//third_party/gemmlowp", + "//third_party/neon_2_sse", + "//third_party/ruy", + ] + + public_deps = [ + ":tflite_public_headers", + "//third_party/flatbuffers:tflite_deps", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + ":tflite_flags", + "//build/config/compiler:no_chromium_code", + "//third_party/eigen3:eigen_includes", + ] + + public_configs = [ ":tflite_config" ] +}
diff --git a/third_party/tflite/LICENSE b/third_party/tflite/LICENSE new file mode 100644 index 0000000..40f8c34 --- /dev/null +++ b/third_party/tflite/LICENSE
@@ -0,0 +1,203 @@ +Copyright 2019 The TensorFlow Authors. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/third_party/tflite/OWNERS b/third_party/tflite/OWNERS new file mode 100644 index 0000000..f14a8b97 --- /dev/null +++ b/third_party/tflite/OWNERS
@@ -0,0 +1,4 @@ +mcrouse@chromium.org +sophiechang@chromium.org +tbansal@chromium.org +# COMPONENT: Internals>OptimizationGuide
diff --git a/third_party/tflite/README.chromium b/third_party/tflite/README.chromium new file mode 100644 index 0000000..9d10dec --- /dev/null +++ b/third_party/tflite/README.chromium
@@ -0,0 +1,14 @@ +Name: TensorFlow Lite +Short Name: tflite +URL: https://github.com/tensorflow/tensorflow +Version: 2.3.0 +Date: 2020/07/27 +License: Apache 2.0 +License File: LICENSE +Security Critical: Yes +CPEPrefix: unknown + +Description: +TFLite is a part of the open-source machine-learning library TensorFlow that +provides a stable ML framework optimized for binary size and execution on +mobile devices with limited computation and memory resources.
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index dfffd6c..d3dc51a3 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py
@@ -1274,9 +1274,8 @@ c = Code() if not self._generate_error_messages: return c - (c.Append('if (error->length())') - .Append(' error->append(UTF8ToUTF16("; "));') - .Append('error->append(%s);' % error16)) + c.Append('DCHECK(error->empty());') + c.Append('*error = %s;' % error16) return c def _GenerateError(self, body):
diff --git a/tools/json_schema_compiler/manifest_parse_util.cc b/tools/json_schema_compiler/manifest_parse_util.cc index 477008a..49938c7c 100644 --- a/tools/json_schema_compiler/manifest_parse_util.cc +++ b/tools/json_schema_compiler/manifest_parse_util.cc
@@ -46,6 +46,7 @@ base::string16* error, std::vector<base::StringPiece>* error_path_reversed) { DCHECK(error); + DCHECK(error->empty()); DCHECK(error_path_reversed); DCHECK(error_path_reversed->empty()); @@ -76,6 +77,7 @@ base::string16* error, std::vector<base::StringPiece>* error_path_reversed) { DCHECK(error); + DCHECK(error->empty()); DCHECK(error_path_reversed); DCHECK(error_path_reversed->empty());
diff --git a/tools/json_schema_compiler/test/error_generation_unittest.cc b/tools/json_schema_compiler/test/error_generation_unittest.cc index 734c823..777f8487 100644 --- a/tools/json_schema_compiler/test/error_generation_unittest.cc +++ b/tools/json_schema_compiler/test/error_generation_unittest.cc
@@ -309,25 +309,6 @@ } } -TEST(JsonSchemaCompilerErrorTest, MultiplePopulationErrors) { - { - std::unique_ptr<base::DictionaryValue> value = - Dictionary("TheArray", std::make_unique<Value>(5)); - errors::ArrayObject out; - base::string16 error; - EXPECT_FALSE(errors::ArrayObject::Populate(*value, &out, &error)); - EXPECT_TRUE(EqualsUtf16("'TheArray': expected list, got integer", - error)); - EXPECT_EQ(NULL, out.the_array.get()); - - EXPECT_FALSE(errors::ArrayObject::Populate(*value, &out, &error)); - EXPECT_TRUE(EqualsUtf16("'TheArray': expected list, got integer; " - "'TheArray': expected list, got integer", - error)); - EXPECT_EQ(NULL, out.the_array.get()); - } -} - TEST(JsonSchemaCompilerErrorTest, TooManyKeys) { { std::unique_ptr<base::DictionaryValue> value =
diff --git a/tools/json_schema_compiler/util.cc b/tools/json_schema_compiler/util.cc index b83e4a6..559279e 100644 --- a/tools/json_schema_compiler/util.cc +++ b/tools/json_schema_compiler/util.cc
@@ -16,11 +16,10 @@ bool ReportError(const base::Value& from, base::Value::Type expected, base::string16* error) { - if (!error->empty()) - error->append(base::ASCIIToUTF16("; ")); - error->append(base::ASCIIToUTF16(base::StringPrintf( + DCHECK(error->empty()); + *error = base::ASCIIToUTF16(base::StringPrintf( "expected %s, got %s", base::Value::GetTypeName(expected), - base::Value::GetTypeName(from.type())))); + base::Value::GetTypeName(from.type()))); return false; // Always false on purpose. }
diff --git a/tools/json_schema_compiler/util.h b/tools/json_schema_compiler/util.h index 7bed0a67..7900670f 100644 --- a/tools/json_schema_compiler/util.h +++ b/tools/json_schema_compiler/util.h
@@ -95,11 +95,10 @@ const auto& list = list_value.GetList(); for (size_t i = 0; i < list.size(); ++i) { if (!PopulateItem(list[i], &item, &item_error)) { - if (!error->empty()) - error->append(base::ASCIIToUTF16("; ")); - error->append(base::ASCIIToUTF16( + DCHECK(error->empty()); + *error = base::ASCIIToUTF16( base::StringPrintf("Parsing array failed at index %" PRIuS ": %s", i, - base::UTF16ToASCII(item_error).c_str()))); + base::UTF16ToASCII(item_error).c_str())); return false; } out->push_back(std::move(item));
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 7ab5d60..1793b17 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -30302,6 +30302,7 @@ <int value="3729" label="MediaStreamTrackProcessor"/> <int value="3730" label="AddEventListenerWithAbortSignal"/> <int value="3731" label="XRSessionRequestLightProbe"/> + <int value="3732" label="BeforematchRevealedHiddenMatchable"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -37411,6 +37412,11 @@ <int value="4" label="Url or App not allowed"/> </enum> +<enum name="IMEAutocorrectActions"> + <int value="0" label="WINDOW_SHOWN"/> + <int value="1" label="UNDERLINED"/> +</enum> + <enum name="IMECommitType"> <obsolete> Deprecated 03/2015, and replaced by IMECommitType2. @@ -42598,6 +42604,8 @@ label="TurnOffStreamingMediaCachingOnBattery:disabled"/> <int value="-1492589689" label="ContentSuggestionsCategories:enabled"/> <int value="-1492211482" label="EnableWindowsGamingInputDataFetcher:enabled"/> + <int value="-1491705891" + label="EnableBluetoothVerboseLogsForGooglers:disabled"/> <int value="-1491417046" label="enable-fullscreen-toolbar-reveal"/> <int value="-1491304576" label="ProgressBarThrottle:disabled"/> <int value="-1490298774" label="enable-captive-portal-bypass-proxy-option"/> @@ -44562,6 +44570,7 @@ label="FramebustingNeedsSameOriginOrUserGesture:enabled"/> <int value="408190863" label="OmniboxDisableInstantExtendedLimit:disabled"/> <int value="409566604" label="IntentPickerPWAPersistence:enabled"/> + <int value="409622437" label="disable-buffer-bw-compression"/> <int value="411250226" label="AutoplayMutedVideos:disabled"/> <int value="412957264" label="tab-close-buttons-hidden-with-touch"/> <int value="413062443" label="MessagesForAndroidInfrastructure:disabled"/> @@ -46108,6 +46117,8 @@ <int value="1927374573" label="EnterpriseRealtimeExtensionRequest:enabled"/> <int value="1928407249" label="NewPhotoPicker:enabled"/> <int value="1929603041" label="HideShelfControlsInTabletMode:disabled"/> + <int value="1930185502" + label="EnableBluetoothVerboseLogsForGooglers:enabled"/> <int value="1930901873" label="disable-sync-app-list"/> <int value="1931309368" label="fill-on-account-select:disabled"/> <int value="1932204471" label="SyncPseudoUSSThemes:disabled"/> @@ -70615,6 +70626,9 @@ </enum> <enum name="StayVsLeave"> + <obsolete> + Removed 2020 November. + </obsolete> <int value="0" label="Stay on the current page"/> <int value="1" label="Leave the current page"/> </enum> @@ -74996,7 +75010,12 @@ <int value="22" label="vaSyncSurface()"/> <int value="23" label="vaTerminate()"/> <int value="24" label="vaUnmapBuffer()"/> - <int value="25" label="Other VA functions"/> + <int value="25" label="vaCreateProtectedSession()"/> + <int value="26" label="vaDestroyProtectedSession()"/> + <int value="27" label="vaAttachProtectedSession()"/> + <int value="28" label="vaDetachProtectedSession()"/> + <int value="29" label="vaProtectedSessionHwUpdate()"/> + <int value="30" label="Other VA functions"/> </enum> <enum name="VAIPFailure">
diff --git a/tools/metrics/histograms/histograms_xml/input/histograms.xml b/tools/metrics/histograms/histograms_xml/input/histograms.xml index 606624ff..0a99319 100644 --- a/tools/metrics/histograms/histograms_xml/input/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/input/histograms.xml
@@ -33,6 +33,16 @@ </summary> </histogram> +<histogram name="InputMethod.Assistive.Autocorrect.Actions" + enum="IMEAutocorrectActions" expires_after="2021-03-15"> + <owner>jopalmer@google.com</owner> + <owner>essential-inputs-team@google.com</owner> + <summary> + The actions taken by assistive autocorrect, such as underlining a word. + Recorded after an action is performed. + </summary> +</histogram> + <histogram name="InputMethod.Assistive.Autocorrect.Count" enum="IMETextInputClient" expires_after="2021-05-16"> <owner>myy@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index 7d53535e..0282f33 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -5903,6 +5903,20 @@ </summary> </histogram> +<histogram name="Graphics.Smoothness.MaxPercentDroppedFrames_1sWindow" + units="%" expires_after="2021-11-12"> + <owner>behdadb@chromium.org</owner> + <owner>sadrul@chromium.org</owner> + <summary> + Tracks the percent of dropped frames for in a 1 second sliding window. + + PercentDroppedFrames is measured by tracking the number of frames which were + not displayed on screen out of the total number of frames expected to be + produced and displayed. In other words, the lower this number is, the + smoother experience. + </summary> +</histogram> + <histogram name="Graphics.Smoothness.MaxStale" units="ms" expires_after="2021-11-01"> <owner>sadrul@chromium.org</owner> @@ -7279,6 +7293,9 @@ <histogram name="JSDialogs.OnBeforeUnloadStayVsLeave" enum="StayVsLeave" expires_after="M77"> + <obsolete> + Removed 2020 November. + </obsolete> <owner>avi@chromium.org</owner> <summary> For onbeforeunload dialogs, the user's choice between staying on the page
diff --git a/tools/perf/benchmarks/benchmark_smoke_unittest.py b/tools/perf/benchmarks/benchmark_smoke_unittest.py index 6e463c2e5..9667aa4 100644 --- a/tools/perf/benchmarks/benchmark_smoke_unittest.py +++ b/tools/perf/benchmarks/benchmark_smoke_unittest.py
@@ -103,7 +103,6 @@ 'memory.long_running_idle_gmail_background_tbmv2', 'tab_switching.typical_25', 'UNSCHEDULED_oortonline_tbmv2', - 'UNSCHEDULED_tab_search', # crbug.com/1146335 'webrtc', # crbug.com/932036 'v8.runtime_stats.top_25' # Fails in Windows, crbug.com/1043048 ]
diff --git a/tools/perf/benchmarks/rendering.py b/tools/perf/benchmarks/rendering.py index a4af9f17..6e183c8 100644 --- a/tools/perf/benchmarks/rendering.py +++ b/tools/perf/benchmarks/rendering.py
@@ -44,6 +44,7 @@ 'Graphics.Smoothness.PercentDroppedFrames.SlowerThread.Universal', 'Graphics.Smoothness.PercentDroppedFrames.ScrollingThread.TouchScroll', 'Graphics.Smoothness.PercentDroppedFrames.ScrollingThread.WheelScroll', + 'Graphics.Smoothness.MaxPercentDroppedFrames_1sWindow', 'Memory.GPU.PeakMemoryUsage.Scroll', 'Memory.GPU.PeakMemoryUsage.PageLoad', ]
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 3d229aae..9f461e3 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,16 +1,16 @@ { "trace_processor_shell": { "win": { - "hash": "47607f3a13086206adc7fb1bd99330e1528b9b33", - "remote_path": "perfetto_binaries/trace_processor_shell/win/dda9c164cb3b286b397a207d45141a33cd543d36/trace_processor_shell.exe" + "hash": "bfdb6057bef6817a2dde5a68acd2e3852a05ff62", + "remote_path": "perfetto_binaries/trace_processor_shell/win/2d31db0b3751edccd984896321db1014b8bd26d5/trace_processor_shell.exe" }, "mac": { - "hash": "10a1b83b6b2187b96fcabde17095497b02b82e12", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/dda9c164cb3b286b397a207d45141a33cd543d36/trace_processor_shell" + "hash": "fc50aba2bda1b92a35ddce6e7cfa0fcba40b010d", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/021b77e7f0c77ed09851495f9e068f09cf8331d2/trace_processor_shell" }, "linux": { "hash": "e71b6aa765b3005bdc9590921a7b9a3b42776905", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/d361e6028c2754587b2f5bb4fa2667a2f166fee1/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/021b77e7f0c77ed09851495f9e068f09cf8331d2/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/page_sets/tab_search/tab_search_story.py b/tools/perf/page_sets/tab_search/tab_search_story.py index ccf1011..3c1b91e 100644 --- a/tools/perf/page_sets/tab_search/tab_search_story.py +++ b/tools/perf/page_sets/tab_search/tab_search_story.py
@@ -60,6 +60,8 @@ 'whatsapp.com', ] +TAB_SEARCH_URL = 'chrome://tab-search/' + class TabSearchStory(page.Page): """Base class for tab search stories""" @@ -87,16 +89,16 @@ def RunPageInteractions(self, action_runner): tabs = action_runner.tab.browser.tabs - tabs_len = len(tabs) # Open Tab Search bubble. action_runner.tab.browser.supports_inspecting_webui = True action_runner.tab.browser.ExecuteBrowserCommand('openTabSearch') # Wait for Tab Search bubble to be inspectable. - py_utils.WaitFor(lambda: len(tabs) > tabs_len, 10) + py_utils.WaitFor( + lambda: any([True for tab in tabs if tab.url == TAB_SEARCH_URL]), 10) # Wait for Tab Search bubble to load. - tab = tabs[-1] + tab = next(iter([tab for tab in tabs if tab.url == TAB_SEARCH_URL])) action_runner = ActionRunner( tab) # Recreate action_runner for Tab Search bubble. tab.WaitForDocumentReadyStateToBeComplete()
diff --git a/ui/file_manager/file_manager/background/js/mock_volume_manager.js b/ui/file_manager/file_manager/background/js/mock_volume_manager.js index 1719058..52720f33 100644 --- a/ui/file_manager/file_manager/background/js/mock_volume_manager.js +++ b/ui/file_manager/file_manager/background/js/mock_volume_manager.js
@@ -9,7 +9,7 @@ // #import * as wrappedVolumeManagerFactory from './volume_manager_factory.m.js'; const {volumeManagerFactory} = wrappedVolumeManagerFactory; // #import {VolumeManagerImpl} from './volume_manager_impl.m.js'; // #import * as wrappedVolumeManagerCommon from '../../../base/js/volume_manager_types.m.js'; const {VolumeManagerCommon} = wrappedVolumeManagerCommon; -// #import {MockFileSystem} from '../../common/js/mock_entry.m.js'; +// #import {MockEntry, MockFileSystem} from '../../common/js/mock_entry.m.js'; // #import * as wrappedUtil from '../../common/js/util.m.js'; const {util} = wrappedUtil; // #import {str} from '../../common/js/util.m.js'; // #import {EntryLocation} from '../../../externs/entry_location.m.js'; @@ -258,3 +258,43 @@ /** @override */ MockVolumeManager.prototype.whenVolumeInfoReady = VolumeManagerImpl.prototype.whenVolumeInfoReady; + +/** + * Used to override window.webkitResolveLocalFileSystemURL for testing. This + * emulates the real function by parsing `url` and finding the matching entry + * in `volumeManager`. E.g. filesystem:downloads/dir/file.txt will look up the + * 'downloads' volume for /dir/file.txt. + * + * @param {VolumeManager} volumeManager VolumeManager to resolve URLs with. + * @param {string} url URL to resolve. + * @param {function(!MockEntry)} successCallback Success callback. + * @param {function(!FileError)=} errorCallback Error callback. + */ +MockVolumeManager.resolveLocalFileSystemURL = + (volumeManager, url, successCallback, errorCallback) => { + const match = url.match(/^filesystem:(\w+)(\/.*)/); + if (match) { + const volumeType = + /** @type {VolumeManagerCommon.VolumeType} */ (match[1]); + let path = match[2]; + const volume = volumeManager.getCurrentProfileVolumeInfo(volumeType); + if (volume) { + // Decode URI in file paths. + path = path.split('/').map(decodeURIComponent).join('/'); + const entry = volume.fileSystem.entries[path]; + if (entry) { + setTimeout(successCallback, 0, entry); + return; + } + } + } + const message = + `MockVolumeManager.resolveLocalFileSystemURL not found: ${url}`; + console.warn(message); + const error = new DOMException(message, 'NotFoundError'); + if (errorCallback) { + setTimeout(errorCallback, 0, error); + } else { + throw error; + } + };
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js index 7167ffb..1dc3328 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -693,7 +693,7 @@ this.fileTransferController_.executePaste( new FileTransferController.PastePlan( - this.entries_.map(e => e.toURL()), pvmDir, + this.entries_.map(e => e.toURL()), [], pvmDir, assert(this.volumeManager_.getLocationInfo(pvmDir)), toMove)); this.directoryModel_.changeDirectoryEntry(pvmDir);
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js index d442e36..dffe64e 100644 --- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js +++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -425,20 +425,38 @@ * Collects parameters of paste operation by the given command and the current * system clipboard. * + * @param {!DataTransfer} clipboardData System data transfer object. + * @param {DirectoryEntry=} opt_destinationEntry Paste destination. + * @param {string=} opt_effect Desired drop/paste effect. Could be + * 'move'|'copy' (default is copy). Ignored if conflicts with + * |clipboardData.effectAllowed|. * @return {!FileTransferController.PastePlan} */ preparePaste(clipboardData, opt_destinationEntry, opt_effect) { + // When FilesApp does drag and drop to itself, it uses fs/sources to + // populate sourceURLs, and it will resolve sourceEntries later using + // webkitResolveLocalFileSystemURL(). const sourceURLs = clipboardData.getData('fs/sources') ? clipboardData.getData('fs/sources').split('\n') : []; + + // When FilesApp is the paste target for other apps such as crostini, + // the file URL is either not provided, or it is not compatible. We use + // DataTransferItem.webkitGetAsEntry() to get the entry now. + const sourceEntries = sourceURLs.length === 0 ? + Array.prototype.filter.call(clipboardData.items, i => i.kind === 'file') + .map(i => i.webkitGetAsEntry()) : + []; + // effectAllowed set in copy/paste handlers stay uninitialized. DnD handlers // work fine. const effectAllowed = clipboardData.effectAllowed !== 'uninitialized' ? clipboardData.effectAllowed : clipboardData.getData('fs/effectallowed'); - const destinationEntry = opt_destinationEntry || + const destinationEntry = assert( + opt_destinationEntry || /** @type {DirectoryEntry} */ - (this.directoryModel_.getCurrentDirEntry()); + (this.directoryModel_.getCurrentDirEntry())); const toMove = util.isDropEffectAllowed(effectAllowed, 'move') && (!util.isDropEffectAllowed(effectAllowed, 'copy') || opt_effect === 'move'); @@ -447,11 +465,12 @@ this.volumeManager_.getLocationInfo(destinationEntry); if (!destinationLocationInfo) { console.log( - 'Failed to get destination location for ' + destinationEntry.title() + + 'Failed to get destination location for ' + destinationEntry.toURL() + ' while attempting to paste files.'); } return new FileTransferController.PastePlan( - sourceURLs, destinationEntry, assert(destinationLocationInfo), toMove); + sourceURLs, sourceEntries, destinationEntry, + assert(destinationLocationInfo), toMove); } /** @@ -469,10 +488,8 @@ const pastePlan = this.preparePaste(clipboardData, opt_destinationEntry, opt_effect); - return FileTransferController.URLsToEntriesWithAccess(pastePlan.sourceURLs) - .then(entriesResult => { - const sourceEntries = entriesResult.entries; - + return pastePlan.resolveEntries().then( + sourceEntries => { if (sourceEntries.length == 0) { // This can happen when copied files were deleted before pasting // them. We execute the plan as-is, so as to share the post-copy @@ -480,13 +497,12 @@ // same-directory entries. return Promise.resolve(this.executePaste(pastePlan)); } - const confirmationType = pastePlan.getConfirmationType(sourceEntries); + const confirmationType = pastePlan.getConfirmationType(); if (confirmationType == FileTransferController.ConfirmationType.NONE) { return Promise.resolve(this.executePaste(pastePlan)); } - const messages = pastePlan.getConfirmationMessages( - confirmationType, sourceEntries); + const messages = pastePlan.getConfirmationMessages(confirmationType); this.confirmationCallback_(pastePlan.isMove, messages) .then(userApproved => { if (userApproved) { @@ -508,21 +524,16 @@ const destinationEntry = pastePlan.destinationEntry; let entries = []; - let failureUrls; let shareEntries; const taskId = this.fileOperationManager_.generateTaskId(); - FileTransferController.URLsToEntriesWithAccess(sourceURLs) - .then(/** - * @param {Object} result - */ - result => { - failureUrls = result.failureUrls; - // The promise is not rejected, so it's safe to not remove the - // early progress center item here. - return this.fileOperationManager_.filterSameDirectoryEntry( - result.entries, destinationEntry, toMove); - }) + pastePlan.resolveEntries() + .then(sourceEntries => { + // The promise is not rejected, so it's safe to not remove the + // early progress center item here. + return this.fileOperationManager_.filterSameDirectoryEntry( + sourceEntries, destinationEntry, toMove); + }) .then(/** * @param {!Array<Entry>} filteredEntries */ @@ -579,7 +590,7 @@ entries, destinationEntry, toMove, taskId); this.pendingTaskIds.splice( this.pendingTaskIds.indexOf(taskId), 1); - }) + }) .catch(error => { if (error !== 'ABORT') { console.error(error.stack ? error.stack : error); @@ -587,9 +598,9 @@ }) .finally(() => { // Publish source not found error item. - for (let i = 0; i < failureUrls.length; i++) { - const fileName = - decodeURIComponent(failureUrls[i].replace(/^.+\//, '')); + for (let i = 0; i < pastePlan.failureUrls.length; i++) { + const fileName = decodeURIComponent( + pastePlan.failureUrls[i].replace(/^.+\//, '')); const item = new ProgressCenterItem(); item.id = 'source-not-found-' + this.sourceNotFoundErrorCount_; if (toMove) { @@ -1338,7 +1349,10 @@ return false; } - if (!clipboardData.types || clipboardData.types.indexOf('fs/tag') === -1) { + // DataTransfer type will be 'fs/tag' when the source was FilesApp, or + // 'Files' when the source was any other app. + const types = clipboardData.types; + if (!types || !(types.includes('fs/tag') || types.includes('Files'))) { return false; // Unsupported type of content. } @@ -1640,12 +1654,15 @@ FileTransferController.PastePlan = class { /** * @param {!Array<string>} sourceURLs URLs of source entries. + * @param {!Array<!Entry>} sourceEntries Entries of source entries. * @param {!DirectoryEntry} destinationEntry Destination directory. * @param {!EntryLocation} destinationLocationInfo Location info of the * destination directory. * @param {boolean} isMove true if move, false if copy. */ - constructor(sourceURLs, destinationEntry, destinationLocationInfo, isMove) { + constructor( + sourceURLs, sourceEntries, destinationEntry, destinationLocationInfo, + isMove) { /** * @type {!Array<string>} * @const @@ -1653,6 +1670,17 @@ this.sourceURLs = sourceURLs; /** + * @type {!Array<!Entry>} + */ + this.sourceEntries = sourceEntries; + + /** + * Any URLs from sourceURLs which failed resolving to into sourceEntries. + * @type {!Array<string>} + */ + this.failureUrls = []; + + /** * @type {!DirectoryEntry} */ this.destinationEntry = destinationEntry; @@ -1670,19 +1698,33 @@ } /** + * Resolves sourceEntries from sourceURLs if needed and returns them. + * + * @return {!Promise<!Array<!Entry>>} + */ + async resolveEntries() { + if (!this.sourceEntries.length) { + const result = + await FileTransferController.URLsToEntriesWithAccess(this.sourceURLs); + this.sourceEntries = result.entries; + this.failureUrls = result.failureUrls; + } + return this.sourceEntries; + } + + /** * Obtains whether the planned operation requires user's confirmation, as well * as its type. * - * @param {!Array<!Entry>} sourceEntries * @return {FileTransferController.ConfirmationType} type of the confirmation * required for the operation. If no confirmation is needed, * FileTransferController.ConfirmationType.NONE will be returned. */ - getConfirmationType(sourceEntries) { - assert(sourceEntries.length != 0); + getConfirmationType() { + assert(this.sourceEntries.length != 0); const source = { - isTeamDrive: util.isSharedDriveEntry(sourceEntries[0]), - teamDriveName: util.getTeamDriveName(sourceEntries[0]) + isTeamDrive: util.isSharedDriveEntry(this.sourceEntries[0]), + teamDriveName: util.getTeamDriveName(this.sourceEntries[0]) }; const destination = { isTeamDrive: util.isSharedDriveEntry(this.destinationEntry), @@ -1727,9 +1769,9 @@ * @param {FileTransferController.ConfirmationType} confirmationType * @return {!Array<string>} sentences for a confirmation dialog box. */ - getConfirmationMessages(confirmationType, sourceEntries) { - assert(sourceEntries.length != 0); - const sourceName = util.getTeamDriveName(sourceEntries[0]); + getConfirmationMessages(confirmationType) { + assert(this.sourceEntries.length != 0); + const sourceName = util.getTeamDriveName(this.sourceEntries[0]); const destinationName = util.getTeamDriveName(this.destinationEntry); switch (confirmationType) { case FileTransferController.ConfirmationType.MOVE_BETWEEN_SHARED_DRIVES:
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller_unittest.js index 26d0a25..53c3e9d 100644 --- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller_unittest.js
@@ -65,7 +65,10 @@ enableExternalFileScheme: () => {}, getProfiles: (callback) => { setTimeout(callback, 0, [], '', ''); - } + }, + grantAccess: (entryURLs, callback) => { + setTimeout(callback, 0); + }, }, }; installMockChrome(mockChrome); @@ -91,8 +94,11 @@ // Fake DirectoryModel. const directoryModel = createFakeDirectoryModel(); - // Fake VolumeManager. + // Create fake VolumeManager and install webkitResolveLocalFileSystemURL. volumeManager = new MockVolumeManager(); + window.webkitResolveLocalFileSystemURL = + MockVolumeManager.resolveLocalFileSystemURL.bind(null, volumeManager); + // Fake FileSelectionHandler. selectionHandler = new FakeFileSelectionHandler(); @@ -231,3 +237,55 @@ selectionHandler.updateSelection([otherFolderEntry], []); assertTrue(fileTransferController.canCutOrDrag()); } + +/** + * Tests preparePaste() with FilesApp fs/sources and standard DataTransfer. + */ +async function testPreparePaste(done) { + const myFilesVolume = volumeManager.volumeInfoList.item(1); + const myFilesMockFs = + /** @type {!MockFileSystem} */ (myFilesVolume.fileSystem); + myFilesMockFs.populate(['/testfile.txt', '/testdir/']); + const testFile = MockFileEntry.create(myFilesMockFs, '/testfile.txt'); + const testDir = MockDirectoryEntry.create(myFilesMockFs, '/testdir'); + + // FilesApp internal drag and drop should populate sourceURLs at first, and + // only populate sourceEntries after calling resolveEntries(). + const filesAppDataTransfer = new DataTransfer(); + filesAppDataTransfer.setData('fs/sources', testFile.toURL()); + const filesAppPastePlan = + fileTransferController.preparePaste(filesAppDataTransfer, testDir); + assertEquals(filesAppPastePlan.sourceURLs.length, 1); + assertEquals(filesAppPastePlan.sourceEntries.length, 0); + await filesAppPastePlan.resolveEntries(); + assertEquals(filesAppPastePlan.sourceEntries.length, 1); + assertEquals(filesAppPastePlan.sourceEntries[0], testFile); + + // Drag and drop from other apps will use DataTransfer.item with + // item.kind === 'file', and use webkitGetAsEntry() to populate sourceEntries. + const otherMockFs = new MockFileSystem('not-filesapp'); + const otherFile = MockFileEntry.create(otherMockFs, '/otherfile.txt'); + const otherDataTransfer = /** @type {!DataTransfer} */ ({ + effectAllowed: 'copy', + getData: () => { + return ''; + }, + items: [{ + kind: 'file', + webkitGetAsEntry: () => { + return otherFile; + }, + }], + }); + const otherPastePlan = + fileTransferController.preparePaste(otherDataTransfer, testDir); + assertEquals(otherPastePlan.sourceURLs.length, 0); + assertEquals(otherPastePlan.sourceEntries.length, 1); + assertEquals(otherPastePlan.sourceEntries[0], otherFile); + await otherPastePlan.resolveEntries(); + assertEquals(otherPastePlan.sourceURLs.length, 0); + assertEquals(otherPastePlan.sourceEntries.length, 1); + assertEquals(otherPastePlan.sourceEntries[0], otherFile); + + done(); +}
diff --git a/ui/file_manager/file_manager/test/js/chrome_file_manager_private_test_impl.js b/ui/file_manager/file_manager/test/js/chrome_file_manager_private_test_impl.js index aa961a3..12b3990 100644 --- a/ui/file_manager/file_manager/test/js/chrome_file_manager_private_test_impl.js +++ b/ui/file_manager/file_manager/test/js/chrome_file_manager_private_test_impl.js
@@ -316,35 +316,5 @@ }, }; -/** - * Override webkitResolveLocalFileSystemURL for testing. - * @param {string} url URL to resolve. - * @param {function(!MockEntry)} successCallback Success callback. - * @param {function(!Error)} errorCallback Error callback. - */ -// eslint-disable-next-line -var webkitResolveLocalFileSystemURL = (url, successCallback, errorCallback) => { - const match = url.match(/^filesystem:(\w+)(\/.*)/); - if (match) { - const volumeType = /** @type {VolumeManagerCommon.VolumeType} */ (match[1]); - let path = match[2]; - const volume = mockVolumeManager.getCurrentProfileVolumeInfo(volumeType); - if (volume) { - // Decode URI in file paths. - path = path.split('/').map(decodeURIComponent).join('/'); - const entry = volume.fileSystem.entries[path]; - if (entry) { - setTimeout(successCallback, 0, entry); - return; - } - } - } - const message = `webkitResolveLocalFileSystemURL not found: ${url}`; - console.warn(message); - const error = new DOMException(message, 'NotFoundError'); - if (errorCallback) { - setTimeout(errorCallback, 0, error); - } else { - throw error; - } -}; +window.webkitResolveLocalFileSystemURL = + MockVolumeManager.resolveLocalFileSystemURL.bind(null, mockVolumeManager);
diff --git a/ui/gfx/android/android_surface_control_compat.cc b/ui/gfx/android/android_surface_control_compat.cc index c22ee52..4508dc2b2 100644 --- a/ui/gfx/android/android_surface_control_compat.cc +++ b/ui/gfx/android/android_surface_control_compat.cc
@@ -11,6 +11,7 @@ #include "base/atomic_sequence_num.h" #include "base/bind.h" #include "base/debug/crash_logging.h" +#include "base/hash/md5_constexpr.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/no_destructor.h" @@ -282,6 +283,12 @@ SurfaceControl::Transaction::OnCompleteCb callback; }; +uint64_t GetTraceIdForTransaction(int transaction_id) { + constexpr uint64_t kMask = + base::MD5Hash64Constexpr("SurfaceControl::Transaction"); + return kMask ^ transaction_id; +} + // Note that the framework API states that this callback can be dispatched on // any thread (in practice it should be the binder thread). void OnTransactionCompletedOnAnyThread(void* context, @@ -290,6 +297,9 @@ auto transaction_stats = ToTransactionStats(stats); TRACE_EVENT_NESTABLE_ASYNC_END0("gpu,benchmark", "SurfaceControlTransaction", ack_ctx->id); + TRACE_EVENT_WITH_FLOW0( + "toplevel.flow", "gfx::SurfaceControlTransaction completed", + GetTraceIdForTransaction(ack_ctx->id), TRACE_EVENT_FLAG_FLOW_IN); if (ack_ctx->task_runner) { ack_ctx->task_runner->PostTask( @@ -301,6 +311,7 @@ delete ack_ctx; } + } // namespace // static @@ -472,6 +483,9 @@ void SurfaceControl::Transaction::SetOnCompleteCb( OnCompleteCb cb, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + TRACE_EVENT_WITH_FLOW0( + "toplevel.flow", "gfx::SurfaceControl::Transaction::SetOnCompleteCb", + GetTraceIdForTransaction(id_), TRACE_EVENT_FLAG_FLOW_OUT); TransactionAckCtx* ack_ctx = new TransactionAckCtx; ack_ctx->callback = std::move(cb); ack_ctx->task_runner = std::move(task_runner);
diff --git a/ui/ozone/platform/drm/ozone_platform_drm.cc b/ui/ozone/platform/drm/ozone_platform_drm.cc index 8a64422..dc8575c7 100644 --- a/ui/ozone/platform/drm/ozone_platform_drm.cc +++ b/ui/ozone/platform/drm/ozone_platform_drm.cc
@@ -230,6 +230,12 @@ } void InitializeGPU(const InitParams& args) override { + // Check if buffer bandwidth compression is disabled + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableBufferBWCompression)) { + setenv("MINIGBM_DEBUG", "nocompression", 1); + } + gpu_task_runner_ = base::ThreadTaskRunnerHandle::Get(); // NOTE: Can't start the thread here since this is called before sandbox
diff --git a/ui/ozone/public/ozone_switches.cc b/ui/ozone/public/ozone_switches.cc index b9754475..16bb1ed 100644 --- a/ui/ozone/public/ozone_switches.cc +++ b/ui/ozone/public/ozone_switches.cc
@@ -22,4 +22,7 @@ const char kDisableRunningAsSystemCompositor[] = "disable-running-as-system-compositor"; +// Disable buffer bandwidth compression +const char kDisableBufferBWCompression[] = "disable-buffer-bw-compression"; + } // namespace switches
diff --git a/ui/ozone/public/ozone_switches.h b/ui/ozone/public/ozone_switches.h index 12dd34e2..6d05ea6 100644 --- a/ui/ozone/public/ozone_switches.h +++ b/ui/ozone/public/ozone_switches.h
@@ -21,6 +21,8 @@ COMPONENT_EXPORT(OZONE_BASE) extern const char kDisableRunningAsSystemCompositor[]; +COMPONENT_EXPORT(OZONE_BASE) extern const char kDisableBufferBWCompression[]; + } // namespace switches #endif // UI_OZONE_PUBLIC_OZONE_SWITCHES_H_