diff --git a/DEPS b/DEPS index 0d7b5ca..fdc6a366 100644 --- a/DEPS +++ b/DEPS
@@ -200,11 +200,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'b69a9d48bf176ba802a22c1bc0002fe09045b458', + 'skia_revision': 'd90024d4982937c249bbbff8f02f46bfce71bb97', # 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': '8a682e08571d84f1d93ef73a07cfac7a089676c9', + 'v8_revision': '22f2e5ef66ed5c820532f27b141096d3ddb1966e', # 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. @@ -212,11 +212,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': 'c4ca12e32e6aef9f5f8eb06c4b361264bec19f8d', + 'angle_revision': 'e51c9068a84f14e42157c097eb764ec3009e0e54', # 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': 'aeb3616301c8a2988ede07e4c34e8975da4d5fa0', + 'swiftshader_revision': '6d612051c083238db89541be4fbb2d624a9baef4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -267,7 +267,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '11b40137016bc78282f346fe45333676b3ac75fb', + 'catapult_revision': '91c1a7c2dc0a8c9442d3d5786c424593eef45cae', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -275,7 +275,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': '361d02972a3d37e6e7ebe25e2df51e781da6c0d0', + 'devtools_frontend_revision': '068400262b841bb557d3322f296406a6272be029', # 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. @@ -1369,7 +1369,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'gt2DKWmtJU6vqOju1UcBB-_Nthud81s3cnZkERzzSEUC' + 'version': 'XF2EE8yaR8BB2gKWbGt1VaQYsdZ57CVGOdgEPj2CcaQC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1551,7 +1551,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'afaca889d46b2c493de34a8f0771c89dea17bb1a', + Var('webrtc_git') + '/src.git' + '@' + '7d75f2ca782f38006bb65bc67533e582190454e8', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1623,7 +1623,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a08962107ef6052993af0b1aca418ec6e5bd921a', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2ee6d70254071c9ed67cfe550cc406a68f008952', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/gfx/hardware_renderer_viz.cc b/android_webview/browser/gfx/hardware_renderer_viz.cc index 5e08a918..f6e0845 100644 --- a/android_webview/browser/gfx/hardware_renderer_viz.cc +++ b/android_webview/browser/gfx/hardware_renderer_viz.cc
@@ -159,7 +159,8 @@ if (child_frame->frame) { DCHECK(!viz_frame_submission_); - without_gpu_->SubmitChildCompositorFrame(child_frame); + without_gpu_->SubmitChildCompositorFrame(child_id.local_surface_id(), + child_frame); } gfx::Size frame_size = without_gpu_->GetChildFrameSize(); @@ -275,7 +276,9 @@ RenderThreadManager* state, RootFrameSinkGetter root_frame_sink_getter, AwVulkanContextProvider* context_provider) - : HardwareRenderer(state), output_surface_provider_(context_provider) { + : HardwareRenderer(state), + viz_frame_submission_(features::IsUsingVizFrameSubmissionForWebView()), + output_surface_provider_(context_provider) { DCHECK_CALLED_ON_VALID_THREAD(render_thread_checker_); DCHECK(output_surface_provider_.renderer_settings().use_skia_renderer); @@ -336,10 +339,43 @@ if (!child_frame_) return; - viz::SurfaceId child_surface_id = child_frame_->GetSurfaceId(); + // Two problems currently can cause the content-generated LocalSurfaceId + // to remain the same even if a frame of a new size is submitted: + // * The content LocalSurfaceId is currently copied from browser, not + // the renderer when the renderer submits a frame + // * Synchronous compositor can resize the viewport in LTHI::OnDraw before + // a new LocalSurfaceId is committed. + // Therefore we do not use the LocalSurfaceId allocated by content, and + // instead generate our own LocalSurfaceId here for the root renderer frame. + if (!renderer_root_local_surface_id_allocator_ || + child_frame_->frame_sink_id != surface_id_.frame_sink_id() || + layer_tree_frame_sink_id_ != child_frame_->layer_tree_frame_sink_id) { + renderer_root_local_surface_id_allocator_ = + std::make_unique<viz::ParentLocalSurfaceIdAllocator>(); + layer_tree_frame_sink_id_ = child_frame_->layer_tree_frame_sink_id; + renderer_root_local_surface_id_ = viz::LocalSurfaceId(); + } + + if (!viz_frame_submission_ && child_frame_->frame) { + if (!renderer_root_local_surface_id_.is_valid() || + child_frame_->frame->size_in_pixels() != frame_size_ || + child_frame_->frame->device_scale_factor() != device_scale_factor_) { + renderer_root_local_surface_id_allocator_->GenerateId(); + renderer_root_local_surface_id_ = + renderer_root_local_surface_id_allocator_->GetCurrentLocalSurfaceId(); + frame_size_ = child_frame_->frame->size_in_pixels(); + device_scale_factor_ = child_frame_->frame->device_scale_factor(); + } + } + + viz::SurfaceId child_surface_id = + viz_frame_submission_ ? child_frame_->GetSurfaceId() + : viz::SurfaceId(child_frame_->frame_sink_id, + renderer_root_local_surface_id_); if (child_surface_id.is_valid() && child_surface_id != surface_id_) { surface_id_ = child_surface_id; - device_scale_factor_ = child_frame_->device_scale_factor; + if (viz_frame_submission_) + device_scale_factor_ = child_frame_->device_scale_factor; } if (!surface_id_.is_valid())
diff --git a/android_webview/browser/gfx/hardware_renderer_viz.h b/android_webview/browser/gfx/hardware_renderer_viz.h index 539912b..7b97e6d 100644 --- a/android_webview/browser/gfx/hardware_renderer_viz.h +++ b/android_webview/browser/gfx/hardware_renderer_viz.h
@@ -35,14 +35,19 @@ void DestroyOnViz(); bool IsUsingVulkan() const; - // Information about last delegated frame. - float device_scale_factor_ = 0; - + const bool viz_frame_submission_; viz::SurfaceId surface_id_; // Used to create viz::OutputSurface and gl::GLSurface OutputSurfaceProviderWebview output_surface_provider_; + std::unique_ptr<viz::ParentLocalSurfaceIdAllocator> + renderer_root_local_surface_id_allocator_; + uint32_t layer_tree_frame_sink_id_ = 0u; + viz::LocalSurfaceId renderer_root_local_surface_id_; + float device_scale_factor_ = 1.0f; + gfx::Size frame_size_; + // These are accessed on the viz thread. std::unique_ptr<OnViz> on_viz_;
diff --git a/android_webview/browser/gfx/root_frame_sink.cc b/android_webview/browser/gfx/root_frame_sink.cc index 12fbe1b..4eac7a7e 100644 --- a/android_webview/browser/gfx/root_frame_sink.cc +++ b/android_webview/browser/gfx/root_frame_sink.cc
@@ -195,7 +195,9 @@ client_ = nullptr; } -void RootFrameSink::SubmitChildCompositorFrame(ChildFrame* child_frame) { +void RootFrameSink::SubmitChildCompositorFrame( + const viz::LocalSurfaceId& local_surface_id, + ChildFrame* child_frame) { DCHECK(child_frame->frame); if (!child_sink_support_ || child_sink_support_->frame_sink_id() != child_frame->frame_sink_id || @@ -209,7 +211,7 @@ } child_sink_support_->SubmitCompositorFrame( - child_frame->local_surface_id, std::move(*child_frame->frame), + local_surface_id, std::move(*child_frame->frame), std::move(child_frame->hit_test_region_list)); child_frame->frame.reset(); }
diff --git a/android_webview/browser/gfx/root_frame_sink.h b/android_webview/browser/gfx/root_frame_sink.h index c607602..afa412f 100644 --- a/android_webview/browser/gfx/root_frame_sink.h +++ b/android_webview/browser/gfx/root_frame_sink.h
@@ -58,7 +58,8 @@ bool IsChildSurface(const viz::FrameSinkId& frame_sink_id); void DettachClient(); - void SubmitChildCompositorFrame(ChildFrame* child_frame); + void SubmitChildCompositorFrame(const viz::LocalSurfaceId& local_surface_id, + ChildFrame* child_frame); viz::FrameTimingDetailsMap TakeChildFrameTimingDetailsMap(); gfx::Size GetChildFrameSize();
diff --git a/apps/load_and_launch_browsertest.cc b/apps/load_and_launch_browsertest.cc index 065d900..02c7168 100644 --- a/apps/load_and_launch_browsertest.cc +++ b/apps/load_and_launch_browsertest.cc
@@ -38,6 +38,12 @@ namespace { +constexpr char kTestExtensionId[] = "behllobkkfkfnphdnhnkndlbkcpglgmj"; + +// Lacros doesn't support launching with chrome already running. See the header +// comment for InProcessBrowserTest::GetCommandLineForRelaunch(). +#if !BUILDFLAG(IS_CHROMEOS_LACROS) + const char* kSwitchesToCopy[] = { sandbox::policy::switches::kNoSandbox, switches::kUserDataDir, @@ -56,10 +62,6 @@ switches::kDisableFeatures, }; -constexpr char kTestExtensionId[] = "behllobkkfkfnphdnhnkndlbkcpglgmj"; - -} // namespace - // TODO(jackhou): Enable this test once it works on OSX. It currently does not // work for the same reason --app-id doesn't. See http://crbug.com/148465 #if defined(OS_MAC) @@ -99,7 +101,7 @@ } // TODO(jackhou): Enable this test once it works on OSX. It currently does not -// work for the same reason --app-id doesn't. See http://crbug.com/148465 +// work for the same reason --app-id doesn't. See http://crbug.com/148465. #if defined(OS_MAC) #define MAYBE_LoadAndLaunchAppWithFile DISABLED_LoadAndLaunchAppWithFile #else @@ -140,7 +142,7 @@ ASSERT_EQ(0, exit_code); } -namespace { +#endif // !BUILDFLAG(IS_CHROMEOS_LACROS) // TestFixture that appends --load-and-launch-app with an app before calling // BrowserMain. @@ -200,8 +202,6 @@ } }; -} // namespace - // Case where Chrome is not running. IN_PROC_BROWSER_TEST_F(LoadAndLaunchPlatformAppBrowserTest, LoadAndLaunchAppChromeNotRunning) { @@ -237,4 +237,5 @@ kTestExtensionId, extensions::ExtensionRegistry::EVERYTHING)); } +} // namespace } // namespace apps
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index b634ba0..d9ef55e 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -323,6 +323,8 @@ "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_file_item_view.cc", + "clipboard/views/clipboard_history_file_item_view.h", "clipboard/views/clipboard_history_item_view.cc", "clipboard/views/clipboard_history_item_view.h", "clipboard/views/clipboard_history_label.cc",
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index 56608873..56c23a8 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -512,9 +512,15 @@ ->context_factory() ->GetHostFrameSinkManager() ->CreateVideoCapturer(video_capturer.InitWithNewPipeAndPassReceiver()); + + // We bind the audio stream factory only if audio recording is enabled. This + // is ok since the |audio_stream_factory| parameter in the recording service + // APIs is optional, and can be not bound. mojo::PendingRemote<audio::mojom::StreamFactory> audio_stream_factory; - delegate_->BindAudioStreamFactory( - audio_stream_factory.InitWithNewPipeAndPassReceiver()); + if (enable_audio_recording_) { + delegate_->BindAudioStreamFactory( + audio_stream_factory.InitWithNewPipeAndPassReceiver()); + } auto frame_sink_id = capture_params.window->GetFrameSinkId(); if (!frame_sink_id.is_valid()) {
diff --git a/ash/capture_mode/capture_mode_controller.h b/ash/capture_mode/capture_mode_controller.h index 234d4b1..81e8417 100644 --- a/ash/capture_mode/capture_mode_controller.h +++ b/ash/capture_mode/capture_mode_controller.h
@@ -252,6 +252,9 @@ std::unique_ptr<CaptureModeSession> capture_mode_session_; + // Whether the service should record audio. + bool enable_audio_recording_ = true; + // True when video recording is in progress. bool is_recording_in_progress_ = false;
diff --git a/ash/capture_mode/capture_mode_test_api.cc b/ash/capture_mode/capture_mode_test_api.cc index 474a7f2..0123998 100644 --- a/ash/capture_mode/capture_mode_test_api.cc +++ b/ash/capture_mode/capture_mode_test_api.cc
@@ -62,6 +62,11 @@ controller_->on_file_saved_callback_ = std::move(callback); } +void CaptureModeTestApi::SetAudioRecordingEnabled(bool enabled) { + DCHECK(!controller_->is_recording_in_progress()); + controller_->enable_audio_recording_ = enabled; +} + void CaptureModeTestApi::SetType(bool for_video) { controller_->SetType(for_video ? CaptureModeType::kVideo : CaptureModeType::kImage);
diff --git a/ash/clipboard/views/clipboard_history_file_item_view.cc b/ash/clipboard/views/clipboard_history_file_item_view.cc new file mode 100644 index 0000000..7f9efcb --- /dev/null +++ b/ash/clipboard/views/clipboard_history_file_item_view.cc
@@ -0,0 +1,51 @@ +// 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/views/clipboard_history_file_item_view.h" + +#include "ash/public/cpp/file_icon_util.h" +#include "base/files/file_path.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/view_class_properties.h" + +namespace { + +// The file icon's preferred size. +constexpr gfx::Size kIconSize(20, 20); + +// The file icon's margin. +constexpr gfx::Insets kIconMargin(/*top=*/0, + /*left=*/0, + /*bottom=*/0, + /*right=*/12); +} // namespace + +namespace ash { + +ClipboardHistoryFileItemView::ClipboardHistoryFileItemView( + const ClipboardHistoryItem* clipboard_history_item, + views::MenuItemView* container) + : ClipboardHistoryTextItemView(clipboard_history_item, container) {} +ClipboardHistoryFileItemView::~ClipboardHistoryFileItemView() = default; + +std::unique_ptr<ClipboardHistoryFileItemView::ContentsView> +ClipboardHistoryFileItemView::CreateContentsView() { + auto file_icon = std::make_unique<views::ImageView>(); + const std::string copied_file_name = base::UTF16ToUTF8(text()); + file_icon->SetImage(GetIconForPath(base::FilePath(copied_file_name))); + file_icon->SetImageSize(kIconSize); + file_icon->SetProperty(views::kMarginsKey, kIconMargin); + auto contents_view = ClipboardHistoryTextItemView::CreateContentsView(); + + // `file_icon` should be `contents_view`'s first child. + contents_view->AddChildViewAt(std::move(file_icon), /*index=*/0); + + return contents_view; +} + +const char* ClipboardHistoryFileItemView::GetClassName() const { + return "ClipboardHistoryFileItemView"; +} + +} // namespace ash
diff --git a/ash/clipboard/views/clipboard_history_file_item_view.h b/ash/clipboard/views/clipboard_history_file_item_view.h new file mode 100644 index 0000000..52dc2c3 --- /dev/null +++ b/ash/clipboard/views/clipboard_history_file_item_view.h
@@ -0,0 +1,36 @@ +// 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_VIEWS_CLIPBOARD_HISTORY_FILE_ITEM_VIEW_H_ +#define ASH_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_FILE_ITEM_VIEW_H_ + +#include "ash/clipboard/views/clipboard_history_text_item_view.h" + +namespace views { +class MenuItemView; +} + +namespace ash { + +// The menu item showing the copied file. +class ClipboardHistoryFileItemView : public ClipboardHistoryTextItemView { + public: + ClipboardHistoryFileItemView( + const ClipboardHistoryItem* clipboard_history_item, + views::MenuItemView* container); + ClipboardHistoryFileItemView(const ClipboardHistoryFileItemView& rhs) = + delete; + ClipboardHistoryFileItemView& operator=( + const ClipboardHistoryFileItemView& rhs) = delete; + ~ClipboardHistoryFileItemView() override; + + private: + // ClipboardHistoryTextItemView: + std::unique_ptr<ContentsView> CreateContentsView() override; + const char* GetClassName() const override; +}; + +} // namespace ash + +#endif // ASH_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_FILE_ITEM_VIEW_H_
diff --git a/ash/clipboard/views/clipboard_history_item_view.cc b/ash/clipboard/views/clipboard_history_item_view.cc index 31735ec..de029f9 100644 --- a/ash/clipboard/views/clipboard_history_item_view.cc +++ b/ash/clipboard/views/clipboard_history_item_view.cc
@@ -8,6 +8,7 @@ #include "ash/clipboard/clipboard_history_resource_manager.h" #include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/views/clipboard_history_bitmap_item_view.h" +#include "ash/clipboard/views/clipboard_history_file_item_view.h" #include "ash/clipboard/views/clipboard_history_text_item_view.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/style/ash_color_provider.h" @@ -188,7 +189,7 @@ return std::make_unique<ClipboardHistoryBitmapItemView>( &item, resource_manager, container); case ClipboardHistoryUtil::ClipboardHistoryDisplayFormat::kFile: - return std::make_unique<ClipboardHistoryTextItemView>(&item, container); + return std::make_unique<ClipboardHistoryFileItemView>(&item, container); } }
diff --git a/ash/clipboard/views/clipboard_history_text_item_view.h b/ash/clipboard/views/clipboard_history_text_item_view.h index fd660c0..05b0281 100644 --- a/ash/clipboard/views/clipboard_history_text_item_view.h +++ b/ash/clipboard/views/clipboard_history_text_item_view.h
@@ -25,11 +25,16 @@ delete; ~ClipboardHistoryTextItemView() override; + protected: + const base::string16& text() const { return text_; } + + // ClipboardHistoryItemView: + std::unique_ptr<ContentsView> CreateContentsView() override; + private: class TextContentsView; // ClipboardHistoryItemView: - std::unique_ptr<ContentsView> CreateContentsView() override; base::string16 GetAccessibleName() const override; const char* GetClassName() const override;
diff --git a/ash/public/cpp/capture_mode_test_api.h b/ash/public/cpp/capture_mode_test_api.h index e9f16cd..95706b1 100644 --- a/ash/public/cpp/capture_mode_test_api.h +++ b/ash/public/cpp/capture_mode_test_api.h
@@ -54,6 +54,10 @@ using OnFileSavedCallback = base::OnceCallback<void(const base::FilePath&)>; void SetOnCaptureFileSavedCallback(OnFileSavedCallback callback); + // Sets whether or not audio will be recorded when capturing a video. Should + // only be called before recording starts, otherwise it has no effect. + void SetAudioRecordingEnabled(bool enabled); + private: // Sets the capture mode type to a video capture if |for_video| is true, or // image capture otherwise.
diff --git a/ash/public/cpp/holding_space/holding_space_image.cc b/ash/public/cpp/holding_space/holding_space_image.cc index cf96ae3..8453f69b 100644 --- a/ash/public/cpp/holding_space/holding_space_image.cc +++ b/ash/public/cpp/holding_space/holding_space_image.cc
@@ -37,7 +37,7 @@ // When missing the cache, asynchronously resolve the bitmap for `scale`. async_bitmap_resolver_.Run( - gfx::ScaleToCeiledSize(placeholder_.size(), scale), + gfx::ScaleToCeiledSize(placeholder_.size(), scale), scale, base::BindOnce(&ImageSkiaSource::CacheImageForScale, weak_factory_.GetWeakPtr(), scale));
diff --git a/ash/public/cpp/holding_space/holding_space_image.h b/ash/public/cpp/holding_space/holding_space_image.h index f778b42..e614d82 100644 --- a/ash/public/cpp/holding_space/holding_space_image.h +++ b/ash/public/cpp/holding_space/holding_space_image.h
@@ -24,8 +24,8 @@ using BitmapCallback = base::OnceCallback<void(const SkBitmap*)>; // Returns a bitmap asynchronously for a given size. - using AsyncBitmapResolver = - base::RepeatingCallback<void(const gfx::Size&, BitmapCallback)>; + using AsyncBitmapResolver = base::RepeatingCallback< + void(const gfx::Size&, float scale_factor, BitmapCallback)>; HoldingSpaceImage(const gfx::ImageSkia& placeholder, AsyncBitmapResolver async_bitmap_resolver);
diff --git a/ash/services/recording/public/mojom/recording_service.mojom b/ash/services/recording/public/mojom/recording_service.mojom index 00de7abc..f53cbea 100644 --- a/ash/services/recording/public/mojom/recording_service.mojom +++ b/ash/services/recording/public/mojom/recording_service.mojom
@@ -37,9 +37,10 @@ // Note that a maximum of one screen recording can be done at any time. interface RecordingService { // All the below Record*() interfaces, take a pending remote to a client (e.g. - // Ash) to which it will send the muxed video chunks, and two other pending - // remotes bound to the video capturer on Viz on the GPU process, and to the - // audio stream factory on the Audio Service respectively. + // Ash) to which it will send the muxed video chunks, a pending remote bound + // to the video capturer on Viz on the GPU process, and another *optional* + // pending remote to the audio stream factory on the Audio Service, which if + // not provided, the service will not record audio. // Starts a fullscreen recording of a root window which has the given // |frame_sink_id|. The resulting video will have a resolution equal to the @@ -50,7 +51,7 @@ RecordFullscreen( pending_remote<RecordingServiceClient> client, pending_remote<viz.mojom.FrameSinkVideoCapturer> video_capturer, - pending_remote<audio.mojom.StreamFactory> audio_stream_factory, + pending_remote<audio.mojom.StreamFactory>? audio_stream_factory, viz.mojom.FrameSinkId frame_sink_id, gfx.mojom.Size video_size); @@ -65,7 +66,7 @@ RecordWindow( pending_remote<RecordingServiceClient> client, pending_remote<viz.mojom.FrameSinkVideoCapturer> video_capturer, - pending_remote<audio.mojom.StreamFactory> audio_stream_factory, + pending_remote<audio.mojom.StreamFactory>? audio_stream_factory, viz.mojom.FrameSinkId frame_sink_id, gfx.mojom.Size initial_video_size, gfx.mojom.Size max_video_size); @@ -78,7 +79,7 @@ RecordRegion( pending_remote<RecordingServiceClient> client, pending_remote<viz.mojom.FrameSinkVideoCapturer> video_capturer, - pending_remote<audio.mojom.StreamFactory> audio_stream_factory, + pending_remote<audio.mojom.StreamFactory>? audio_stream_factory, viz.mojom.FrameSinkId frame_sink_id, gfx.mojom.Size full_capture_size, gfx.mojom.Rect crop_region);
diff --git a/ash/services/recording/recording_encoder_muxer.cc b/ash/services/recording/recording_encoder_muxer.cc index 10b97d7..109bf36 100644 --- a/ash/services/recording/recording_encoder_muxer.cc +++ b/ash/services/recording/recording_encoder_muxer.cc
@@ -36,7 +36,7 @@ base::SequenceBound<RecordingEncoderMuxer> RecordingEncoderMuxer::Create( scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, const media::VideoEncoder::Options& video_encoder_options, - const media::AudioParameters& audio_input_params, + const media::AudioParameters* audio_input_params, media::WebmMuxer::WriteDataCB muxer_output_callback, FailureCallback on_failure_callback) { return base::SequenceBound<RecordingEncoderMuxer>( @@ -70,9 +70,10 @@ std::unique_ptr<media::AudioBus> audio_bus, base::TimeTicks capture_time) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(audio_encoder_); if (!did_failure_occur()) - audio_encoder_.EncodeAudio(*audio_bus, capture_time); + audio_encoder_->EncodeAudio(*audio_bus, capture_time); } void RecordingEncoderMuxer::FlushAndFinalize(base::OnceClosure on_done) { @@ -82,7 +83,8 @@ // it will result in OnAudioEncoded() being called directly (if any audio // frames were still buffered and not processed). The video encoder responds // asynchronously. - audio_encoder_.Flush(); + if (audio_encoder_) + audio_encoder_->Flush(); video_encoder_.Flush( base::BindOnce(&RecordingEncoderMuxer::OnVideoEncoderFlushed, base::Unretained(this), std::move(on_done))); @@ -90,21 +92,24 @@ RecordingEncoderMuxer::RecordingEncoderMuxer( const media::VideoEncoder::Options& video_encoder_options, - const media::AudioParameters& audio_input_params, + const media::AudioParameters* audio_input_params, media::WebmMuxer::WriteDataCB muxer_output_callback, FailureCallback on_failure_callback) : audio_encoder_( - audio_input_params, - base::BindRepeating(&RecordingEncoderMuxer::OnAudioEncoded, - base::Unretained(this)), - base::BindRepeating(&RecordingEncoderMuxer::OnEncoderStatus, - base::Unretained(this), - /*for_video=*/false), - // 0 means the encoder picks bitrate automatically. - /*bits_per_second=*/0), + !audio_input_params + ? nullptr + : std::make_unique<media::AudioOpusEncoder>( + *audio_input_params, + base::BindRepeating(&RecordingEncoderMuxer::OnAudioEncoded, + base::Unretained(this)), + base::BindRepeating(&RecordingEncoderMuxer::OnEncoderStatus, + base::Unretained(this), + /*for_video=*/false), + // 0 means the encoder picks bitrate automatically. + /*bits_per_second=*/0)), webm_muxer_(media::kCodecOpus, /*has_video_=*/true, - /*has_audio_=*/true, + /*has_audio_=*/!!audio_input_params, muxer_output_callback), on_failure_callback_(std::move(on_failure_callback)) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -175,6 +180,7 @@ void RecordingEncoderMuxer::OnAudioEncoded( media::EncodedAudioBuffer encoded_audio) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(audio_encoder_); // TODO(crbug.com/1143798): Explore changing the WebmMuxer so it doesn't work // with strings, to avoid copying the encoded data.
diff --git a/ash/services/recording/recording_encoder_muxer.h b/ash/services/recording/recording_encoder_muxer.h index 211e771..9c714a6 100644 --- a/ash/services/recording/recording_encoder_muxer.h +++ b/ash/services/recording/recording_encoder_muxer.h
@@ -5,6 +5,8 @@ #ifndef ASH_SERVICES_RECORDING_RECORDING_ENCODER_MUXER_H_ #define ASH_SERVICES_RECORDING_RECORDING_ENCODER_MUXER_H_ +#include <memory> + #include "base/callback_forward.h" #include "base/containers/circular_deque.h" #include "base/containers/queue.h" @@ -56,6 +58,8 @@ // |blocking_task_runner| on which all operations as well as destruction will // happen. |video_encoder_options| and |audio_input_params| will be used to // initialize the video and audio encoders respectively. + // If |audio_input_params| is nullptr, then the service is not recording + // audio, and the muxer will be initialized accordingly. // |muxer_output_callback| will be called on the same sequence of // |blocking_task_runner| to provide the muxer output chunks ready to be sent // to the recording service client. @@ -65,7 +69,7 @@ static base::SequenceBound<RecordingEncoderMuxer> Create( scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, const media::VideoEncoder::Options& video_encoder_options, - const media::AudioParameters& audio_input_params, + const media::AudioParameters* audio_input_params, media::WebmMuxer::WriteDataCB muxer_output_callback, FailureCallback on_failure_callback); @@ -95,7 +99,7 @@ RecordingEncoderMuxer( const media::VideoEncoder::Options& video_encoder_options, - const media::AudioParameters& audio_input_params, + const media::AudioParameters* audio_input_params, media::WebmMuxer::WriteDataCB muxer_output_callback, FailureCallback on_failure_callback); ~RecordingEncoderMuxer(); @@ -136,7 +140,8 @@ media::VpxVideoEncoder video_encoder_ GUARDED_BY_CONTEXT(sequence_checker_); - media::AudioOpusEncoder audio_encoder_ GUARDED_BY_CONTEXT(sequence_checker_); + std::unique_ptr<media::AudioOpusEncoder> audio_encoder_ + GUARDED_BY_CONTEXT(sequence_checker_); media::WebmMuxer webm_muxer_ GUARDED_BY_CONTEXT(sequence_checker_);
diff --git a/ash/services/recording/recording_service.cc b/ash/services/recording/recording_service.cc index fac3f24..e92da981 100644 --- a/ash/services/recording/recording_service.cc +++ b/ash/services/recording/recording_service.cc
@@ -16,7 +16,6 @@ #include "base/time/time.h" #include "media/audio/audio_device_description.h" #include "media/base/audio_codecs.h" -#include "media/base/audio_parameters.h" #include "media/base/status.h" #include "media/base/video_frame.h" #include "media/capture/mojom/video_capture_types.mojom.h" @@ -63,7 +62,8 @@ RecordingService::RecordingService( mojo::PendingReceiver<mojom::RecordingService> receiver) - : receiver_(this, std::move(receiver)), + : audio_parameters_(GetAudioParameters()), + receiver_(this, std::move(receiver)), consumer_receiver_(this), main_task_runner_(base::ThreadTaskRunnerHandle::Get()), encoding_task_runner_(base::ThreadPool::CreateSequencedTaskRunner( @@ -126,7 +126,8 @@ void RecordingService::StopRecording() { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); video_capturer_remote_->Stop(); - audio_capturer_->Stop(); + if (audio_capturer_) + audio_capturer_->Stop(); audio_capturer_.reset(); } @@ -260,9 +261,11 @@ // a keyframe if one has not been coded in the last keyframe_interval frames. video_encoder_options.keyframe_interval = 100; - const auto audio_params = GetAudioParameters(); + const bool should_record_audio = audio_stream_factory.is_valid(); + encoder_muxer_ = RecordingEncoderMuxer::Create( - encoding_task_runner_, video_encoder_options, audio_params, + encoding_task_runner_, video_encoder_options, + should_record_audio ? &audio_parameters_ : nullptr, base::BindRepeating(&RecordingService::OnMuxerWrite, base::Unretained(this)), base::BindOnce(&RecordingService::OnEncodingFailure, @@ -270,12 +273,15 @@ ConnectAndStartVideoCapturer(std::move(video_capturer)); + if (!should_record_audio) + return; + audio_capturer_ = audio::CreateInputDevice( std::move(audio_stream_factory), std::string(media::AudioDeviceDescription::kDefaultDeviceId), audio::DeadStreamDetection::kEnabled); DCHECK(audio_capturer_); - audio_capturer_->Initialize(audio_params, this); + audio_capturer_->Initialize(audio_parameters_, this); audio_capturer_->Start(); } @@ -316,7 +322,8 @@ // capturer. We will stop the recording and flush whatever video chunks we // currently have. did_failure_occur_ = true; - audio_capturer_->Stop(); + if (audio_capturer_) + audio_capturer_->Stop(); audio_capturer_.reset(); TerminateRecording(/*success=*/false); } @@ -326,6 +333,7 @@ base::TimeTicks audio_capture_time) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); DCHECK(encoder_muxer_); + DCHECK(audio_capturer_); // We ignore any subsequent frames after a failure. if (did_failure_occur_)
diff --git a/ash/services/recording/recording_service.h b/ash/services/recording/recording_service.h index 0857274a..79f8dc6 100644 --- a/ash/services/recording/recording_service.h +++ b/ash/services/recording/recording_service.h
@@ -18,7 +18,9 @@ #include "base/thread_annotations.h" #include "base/threading/sequence_bound.h" #include "base/threading/thread_checker.h" +#include "media/base/audio_bus.h" #include "media/base/audio_capturer_source.h" +#include "media/base/audio_parameters.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -144,6 +146,9 @@ // reset the |number_of_buffered_chunks_| back to 0. void FlushBufferedChunks(); + // The audio parameters that will be used when recording audio. + const media::AudioParameters audio_parameters_; + // The mojo receiving end of the service. mojo::Receiver<mojom::RecordingService> receiver_; @@ -179,7 +184,8 @@ mojo::Remote<viz::mojom::FrameSinkVideoCapturer> video_capturer_remote_ GUARDED_BY_CONTEXT(main_thread_checker_); - // The audio capturer instance. + // The audio capturer instance. It is created only if the service is requested + // to record audio along side the video. scoped_refptr<media::AudioCapturerSource> audio_capturer_ GUARDED_BY_CONTEXT(main_thread_checker_);
diff --git a/ash/system/dark_mode/dark_mode_detailed_view.cc b/ash/system/dark_mode/dark_mode_detailed_view.cc index a03eec9..d6b95297 100644 --- a/ash/system/dark_mode/dark_mode_detailed_view.cc +++ b/ash/system/dark_mode/dark_mode_detailed_view.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "ash/system/dark_mode/dark_mode_detailed_view.h" +#include <cstddef> #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" @@ -120,8 +121,10 @@ void DarkModeDetailedView::OnThemeChanged() { TrayDetailedView::OnThemeChanged(); - themed_label_->SetEnabledColor(GetLabelColor()); - neutral_label_->SetEnabledColor(GetLabelColor()); + TrayPopupUtils::SetLabelFontList(themed_label_, + TrayPopupUtils::FontStyle::kSystemInfo); + TrayPopupUtils::SetLabelFontList(neutral_label_, + TrayPopupUtils::FontStyle::kSystemInfo); TrayPopupUtils::UpdateToggleButtonColors(toggle_); }
diff --git a/ash/system/ime_menu/ime_menu_tray.cc b/ash/system/ime_menu/ime_menu_tray.cc index 88b7c46..b4d4c60 100644 --- a/ash/system/ime_menu/ime_menu_tray.cc +++ b/ash/system/ime_menu/ime_menu_tray.cc
@@ -135,7 +135,7 @@ title_label->SetEnabledColor(color_provider->GetContentLayerColor( AshColorProvider::ContentLayerType::kTextColorPrimary)); TrayPopupUtils::SetLabelFontList(title_label, - TrayPopupUtils::FontStyle::kSubHeader); + TrayPopupUtils::FontStyle::kPodMenuHeader); layout_ptr->SetFlexForView(title_label, 1); settings_button_ = AddChildView(std::make_unique<TopShortcutButton>(
diff --git a/ash/system/palette/palette_tray.cc b/ash/system/palette/palette_tray.cc index 7e92c32..03ad6bd 100644 --- a/ash/system/palette/palette_tray.cc +++ b/ash/system/palette/palette_tray.cc
@@ -105,7 +105,7 @@ title_label->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( AshColorProvider::ContentLayerType::kTextColorPrimary)); TrayPopupUtils::SetLabelFontList(title_label, - TrayPopupUtils::FontStyle::kSmallTitle); + TrayPopupUtils::FontStyle::kPodMenuHeader); layout_ptr->SetFlexForView(title_label, 1); help_button_ = AddChildView(std::make_unique<TopShortcutButton>( base::BindRepeating(
diff --git a/ash/system/tray/tray_popup_utils.cc b/ash/system/tray/tray_popup_utils.cc index 9640a4a..94bfe55 100644 --- a/ash/system/tray/tray_popup_utils.cc +++ b/ash/system/tray/tray_popup_utils.cc
@@ -369,21 +369,30 @@ void TrayPopupUtils::SetLabelFontList(views::Label* label, FontStyle style) { label->SetAutoColorReadabilityEnabled(false); - const gfx::FontList& base_font_list = views::Label::GetDefaultFontList(); + const gfx::FontList google_sans_font_list({"Google Sans"}, gfx::Font::NORMAL, + 16, gfx::Font::Weight::MEDIUM); + const gfx::FontList roboto_font_list({"Roboto"}, gfx::Font::NORMAL, 16, + gfx::Font::Weight::MEDIUM); + switch (style) { case FontStyle::kTitle: - label->SetFontList(base_font_list.Derive(8, gfx::Font::NORMAL, - gfx::Font::Weight::MEDIUM)); + label->SetFontList(google_sans_font_list); + break; + case FontStyle::kPodMenuHeader: + label->SetFontList(roboto_font_list); break; case FontStyle::kSubHeader: - label->SetFontList(base_font_list.Derive(4, gfx::Font::NORMAL, - gfx::Font::Weight::MEDIUM)); + label->SetFontList(roboto_font_list.Derive(-1, gfx::Font::NORMAL, + gfx::Font::Weight::MEDIUM)); break; case FontStyle::kSmallTitle: + label->SetFontList(roboto_font_list.Derive(-3, gfx::Font::NORMAL, + gfx::Font::Weight::MEDIUM)); + break; case FontStyle::kDetailedViewLabel: case FontStyle::kSystemInfo: - label->SetFontList(base_font_list.Derive(1, gfx::Font::NORMAL, - gfx::Font::Weight::NORMAL)); + label->SetFontList(roboto_font_list.Derive(-4, gfx::Font::NORMAL, + gfx::Font::Weight::NORMAL)); break; } }
diff --git a/ash/system/tray/tray_popup_utils.h b/ash/system/tray/tray_popup_utils.h index 8f8d3c79..a0a62bd 100644 --- a/ash/system/tray/tray_popup_utils.h +++ b/ash/system/tray/tray_popup_utils.h
@@ -38,7 +38,9 @@ enum class FontStyle { // Topmost header rows for default view and detailed view. kTitle, - // Topmost header rows for secondary tray bubbles. + // Topmost header for secondary tray bubbles + kPodMenuHeader, + // Small title used for selections in tray bubbles. kSmallTitle, // Text in sub-section header rows in detailed views. kSubHeader,
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 2d04c66..3a8aa58 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -1215,6 +1215,7 @@ params.name = "OverviewNoWindowsLabel"; params.horizontal_padding = kNoItemsIndicatorHorizontalPaddingDp; params.vertical_padding = kNoItemsIndicatorVerticalPaddingDp; + params.rounding_dp = kNoItemsIndicatorRoundingDp; auto* color_provider = AshColorProvider::Get(); params.background_color = color_provider->GetBaseLayerColor( AshColorProvider::BaseLayerType::kTransparent80); @@ -1227,10 +1228,6 @@ params.hide_in_mini_view = true; no_windows_widget_ = std::make_unique<RoundedLabelWidget>(); no_windows_widget_->Init(std::move(params)); - no_windows_widget_->GetLayer()->SetRoundedCornerRadius( - gfx::RoundedCornersF(kNoItemsIndicatorRoundingDp)); - no_windows_widget_->GetLayer()->SetBackgroundBlur( - static_cast<float>(AshColorProvider::LayerBlurSigma::kBlurDefault)); aura::Window* widget_window = no_windows_widget_->GetNativeWindow(); widget_window->parent()->StackChildAtBottom(widget_window);
diff --git a/ash/wm/overview/rounded_label_widget.cc b/ash/wm/overview/rounded_label_widget.cc index 31fa3615..e229b6b 100644 --- a/ash/wm/overview/rounded_label_widget.cc +++ b/ash/wm/overview/rounded_label_widget.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/public/cpp/window_properties.h" +#include "ash/style/ash_color_provider.h" #include "ash/wm/overview/scoped_overview_animation_settings.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" @@ -42,7 +43,8 @@ SetBackgroundColor(background_color); SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); - + layer()->SetBackgroundBlur( + static_cast<float>(AshColorProvider::LayerBlurSigma::kBlurDefault)); const gfx::RoundedCornersF radii(rounding_dp); layer()->SetRoundedCornerRadius(radii); layer()->SetIsFastRoundedCorner(true);
diff --git a/base/system/sys_info.h b/base/system/sys_info.h index 2884804..61df0ad 100644 --- a/base/system/sys_info.h +++ b/base/system/sys_info.h
@@ -161,10 +161,14 @@ // Returns true when actually running in a Chrome OS environment. static bool IsRunningOnChromeOS(); - // Test method to force re-parsing of lsb-release. + // Overrides |lsb_release| and |lsb_release_time|. Overrides cannot be nested. + // Call ResetChromeOSVersionInfoForTest() to restore the previous values. static void SetChromeOSVersionInfoForTest(const std::string& lsb_release, const Time& lsb_release_time); + // Undoes the function above. + static void ResetChromeOSVersionInfoForTest(); + // Returns the kernel version of the host operating system. static std::string KernelVersion();
diff --git a/base/system/sys_info_chromeos.cc b/base/system/sys_info_chromeos.cc index e8d2b48..aefbb33 100644 --- a/base/system/sys_info_chromeos.cc +++ b/base/system/sys_info_chromeos.cc
@@ -12,7 +12,7 @@ #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util.h" -#include "base/lazy_instance.h" +#include "base/no_destructor.h" #include "base/notreached.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" @@ -156,11 +156,18 @@ bool is_running_on_chromeos_; }; -static LazyInstance<ChromeOSVersionInfo>::Leaky g_chrome_os_version_info = - LAZY_INSTANCE_INITIALIZER; +bool g_use_chromeos_version_info_for_test = false; ChromeOSVersionInfo& GetChromeOSVersionInfo() { - return g_chrome_os_version_info.Get(); + // ChromeOSVersionInfo only stores the parsed lsb-release values. We use a + // second instance for overrides in tests so we can cleanly restore the + // original lsb-release. + if (g_use_chromeos_version_info_for_test) { + static base::NoDestructor<ChromeOSVersionInfo> version_info_for_test; + return *version_info_for_test; + } + static base::NoDestructor<ChromeOSVersionInfo> version_info; + return *version_info; } } // namespace @@ -229,10 +236,18 @@ // static void SysInfo::SetChromeOSVersionInfoForTest(const std::string& lsb_release, const Time& lsb_release_time) { + DCHECK(!g_use_chromeos_version_info_for_test) << "Nesting is not allowed"; + g_use_chromeos_version_info_for_test = true; std::unique_ptr<Environment> env(Environment::Create()); env->SetVar(kLsbReleaseKey, lsb_release); env->SetVar(kLsbReleaseTimeKey, NumberToString(lsb_release_time.ToDoubleT())); - g_chrome_os_version_info.Get().Parse(); + GetChromeOSVersionInfo().Parse(); +} + +// static +void SysInfo::ResetChromeOSVersionInfoForTest() { + DCHECK(g_use_chromeos_version_info_for_test); + g_use_chromeos_version_info_for_test = false; } // static
diff --git a/base/system/sys_info_unittest.cc b/base/system/sys_info_unittest.cc index 1604b54..e44745c 100644 --- a/base/system/sys_info_unittest.cc +++ b/base/system/sys_info_unittest.cc
@@ -17,6 +17,8 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/system/sys_info.h" +#include "base/test/scoped_chromeos_version_info.h" +#include "base/test/scoped_running_on_chromeos.h" #include "base/test/task_environment.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" @@ -223,7 +225,7 @@ const char kLsbRelease[] = "FOO=1234123.34.5\n" "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, Time()); + test::ScopedChromeOSVersionInfo version(kLsbRelease, Time()); SysInfo::OperatingSystemVersionNumbers(&os_major_version, &os_minor_version, &os_bugfix_version); EXPECT_EQ(1, os_major_version); @@ -238,7 +240,7 @@ const char kLsbRelease[] = "CHROMEOS_RELEASE_VERSION=1.2.3.4\n" "FOO=1234123.34.5\n"; - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, Time()); + test::ScopedChromeOSVersionInfo version(kLsbRelease, Time()); SysInfo::OperatingSystemVersionNumbers(&os_major_version, &os_minor_version, &os_bugfix_version); EXPECT_EQ(1, os_major_version); @@ -251,7 +253,7 @@ int32_t os_minor_version = -1; int32_t os_bugfix_version = -1; const char kLsbRelease[] = "FOO=1234123.34.5\n"; - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, Time()); + test::ScopedChromeOSVersionInfo version(kLsbRelease, Time()); SysInfo::OperatingSystemVersionNumbers(&os_major_version, &os_minor_version, &os_bugfix_version); EXPECT_EQ(0, os_major_version); @@ -263,61 +265,74 @@ const char kLsbRelease[] = "CHROMEOS_RELEASE_VERSION=1.2.3.4"; // Use a fake time that can be safely displayed as a string. const Time lsb_release_time(Time::FromDoubleT(12345.6)); - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, lsb_release_time); + test::ScopedChromeOSVersionInfo version(kLsbRelease, lsb_release_time); Time parsed_lsb_release_time = SysInfo::GetLsbReleaseTime(); EXPECT_DOUBLE_EQ(lsb_release_time.ToDoubleT(), parsed_lsb_release_time.ToDoubleT()); } TEST_F(SysInfoTest, IsRunningOnChromeOS) { - SysInfo::SetChromeOSVersionInfoForTest("", Time()); - EXPECT_FALSE(SysInfo::IsRunningOnChromeOS()); - - const char kLsbRelease1[] = - "CHROMEOS_RELEASE_NAME=Non Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease1, Time()); - EXPECT_FALSE(SysInfo::IsRunningOnChromeOS()); - - const char kLsbRelease2[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease2, Time()); - EXPECT_TRUE(SysInfo::IsRunningOnChromeOS()); - - const char kLsbRelease3[] = "CHROMEOS_RELEASE_NAME=Chromium OS\n"; - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease3, Time()); - EXPECT_TRUE(SysInfo::IsRunningOnChromeOS()); + { + const char kLsbRelease1[] = + "CHROMEOS_RELEASE_NAME=Non Chrome OS\n" + "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; + test::ScopedChromeOSVersionInfo version(kLsbRelease1, Time()); + EXPECT_FALSE(SysInfo::IsRunningOnChromeOS()); + } + { + const char kLsbRelease2[] = + "CHROMEOS_RELEASE_NAME=Chrome OS\n" + "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; + test::ScopedChromeOSVersionInfo version(kLsbRelease2, Time()); + EXPECT_TRUE(SysInfo::IsRunningOnChromeOS()); + } + { + const char kLsbRelease3[] = "CHROMEOS_RELEASE_NAME=Chromium OS\n"; + test::ScopedChromeOSVersionInfo version(kLsbRelease3, Time()); + EXPECT_TRUE(SysInfo::IsRunningOnChromeOS()); + } } TEST_F(SysInfoTest, CrashOnBaseImage) { - const char kLsbRelease2[] = + const char kLsbRelease[] = "CHROMEOS_RELEASE_NAME=Chrome OS\n" "CHROMEOS_RELEASE_VERSION=1.2.3.4\n" "CHROMEOS_RELEASE_TRACK=stable-channel\n"; - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease2, Time()); + test::ScopedChromeOSVersionInfo version(kLsbRelease, Time()); EXPECT_TRUE(SysInfo::IsRunningOnChromeOS()); EXPECT_DEATH_IF_SUPPORTED({ SysInfo::CrashIfChromeOSNonTestImage(); }, ""); } TEST_F(SysInfoTest, NoCrashOnTestImage) { - const char kLsbRelease2[] = + const char kLsbRelease[] = "CHROMEOS_RELEASE_NAME=Chrome OS\n" "CHROMEOS_RELEASE_VERSION=1.2.3.4\n" "CHROMEOS_RELEASE_TRACK=testimage-channel\n"; - SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease2, Time()); + test::ScopedChromeOSVersionInfo version(kLsbRelease, Time()); EXPECT_TRUE(SysInfo::IsRunningOnChromeOS()); // Should not crash. SysInfo::CrashIfChromeOSNonTestImage(); } TEST_F(SysInfoTest, NoCrashOnLinuxBuild) { - SysInfo::SetChromeOSVersionInfoForTest("", Time()); + test::ScopedChromeOSVersionInfo version("", Time()); EXPECT_FALSE(SysInfo::IsRunningOnChromeOS()); // Should not crash. SysInfo::CrashIfChromeOSNonTestImage(); } +TEST_F(SysInfoTest, ScopedRunningOnChromeOS) { + // base_unittests run both on linux-chromeos and actual devices, so the + // initial state of IsRunningOnChromeOS may vary. + bool was_running = SysInfo::IsRunningOnChromeOS(); + { + test::ScopedRunningOnChromeOS running_on_chromeos; + EXPECT_TRUE(SysInfo::IsRunningOnChromeOS()); + } + // Previous value restored. + EXPECT_EQ(was_running, SysInfo::IsRunningOnChromeOS()); +} + #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) } // namespace base
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index c395665..b823030 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/compiled_action.gni") +import("//build/config/chromeos/ui_mode.gni") import("//build/config/nacl/config.gni") import("//build/config/ui.gni") import("//build_overrides/build.gni") @@ -182,6 +183,15 @@ ] } + if (is_chromeos_ash || is_chromeos_lacros) { + sources += [ + "scoped_chromeos_version_info.cc", + "scoped_chromeos_version_info.h", + "scoped_running_on_chromeos.cc", + "scoped_running_on_chromeos.h", + ] + } + if (is_linux || is_chromeos) { sources += [ "test_file_util_linux.cc" ] public_deps += [ ":fontconfig_util_linux" ]
diff --git a/base/test/scoped_chromeos_version_info.cc b/base/test/scoped_chromeos_version_info.cc new file mode 100644 index 0000000..35ef9fa --- /dev/null +++ b/base/test/scoped_chromeos_version_info.cc
@@ -0,0 +1,23 @@ +// 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 "base/test/scoped_chromeos_version_info.h" + +#include "base/system/sys_info.h" + +namespace base { +namespace test { + +ScopedChromeOSVersionInfo::ScopedChromeOSVersionInfo(StringPiece lsb_release, + Time lsb_release_time) { + SysInfo::SetChromeOSVersionInfoForTest(lsb_release.as_string(), + lsb_release_time); +} + +ScopedChromeOSVersionInfo::~ScopedChromeOSVersionInfo() { + SysInfo::ResetChromeOSVersionInfoForTest(); +} + +} // namespace test +} // namespace base
diff --git a/base/test/scoped_chromeos_version_info.h b/base/test/scoped_chromeos_version_info.h new file mode 100644 index 0000000..c392c38 --- /dev/null +++ b/base/test/scoped_chromeos_version_info.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 BASE_TEST_SCOPED_CHROMEOS_VERSION_INFO_H_ +#define BASE_TEST_SCOPED_CHROMEOS_VERSION_INFO_H_ + +#include "base/strings/string_piece.h" +#include "base/time/time.h" + +namespace base { +namespace test { + +// Test helper that temporarily overrides the cached lsb-release data. +// NOTE: Must be created on the main thread before any other threads are +// started. Cannot be nested. +class ScopedChromeOSVersionInfo { + public: + // Overrides |lsb_release| and |lsb_release_time|. For example, can be used to + // simulate a specific OS version. Note that |lsb_release| must contain + // CHROMEOS_RELEASE_NAME to make base::SysInfo::IsRunningOnChromeOS() return + // true. + ScopedChromeOSVersionInfo(StringPiece lsb_release, Time lsb_release_time); + ScopedChromeOSVersionInfo(const ScopedChromeOSVersionInfo&) = delete; + ScopedChromeOSVersionInfo& operator=(const ScopedChromeOSVersionInfo&) = + delete; + ~ScopedChromeOSVersionInfo(); +}; + +} // namespace test +} // namespace base + +#endif // BASE_TEST_SCOPED_CHROMEOS_VERSION_INFO_H_
diff --git a/base/test/scoped_running_on_chromeos.cc b/base/test/scoped_running_on_chromeos.cc new file mode 100644 index 0000000..d171d23 --- /dev/null +++ b/base/test/scoped_running_on_chromeos.cc
@@ -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. + +#include "base/test/scoped_running_on_chromeos.h" + +#include "base/system/sys_info.h" +#include "base/time/time.h" + +namespace base { +namespace test { +namespace { + +// Chrome OS /etc/lsb-release values that make SysInfo::IsRunningOnChromeOS() +// return true. +const char kLsbRelease[] = + "CHROMEOS_RELEASE_NAME=Chrome OS\n" + "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; + +} // namespace + +ScopedRunningOnChromeOS::ScopedRunningOnChromeOS() { + SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, Time()); +} + +ScopedRunningOnChromeOS::~ScopedRunningOnChromeOS() { + SysInfo::ResetChromeOSVersionInfoForTest(); +} + +} // namespace test +} // namespace base
diff --git a/base/test/scoped_running_on_chromeos.h b/base/test/scoped_running_on_chromeos.h new file mode 100644 index 0000000..1b4da38 --- /dev/null +++ b/base/test/scoped_running_on_chromeos.h
@@ -0,0 +1,25 @@ +// 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 BASE_TEST_SCOPED_RUNNING_ON_CHROMEOS_H_ +#define BASE_TEST_SCOPED_RUNNING_ON_CHROMEOS_H_ + +namespace base { +namespace test { + +// Test helper that forces base::SysInfo::IsRunningOnChromeOS() to return true. +// NOTE: Must be created on the main thread before any other threads are +// started. Cannot be nested. +class ScopedRunningOnChromeOS { + public: + ScopedRunningOnChromeOS(); + ScopedRunningOnChromeOS(const ScopedRunningOnChromeOS&) = delete; + ScopedRunningOnChromeOS& operator=(const ScopedRunningOnChromeOS&) = delete; + ~ScopedRunningOnChromeOS(); +}; + +} // namespace test +} // namespace base + +#endif // BASE_TEST_SCOPED_RUNNING_ON_CHROMEOS_H_
diff --git a/build/android/docs/lint.md b/build/android/docs/lint.md index 7e68e52..4ba13d7 100644 --- a/build/android/docs/lint.md +++ b/build/android/docs/lint.md
@@ -86,6 +86,11 @@ [build/android/gyp/lint.py](https://source.chromium.org/chromium/chromium/src/+/master:build/android/gyp/lint.py). Disabling globally makes lint a bit faster. +The exception to the above rule is for warnings that affect multiple languages. +Feel free to suppress those in lint-suppressions.xml files since it is not +practical to suppress them in each language file and it is a lot of extra bloat +to list out every language for every violation in lint-baseline.xml files. + Here is an example of how to structure a suppressions XML file: ```xml
diff --git a/build/android/gyp/desugar.py b/build/android/gyp/desugar.py index 6d2a234..1df7bf7 100755 --- a/build/android/gyp/desugar.py +++ b/build/android/gyp/desugar.py
@@ -21,7 +21,9 @@ help='Jar input path to include .class files from.') parser.add_argument('--output-jar', required=True, help='Jar output path.') - parser.add_argument('--classpath', required=True, + parser.add_argument('--classpath', + action='append', + required=True, help='Classpath.') parser.add_argument('--bootclasspath', required=True, help='Path to javac bootclasspath interface jar.')
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 15707eb..ea43332 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -2050,6 +2050,11 @@ "--depfile", rebase_path(depfile, root_build_dir), ] + if (defined(invoker.desugar_jars_paths)) { + _rebased_desugar_jars_paths = + rebase_path(invoker.desugar_jars_paths, root_build_dir) + args += [ "--classpath=${_rebased_desugar_jars_paths}" ] + } if (treat_warnings_as_errors) { args += [ "--warnings-as-errors" ] } @@ -3447,6 +3452,9 @@ # input_jars_paths: Optional list of additional .jar file paths, which will # be added to the compile-time classpath when building this target (but # not to the runtime classpath). + # desugar_jars_paths: Optional list of additional .jar file paths, which will + # be added to the desugar classpath when building this target (but not to + # any other classpath). This is only used to break dependency cycles. # gradle_treat_as_prebuilt: Cause generate_gradle.py to reference this # library via its built .jar rather than including its .java sources. # proguard_enabled: Optional. True to enable ProGuard obfuscation. @@ -4063,6 +4071,9 @@ enable_desugar = _enable_desugar && enable_bazel_desugar if (enable_desugar) { classpath_deps = _full_classpath_deps + if (defined(invoker.desugar_jars_paths)) { + desugar_jars_paths = invoker.desugar_jars_paths + } } } if (defined(invoker.enable_jetify) && invoker.enable_jetify) {
diff --git a/build/config/coverage/OWNERS b/build/config/coverage/OWNERS index 3583b2a8..0fc481f 100644 --- a/build/config/coverage/OWNERS +++ b/build/config/coverage/OWNERS
@@ -1,4 +1,3 @@ inferno@chromium.org liaoyuke@chromium.org -mmoroz@chromium.org ochang@chromium.org
diff --git a/build/config/sanitizers/OWNERS b/build/config/sanitizers/OWNERS index 0a25a01..f6a122b 100644 --- a/build/config/sanitizers/OWNERS +++ b/build/config/sanitizers/OWNERS
@@ -1,4 +1,3 @@ inferno@chromium.org metzman@chromium.org -mmoroz@chromium.org ochang@chromium.org
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 5df48ad..66fdedf 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20201120.1.1 +0.20201120.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 5df48ad..66fdedf 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20201120.1.1 +0.20201120.3.1
diff --git a/build/fuchsia/symbolizer.py b/build/fuchsia/symbolizer.py index e9732c6..7db9fc9f 100644 --- a/build/fuchsia/symbolizer.py +++ b/build/fuchsia/symbolizer.py
@@ -4,19 +4,48 @@ import logging import os +import re import subprocess from common import SDK_ROOT from common import GetHostArchFromPlatform from common import GetHostToolPathFromPlatform -# TODO(crbug.com/1131647): Change 'llvm-3.8' to 'llvm' after docker image is -# updated. -ARM64_DOCKER_LLVM_SYMBOLIZER_PATH = os.path.join('/', 'usr', 'lib', 'llvm-3.8', +# Paths to the llvm-symbolizer executable in different test hosts. +X64_LLVM_SYMBOLIZER_PATH = os.path.join(SDK_ROOT, os.pardir, os.pardir, + 'llvm-build', 'Release+Asserts', 'bin', + 'llvm-symbolizer') +ARM64_XENIAL_LLVM_SYMBOLIZER_PATH = os.path.join('/', 'usr', 'lib', 'llvm-3.8', + 'bin', 'llvm-symbolizer') +ARM64_BIONIC_LLVM_SYMBOLIZER_PATH = os.path.join('/', 'usr', 'lib', 'llvm-6.0', 'bin', 'llvm-symbolizer') + +def _GetLLVMSymbolizerPath(): + """Determines the path to the LLVM symbolizer executable based on test host + architecture and Ubuntu distro.""" + + if GetHostArchFromPlatform() == 'x64': + return X64_LLVM_SYMBOLIZER_PATH + + # Get distro codename from /etc/os-release. + with open(os.path.join('/', 'etc', 'os-release')) as os_release_file: + os_release_text = os_release_file.read() + version_codename_re = r'^VERSION_CODENAME=(?P<codename>[\w.-]+)$' + match = re.search(version_codename_re, os_release_text, re.MULTILINE) + codename = match.group('codename') if match else None + + if codename == 'xenial': + return ARM64_XENIAL_LLVM_SYMBOLIZER_PATH + elif codename == 'bionic': + return ARM64_BIONIC_LLVM_SYMBOLIZER_PATH + else: + raise Exception('Unknown Ubuntu release "%s"' % codename) + + def BuildIdsPaths(package_paths): - """Generate build ids paths for symbolizer processes.""" + """Generates build ids paths for symbolizer processes.""" + build_ids_paths = map( lambda package_path: os.path.join( os.path.dirname(package_path), 'ids.txt'), @@ -33,15 +62,8 @@ unstripped binaries on the filesystem. Returns a Popen object for the started process.""" - if (GetHostArchFromPlatform() == 'arm64' and - os.path.isfile(ARM64_DOCKER_LLVM_SYMBOLIZER_PATH)): - llvm_symbolizer_path = ARM64_DOCKER_LLVM_SYMBOLIZER_PATH - else: - llvm_symbolizer_path = os.path.join(SDK_ROOT, os.pardir, os.pardir, - 'llvm-build', 'Release+Asserts', 'bin', - 'llvm-symbolizer') - symbolizer = GetHostToolPathFromPlatform('symbolize') + llvm_symbolizer_path = _GetLLVMSymbolizerPath() symbolizer_cmd = [symbolizer, '-ids-rel', '-llvm-symbolizer', llvm_symbolizer_path, '-build-id-dir', os.path.join(SDK_ROOT, '.build-id')]
diff --git a/build/sanitizers/OWNERS b/build/sanitizers/OWNERS index e9a248c..85a810a 100644 --- a/build/sanitizers/OWNERS +++ b/build/sanitizers/OWNERS
@@ -4,7 +4,6 @@ inferno@chromium.org mbarbella@chromium.org metzman@chromium.org -mmoroz@chromium.org rnk@chromium.org per-file tsan_suppressions.cc=* per-file lsan_suppressions.cc=*
diff --git a/build/toolchain/OWNERS b/build/toolchain/OWNERS index 39669b3..d7012d39 100644 --- a/build/toolchain/OWNERS +++ b/build/toolchain/OWNERS
@@ -1,9 +1,5 @@ dpranke@google.com scottmg@chromium.org -# Clang Static Analyzer. -per-file clang_static_analyzer*=mmoroz@chromium.org - # Code Coverage. -per-file *code_coverage*=mmoroz@chromium.org per-file *code_coverage*=liaoyuke@chromium.org
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index 5dfca52..0f76c1a 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -45,78 +45,6 @@ namespace cc { namespace { -class ScopedSkSurfaceForUnpremultiplyAndDither { - public: - ScopedSkSurfaceForUnpremultiplyAndDither( - viz::RasterContextProvider* context_provider, - sk_sp<SkColorSpace> color_space, - const gfx::Rect& playback_rect, - const gfx::Rect& raster_full_rect, - const gfx::Size& max_tile_size, - GLuint texture_id, - const gfx::Size& texture_size, - bool can_use_lcd_text, - int msaa_sample_count) - : context_provider_(context_provider), - texture_id_(texture_id), - offset_(playback_rect.OffsetFromOrigin() - - raster_full_rect.OffsetFromOrigin()), - size_(playback_rect.size()) { - // Determine the |intermediate_size| to use for our 32-bit texture. If we - // know the max tile size, use that. This prevents GPU cache explosion due - // to using lots of different 32-bit texture sizes. Otherwise just use the - // exact size of the target texture. - gfx::Size intermediate_size; - if (!max_tile_size.IsEmpty()) { - DCHECK_GE(max_tile_size.width(), texture_size.width()); - DCHECK_GE(max_tile_size.height(), texture_size.height()); - intermediate_size = max_tile_size; - } else { - intermediate_size = texture_size; - } - - // Allocate a 32-bit surface for raster. We will copy from that into our - // actual surface in destruction. - SkImageInfo n32Info = SkImageInfo::MakeN32Premul(intermediate_size.width(), - intermediate_size.height(), - std::move(color_space)); - SkSurfaceProps surface_props = - skia::LegacyDisplayGlobals::ComputeSurfaceProps(can_use_lcd_text); - surface_ = SkSurface::MakeRenderTarget( - context_provider->GrContext(), SkBudgeted::kNo, n32Info, - msaa_sample_count, kTopLeft_GrSurfaceOrigin, &surface_props); - } - - ~ScopedSkSurfaceForUnpremultiplyAndDither() { - // In lost-context cases, |surface_| may be null and there's nothing - // meaningful to do here. - if (!surface_) - return; - - GrBackendTexture backend_texture = - surface_->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess); - if (!backend_texture.isValid()) { - return; - } - GrGLTextureInfo info; - if (!backend_texture.getGLTextureInfo(&info)) { - return; - } - context_provider_->ContextGL()->UnpremultiplyAndDitherCopyCHROMIUM( - info.fID, texture_id_, offset_.x(), offset_.y(), size_.width(), - size_.height()); - } - - SkSurface* surface() { return surface_.get(); } - - private: - viz::RasterContextProvider* context_provider_; - GLuint texture_id_; - gfx::Vector2d offset_; - gfx::Size size_; - sk_sp<SkSurface> surface_; -}; - static void RasterizeSourceOOP( const RasterSource* raster_source, bool resource_has_previous_content, @@ -186,7 +114,6 @@ const gfx::AxisTransform2d& transform, const RasterSource::PlaybackSettings& playback_settings, viz::RasterContextProvider* context_provider, - bool unpremultiply_and_dither, const gfx::Size& max_tile_size) { gpu::raster::RasterInterface* ri = context_provider->RasterInterface(); if (mailbox->IsZero()) { @@ -211,26 +138,15 @@ texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); { ScopedGrContextAccess gr_context_access(context_provider); - base::Optional<viz::ClientResourceProvider::ScopedSkSurface> scoped_surface; - base::Optional<ScopedSkSurfaceForUnpremultiplyAndDither> - scoped_dither_surface; SkSurface* surface; sk_sp<SkColorSpace> sk_color_space = color_space.ToSkColorSpace(); - if (!unpremultiply_and_dither) { - scoped_surface.emplace(context_provider->GrContext(), sk_color_space, - texture_id, texture_target, resource_size, - resource_format, - skia::LegacyDisplayGlobals::ComputeSurfaceProps( - playback_settings.use_lcd_text), - playback_settings.msaa_sample_count); - surface = scoped_surface->surface(); - } else { - scoped_dither_surface.emplace( - context_provider, sk_color_space, playback_rect, raster_full_rect, - max_tile_size, texture_id, resource_size, - playback_settings.use_lcd_text, playback_settings.msaa_sample_count); - surface = scoped_dither_surface->surface(); - } + viz::ClientResourceProvider::ScopedSkSurface scoped_surface( + context_provider->GrContext(), sk_color_space, texture_id, + texture_target, resource_size, resource_format, + skia::LegacyDisplayGlobals::ComputeSurfaceProps( + playback_settings.use_lcd_text), + playback_settings.msaa_sample_count); + surface = scoped_surface.surface(); // Allocating an SkSurface will fail after a lost context. Pretend we // rasterized, as the contents of the resource don't matter anymore. @@ -379,8 +295,6 @@ use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources), tile_format_(tile_format), max_tile_size_(max_tile_size), - unpremultiply_and_dither_low_bit_depth_tiles_( - unpremultiply_and_dither_low_bit_depth_tiles), enable_oop_rasterization_(enable_oop_rasterization), pending_raster_queries_(pending_raster_queries), random_generator_(static_cast<uint32_t>(base::RandUint64())), @@ -599,7 +513,6 @@ resource_size, resource_format, color_space, raster_full_rect, playback_rect, transform, playback_settings, worker_context_provider_, - ShouldUnpremultiplyAndDitherResource(resource_format), max_tile_size_); } if (measure_raster_metric) { @@ -614,12 +527,8 @@ bool GpuRasterBufferProvider::ShouldUnpremultiplyAndDitherResource( viz::ResourceFormat format) const { - switch (format) { - case viz::RGBA_4444: - return unpremultiply_and_dither_low_bit_depth_tiles_; - default: - return false; - } + // TODO(crbug.com/1151490): Re-enable for OOPR. + return false; } } // namespace cc
diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h index d3cc322..2980c4c 100644 --- a/cc/raster/gpu_raster_buffer_provider.h +++ b/cc/raster/gpu_raster_buffer_provider.h
@@ -164,7 +164,6 @@ const bool use_gpu_memory_buffer_resources_; const viz::ResourceFormat tile_format_; const gfx::Size max_tile_size_; - const bool unpremultiply_and_dither_low_bit_depth_tiles_; const bool enable_oop_rasterization_; RasterQueryQueue* const pending_raster_queries_;
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc index d837df9..65911d4 100644 --- a/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -353,7 +353,8 @@ // This test doesn't work on Vulkan because on our hardware we can't render to // RGBA4444 format using either SwiftShader or native Vulkan. See -// crbug.com/987278 for details +// crbug.com/987278 for details. +// TODO(crbug.com/1151490) : Re-enable after this is supported for OOPR. #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) class LayerTreeHostTilesTestPartialInvalidationLowBitDepth : public LayerTreeHostTilesTestPartialInvalidation { @@ -373,14 +374,16 @@ RasterTestConfig{viz::RendererType::kGL, TestRasterType::kGpu}), ::testing::PrintToStringParamName()); -TEST_P(LayerTreeHostTilesTestPartialInvalidationLowBitDepth, PartialRaster) { +TEST_P(LayerTreeHostTilesTestPartialInvalidationLowBitDepth, + DISABLED_PartialRaster) { use_partial_raster_ = true; RunSingleThreadedPixelTest(picture_layer_, base::FilePath(FILE_PATH_LITERAL( "blue_yellow_partial_flipped_dither.png"))); } -TEST_P(LayerTreeHostTilesTestPartialInvalidationLowBitDepth, FullRaster) { +TEST_P(LayerTreeHostTilesTestPartialInvalidationLowBitDepth, + DISABLED_FullRaster) { RunSingleThreadedPixelTest( picture_layer_, base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped_dither.png")));
diff --git a/chrome/VERSION b/chrome/VERSION index 39c467e..e2adb3c 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=89 MINOR=0 -BUILD=4332 +BUILD=4333 PATCH=0
diff --git a/chrome/android/expectations/lint-baseline.xml b/chrome/android/expectations/lint-baseline.xml index c810c5a..f23aa2a 100644 --- a/chrome/android/expectations/lint-baseline.xml +++ b/chrome/android/expectations/lint-baseline.xml
@@ -173,7 +173,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java" - line="463" + line="422" column="30"/> </issue> @@ -195,7 +195,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> <location file="../../android_webview/java/src/org/chromium/android_webview/AwContents.java" - line="1347" + line="1348" column="9"/> </issue> @@ -206,7 +206,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../android_webview/java/src/org/chromium/android_webview/AwContents.java" - line="1348" + line="1349" column="17"/> </issue> @@ -217,7 +217,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../android_webview/java/src/org/chromium/android_webview/AwContents.java" - line="1844" + line="1845" column="46"/> </issue> @@ -228,7 +228,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../android_webview/java/src/org/chromium/android_webview/AwContents.java" - line="2843" + line="2840" column="22"/> </issue> @@ -305,7 +305,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> <location file="../../android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java" - line="135" + line="144" column="36"/> </issue> @@ -316,7 +316,7 @@ errorLine2=" ~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/BottomSheetManager.java" - line="224" + line="236" column="55"/> </issue> @@ -327,7 +327,7 @@ errorLine2=" ~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/ui/BottomSheetManager.java" - line="228" + line="240" column="48"/> </issue> @@ -338,7 +338,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="../../weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java" - line="305" + line="300" column="57"/> </issue> @@ -349,7 +349,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="../../weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java" - line="416" + line="411" column="77"/> </issue> @@ -360,7 +360,7 @@ errorLine2=" ~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java" - line="367" + line="364" column="84"/> </issue> @@ -371,7 +371,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java" - line="757" + line="754" column="23"/> </issue> @@ -393,7 +393,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java" - line="791" + line="797" column="67"/> </issue> @@ -437,7 +437,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java" - line="137" + line="138" column="46"/> </issue> @@ -448,7 +448,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManagerImpl.java" - line="143" + line="144" column="46"/> </issue> @@ -470,7 +470,7 @@ errorLine2=" ^"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java" - line="491" + line="504" column="43"/> </issue> @@ -481,7 +481,7 @@ errorLine2=" ~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/autofill/prefeditor/EditorDialog.java" - line="495" + line="508" column="42"/> </issue> @@ -547,7 +547,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java" - line="112" + line="111" column="20"/> </issue> @@ -558,7 +558,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java" - line="131" + line="130" column="42"/> </issue> @@ -569,7 +569,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java" - line="145" + line="144" column="20"/> </issue> @@ -653,39 +653,6 @@ <issue id="VisibleForTests" message="This method should only be accessed from tests or within private scope" - errorLine1=" dropdown = new OmniboxSuggestionsRecyclerView(context);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownFactory.java" - line="38" - column="24"/> - </issue> - - <issue - id="VisibleForTests" - message="This method should only be accessed from tests or within private scope" - errorLine1=" dropdown.setAdapter(adapter);" - errorLine2=" ~~~~~~~~~~"> - <location - file="../../chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownFactory.java" - line="42" - column="18"/> - </issue> - - <issue - id="VisibleForTests" - message="This method should only be accessed from tests or within private scope" - errorLine1=" dropdown = new OmniboxSuggestionsList(context);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownFactory.java" - line="50" - column="24"/> - </issue> - - <issue - id="VisibleForTests" - message="This method should only be accessed from tests or within private scope" errorLine1=" .setAnchorView(mToolbarLayout.getOptionalButtonView())" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> <location @@ -701,7 +668,7 @@ errorLine2=" ~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java" - line="515" + line="516" column="22"/> </issue> @@ -745,7 +712,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java" - line="477" + line="470" column="52"/> </issue> @@ -778,7 +745,7 @@ errorLine2=" ~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java" - line="327" + line="334" column="20"/> </issue> @@ -954,7 +921,7 @@ errorLine2=" ~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java" - line="1535" + line="1534" column="74"/> </issue> @@ -965,7 +932,7 @@ errorLine2=" ~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java" - line="626" + line="590" column="31"/> </issue> @@ -1064,7 +1031,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../components/messages/android/java/res/layout/message_banner_view.xml" - line="27" + line="31" column="9"/> </issue> @@ -1075,7 +1042,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../components/messages/android/java/res/layout/message_banner_view.xml" - line="56" + line="60" column="9"/> </issue> @@ -1448,6 +1415,17 @@ errorLine1="<FrameLayout" errorLine2="^"> <location + file="../../chrome/android/feed/core/java/resv1/layout/feed_more_button.xml" + line="7" + column="1"/> + </issue> + + <issue + id="MergeRootFrame" + message="This `<FrameLayout>` can be replaced with a `<merge>` tag" + errorLine1="<FrameLayout" + errorLine2="^"> + <location file="../../chrome/android/java/res/layout/signin_activity.xml" line="5" column="1"/> @@ -1460,11 +1438,55 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java" - line="34" + line="35" column="33"/> </issue> <issue + id="UsableSpace" + message="Consider also using `StorageManager#getAllocatableBytes` and `allocateBytes` which will consider clearable cached data" + errorLine1=" dir.getAbsolutePath(), dir.getUsableSpace(), dir.getTotalSpace(), type);" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="../../chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDirectoryProvider.java" + line="152" + column="48"/> + </issue> + + <issue + id="UsableSpace" + message="Consider also using `StorageManager#getAllocatableBytes` and `allocateBytes` which will consider clearable cached data" + errorLine1=" mFreeSpace = Environment.getExternalStorageDirectory().getUsableSpace();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="../../chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java" + line="317" + column="68"/> + </issue> + + <issue + id="UsableSpace" + message="Consider also using `StorageManager#getAllocatableBytes` and `allocateBytes` which will consider clearable cached data" + errorLine1=" return Environment.getDataDirectory().getUsableSpace();" + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="../../chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java" + line="240" + column="47"/> + </issue> + + <issue + id="UsableSpace" + message="Consider also using `StorageManager#getAllocatableBytes` and `allocateBytes` which will consider clearable cached data" + errorLine1=" defaultDownloadDir.getAbsolutePath(), defaultDownloadDir.getUsableSpace()," + errorLine2=" ~~~~~~~~~~~~~~"> + <location + file="../../chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/storage/StorageSummaryProvider.java" + line="86" + column="82"/> + </issue> + + <issue id="Autofill" message="Missing `autofillHints` attribute" errorLine1=" <EditText" @@ -1504,7 +1526,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelListItem.java" - line="459" + line="458" column="20"/> </issue> @@ -1515,7 +1537,7 @@ errorLine2=" ^"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java" - line="193" + line="216" column="46"/> </issue> @@ -1526,7 +1548,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java" - line="270" + line="283" column="9"/> </issue> @@ -1537,7 +1559,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="../../components/browser_ui/android/bottomsheet/internal/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheet.java" - line="275" + line="278" column="20"/> </issue> @@ -1592,7 +1614,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java" - line="660" + line="661" column="20"/> </issue> @@ -1713,7 +1735,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java" - line="111" + line="139" column="20"/> </issue> @@ -1823,7 +1845,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java" - line="264" + line="261" column="20"/> </issue> @@ -1834,7 +1856,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="../../chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java" - line="488" + line="487" column="20"/> </issue> @@ -1907,94 +1929,6 @@ <issue id="KeyboardInaccessibleWidget" message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/layout/download_manager_card_footer.xml" - line="14" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/layout/download_manager_generic_item.xml" - line="14" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/layout/download_manager_image_item.xml" - line="13" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/layout/download_manager_in_progress_image_item.xml" - line="13" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/layout/download_manager_in_progress_item.xml" - line="13" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/layout/download_manager_in_progress_video_item.xml" - line="12" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/layout/download_manager_prefetch_article.xml" - line="14" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../chrome/browser/download/android/java/res/layout/download_manager_video_item.xml" - line="13" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" errorLine1=" android:clickable="true"" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> <location @@ -2031,17 +1965,6 @@ errorLine1=" android:clickable="true"" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="../../chrome/android/java/res/layout/share_sheet_item.xml" - line="9" - column="5"/> - </issue> - - <issue - id="KeyboardInaccessibleWidget" - message="'clickable' attribute found, please also add 'focusable'" - errorLine1=" android:clickable="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location file="../../chrome/android/java/res/layout/start_top_toolbar.xml" line="13" column="5"/>
diff --git a/chrome/android/expectations/lint-suppressions.xml b/chrome/android/expectations/lint-suppressions.xml index c7bed24..38615bc 100644 --- a/chrome/android/expectations/lint-suppressions.xml +++ b/chrome/android/expectations/lint-suppressions.xml
@@ -54,10 +54,6 @@ <issue id="InvalidVectorPath" severity="ignore"/> <issue id="LogConditional" severity="ignore"/> <issue id="LongLogTag" severity="ignore"/> - <issue id="MergeRootFrame"> - <!-- TODO(crbug.com/1039415): Remove suppression after fixing bug. --> - <ignore regexp="chrome/android/feed/core/java/resv1/layout/feed_more_button.xml"/> - </issue> <issue id="MissingClass" severity="ignore"/> <issue id="MissingDefaultResource"> <!-- Only used by ToolbarControlContainer guarded by tablet form-factor. --> @@ -68,10 +64,6 @@ <issue id="MissingPermission" severity="ignore"/> <issue id="MissingQuantity" severity="ignore"/> <issue id="MissingRegistered" severity="ignore"/> - <issue id="MissingSuperCall"> - <!-- TODO(wnwen): File bug to fix --> - <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectionToolbar.java"/> - </issue> <issue id="MissingTranslation"> <ignore regexp="restriction_values.xml.*"/> </issue> @@ -82,8 +74,6 @@ <ignore regexp="Static interface method requires API level 24"/> <!-- 1: TaskInfo is refactored at API 29. --> <ignore regexp="Field requires API level .*`android.app.TaskInfo"/> - <!-- 1: TODO(crbug.com/1085410): Fix --> - <ignore regexp="components/content_capture/android/java/src/org/chromium/components/content_capture"/> <!-- Endnote: Please specify number of suppressions when adding more --> </issue> <!-- This warning just adds a lot of false positives. --> @@ -255,25 +245,17 @@ <ignore regexp="components/page_info/android/java/res/drawable-hdpi/pageinfo_*"/> <!--TODO(crbug.com/1052375): Remove this suppression once PermissionParamsListBuilder moves to components.--> <ignore regexp="The resource `R.string.page_info_permission_ads_subtitle` appears to be unused"/> - <!--TODO(crbug.com/1069186): The following 14 are found when we switched to linting the entire app. --> + <!--TODO(crbug.com/1069186): The following 10 are found when we switched to linting the entire app. --> <ignore regexp="The resource `R.string.download_manager_ui_documents` appears to be unused"/> <ignore regexp="The resource `R.string.download_manager_offline_home` appears to be unused"/> <ignore regexp="The resource `R.string.ntp_learn_more_about_suggested_content` appears to be unused"/> - <ignore regexp="The resource `R.string.ntp_feed_menu_iph` appears to be unused"/> <ignore regexp="The resource `R.string.tab_switcher_button_label` appears to be unused"/> - <ignore regexp="The resource `R.string.prefs_autofill_assistant_switch` appears to be unused"/> <ignore regexp="The resource `R.string.storage_clear_dialog_text` appears to be unused"/> <ignore regexp="The resource `R.string.website_settings_category_notifications_block` appears to be unused"/> <ignore regexp="The resource `R.string.autofill_cc_google_issued` appears to be unused"/> <ignore regexp="The resource `R.string.notification_manage_button` appears to be unused"/> <ignore regexp="The resource `R.string.app_banner_add` appears to be unused"/> <ignore regexp="The resource `R.string.notification_category_permission_requests` appears to be unused"/> - <ignore regexp="The resource `R.drawable.ic_launcher_background` appears to be unused"/> - <ignore regexp="The resource `R.string.combined_notification_text` appears to be unused"/> - <ignore regexp="The resource `R.plurals.public_notification_text` appears to be unused"/> - <ignore regexp="The resource `R.mipmap.app_shortcut_icon` appears to be unused"/> - <ignore regexp="The resource `R.string.app_banner_install` appears to be unused"/> - <ignore regexp="The resource `R.string.iph_download_indicator_text` appears to be unused"/> <!--TODO(crbug.com/1106109): Remove this suppression once Most Visited Tiles header is implemented.--> <ignore regexp="The resource `R.string.most_visited_tiles_header` appears to be unused"/> <ignore regexp="The resource `R.string.accessibility_omnibox_showing_suggestions_for_website` appears to be unused"/> @@ -296,13 +278,6 @@ <ignore regexp="The resource `R.string.price_drop_spotted_show_me` appears to be unused"/> <!-- Endnote: Please specify number of suppressions when adding more --> </issue> - <issue id="UsableSpace"> - <!-- TODO(crbug.com/1077861): Old code, good to fix. --> - <ignore regexp="chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DownloadDirectoryProvider.java"/> - <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java"/> - <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java"/> - <ignore regexp="chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/storage/StorageSummaryProvider.java"/> - </issue> <issue id="VectorPath" severity="ignore"/> <!-- These constructors are useful for layout editors which we currently do not support. --> <issue id="ViewConstructor" severity="ignore"/>
diff --git a/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected b/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected index 08d48a4..c1bb978 100644 --- a/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected +++ b/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected
@@ -599,9 +599,10 @@ </intent-filter> # DIFF-ANCHOR: 9c5197e9 </activity> # DIFF-ANCHOR: aea75380 <activity # DIFF-ANCHOR: a1fac31f - android:exported="false" + android:exported="true" android:label="@string/cablev2_activity_title" android:name="org.chromium.chrome.browser.webauth.authenticator.CableAuthenticatorActivity" + android:permission="com.google.android.gms.auth.cryptauth.permission.CABLEV2_SERVER_LINK" android:theme="@style/Theme.Chromium.Activity.Fullscreen"> <intent-filter> # DIFF-ANCHOR: 5873407a <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/>
diff --git a/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected b/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected index f5921ef..cb6797ad 100644 --- a/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected +++ b/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected
@@ -572,9 +572,10 @@ </intent-filter> # DIFF-ANCHOR: 9c5197e9 </activity> # DIFF-ANCHOR: aea75380 <activity # DIFF-ANCHOR: a1fac31f - android:exported="false" + android:exported="true" android:label="@string/cablev2_activity_title" android:name="org.chromium.chrome.browser.webauth.authenticator.CableAuthenticatorActivity" + android:permission="com.google.android.gms.auth.cryptauth.permission.CABLEV2_SERVER_LINK" android:theme="@style/Theme.Chromium.Activity.Fullscreen"> <intent-filter> # DIFF-ANCHOR: 5873407a <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/>
diff --git a/chrome/android/features/cablev2_authenticator/BUILD.gn b/chrome/android/features/cablev2_authenticator/BUILD.gn index 9e9d7d00..6eee7d9 100644 --- a/chrome/android/features/cablev2_authenticator/BUILD.gn +++ b/chrome/android/features/cablev2_authenticator/BUILD.gn
@@ -48,6 +48,7 @@ "java/res/layout/cablev2_fcm.xml", "java/res/layout/cablev2_qr_dialog.xml", "java/res/layout/cablev2_qr_scan.xml", + "java/res/layout/cablev2_serverlink.xml", "java/res/layout/cablev2_usb_attached.xml", "java/res/values/attrs.xml", "java/res/values/styles.xml",
diff --git a/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_serverlink.xml b/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_serverlink.xml new file mode 100644 index 0000000..fb83e19 --- /dev/null +++ b/chrome/android/features/cablev2_authenticator/java/res/layout/cablev2_serverlink.xml
@@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-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. --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:orientation="vertical"> + + <TextView + xmlns:tools="http://schemas.android.com/tools" + tools:ignore="HardcodedText" + style="@style/TextAppearance.TextLarge.Primary" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:text="Connecting to your computer" /> + <TextView + xmlns:tools="http://schemas.android.com/tools" + style="@style/TextAppearance.TextMedium.Secondary" + android:id="@+id/status_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" /> +</LinearLayout>
diff --git a/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticator.java b/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticator.java index 34f74588..c8f601a 100644 --- a/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticator.java +++ b/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticator.java
@@ -96,7 +96,7 @@ public CableAuthenticator(Context context, CableAuthenticatorUI ui, long networkContext, long registration, String activityClassName, boolean isFcmNotification, - UsbAccessory accessory) { + UsbAccessory accessory, byte[] serverLink) { mContext = context; mUi = ui; @@ -118,6 +118,10 @@ CableAuthenticatorJni.get().onInteractionReady(this); } + if (serverLink != null) { + CableAuthenticatorJni.get().startServerLink(this, serverLink); + } + // Otherwise wait for a QR scan. } @@ -464,6 +468,10 @@ } static String getName() { + final String name = BluetoothAdapter.getDefaultAdapter().getName(); + if (name != null && name.length() > 0) { + return name; + } return Build.MANUFACTURER + " " + Build.MODEL; } @@ -569,6 +577,12 @@ String qrUrl, boolean link); /** + * Called to instruct the C++ code to start a new transaction based on the given link + * information which has been provided by the server. + */ + boolean startServerLink(CableAuthenticator cableAuthenticator, byte[] serverLinkData); + + /** * unlink causes the root secret to be rotated and the FCM token to be rotated. This * prevents all previously linked devices from being able to contact this device in the * future -- they'll have to go via the QR-scanning path again. It returns the updated state
diff --git a/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java b/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java index 7eab9b6..11246b3 100644 --- a/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java +++ b/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUI.java
@@ -23,11 +23,13 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.TextView; import androidx.appcompat.app.AlertDialog; import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.Fragment; +import org.chromium.base.Log; import org.chromium.ui.base.ActivityAndroidPermissionDelegate; import org.chromium.ui.base.AndroidPermissionDelegate; import org.chromium.ui.widget.Toast; @@ -39,14 +41,27 @@ */ public class CableAuthenticatorUI extends Fragment implements OnClickListener, QRScanDialog.Callback { + private static final String TAG = "CableAuthenticatorUI"; + // ENABLE_BLUETOOTH_REQUEST_CODE is a random int used to identify responses // to a request to enable Bluetooth. (Request codes can only be 16-bit.) private static final int ENABLE_BLUETOOTH_REQUEST_CODE = 64907; + private static final String ACTIVITY_CLASS_NAME_EXTRA = + "org.chromium.chrome.modules.cablev2_authenticator.ActivityClassName"; + private static final String FCM_EXTRA = "org.chromium.chrome.modules.cablev2_authenticator.FCM"; + private static final String NETWORK_CONTEXT_EXTRA = + "org.chromium.chrome.modules.cablev2_authenticator.NetworkContext"; + private static final String REGISTRATION_EXTRA = + "org.chromium.chrome.modules.cablev2_authenticator.Registration"; + private static final String SERVER_LINK_EXTRA = + "org.chromium.chrome.browser.webauth.authenticator.ServerLink"; + private enum Mode { QR, // Triggered from Settings; can scan QR code to start handshake. FCM, // Triggered by user selecting notification; handshake already running. USB, // Triggered by connecting via USB. + SERVER_LINK, // Triggered by GMSCore forwarding from GAIA. } private Mode mMode; private AndroidPermissionDelegate mPermissionDelegate; @@ -54,6 +69,7 @@ private LinearLayout mQRButton; private LinearLayout mUnlinkButton; private ImageView mHeader; + private TextView mStatusText; // The following two members store a pending QR-scan result while Bluetooth // is enabled. @@ -68,25 +84,27 @@ Bundle arguments = getArguments(); final UsbAccessory accessory = (UsbAccessory) arguments.getParcelable(UsbManager.EXTRA_ACCESSORY); + final byte[] serverLink = arguments.getByteArray(SERVER_LINK_EXTRA); if (accessory != null) { mMode = Mode.USB; - } else if (arguments.getBoolean("org.chromium.chrome.modules.cablev2_authenticator.FCM")) { + } else if (arguments.getBoolean(FCM_EXTRA)) { mMode = Mode.FCM; + } else if (serverLink != null) { + mMode = Mode.SERVER_LINK; } else { mMode = Mode.QR; } - final long networkContext = arguments.getLong( - "org.chromium.chrome.modules.cablev2_authenticator.NetworkContext"); - final long registration = - arguments.getLong("org.chromium.chrome.modules.cablev2_authenticator.Registration"); - final String activityClassName = arguments.getString( - "org.chromium.chrome.modules.cablev2_authenticator.ActivityClassName"); + Log.i(TAG, "Starting in mode " + mMode.toString()); + + final long networkContext = arguments.getLong(NETWORK_CONTEXT_EXTRA); + final long registration = arguments.getLong(REGISTRATION_EXTRA); + final String activityClassName = arguments.getString(ACTIVITY_CLASS_NAME_EXTRA); mPermissionDelegate = new ActivityAndroidPermissionDelegate( new WeakReference<Activity>((Activity) context)); mAuthenticator = new CableAuthenticator(getContext(), this, networkContext, registration, - activityClassName, mMode == Mode.FCM, accessory); + activityClassName, mMode == Mode.FCM, accessory, serverLink); } @Override @@ -102,13 +120,18 @@ case FCM: return inflater.inflate(R.layout.cablev2_fcm, container, false); + case SERVER_LINK: + View v = inflater.inflate(R.layout.cablev2_serverlink, container, false); + mStatusText = v.findViewById(R.id.status_text); + return v; + case QR: // TODO: should check FEATURE_BLUETOOTH with // https://developer.android.com/reference/android/content/pm/PackageManager.html#hasSystemFeature(java.lang.String) // TODO: strings should be translated but this will be replaced during // the UI process. - View v = inflater.inflate(R.layout.cablev2_qr_scan, container, false); + v = inflater.inflate(R.layout.cablev2_qr_scan, container, false); mQRButton = v.findViewById(R.id.qr_scan); mQRButton.setOnClickListener(this); @@ -208,19 +231,26 @@ } void onStatus(int code) { - if (mMode != Mode.QR) { - // In FCM mode, the handshake is done before the UI appears. For - // USB everything should happen immediately. - return; - } + switch (mMode) { + case QR: + // These values must match up with the Status enum in v2_authenticator.h + if (code == 1) { + setHeader(R.style.step2); + } else if (code == 2) { + setHeader(R.style.step3); + } else if (code == 3) { + setHeader(R.style.step4); + } + break; - // These values must match up with the Status enum in v2_authenticator.h - if (code == 1) { - setHeader(R.style.step2); - } else if (code == 2) { - setHeader(R.style.step3); - } else if (code == 3) { - setHeader(R.style.step4); + case SERVER_LINK: + mStatusText.setText(String.valueOf(code)); + break; + + case FCM: + case USB: + // In FCM mode, the handshake is done before the UI appears. For + // USB everything should happen immediately. } }
diff --git a/chrome/android/features/cablev2_authenticator/native/cablev2_authenticator_android.cc b/chrome/android/features/cablev2_authenticator/native/cablev2_authenticator_android.cc index 208299f..1bdd90d 100644 --- a/chrome/android/features/cablev2_authenticator/native/cablev2_authenticator_android.cc +++ b/chrome/android/features/cablev2_authenticator/native/cablev2_authenticator_android.cc
@@ -87,6 +87,29 @@ return base::as_bytes(base::make_span(data_bytes, data_len)); } +// JavaByteArrayToFixedSpan returns a span that aliases |data|, or |nullopt| if +// the span is not of the correct length. Be aware that the reference for |data| +// must outlive the span. +template <size_t N> +base::Optional<base::span<const uint8_t, N>> JavaByteArrayToFixedSpan( + JNIEnv* env, + const JavaParamRef<jbyteArray>& data) { + static_assert(N != 0, + "Zero case is different from JavaByteArrayToSpan as null " + "inputs will always be rejected here."); + + if (data.is_null()) { + return base::nullopt; + } + + const size_t data_len = env->GetArrayLength(data); + if (data_len != N) { + return base::nullopt; + } + const jbyte* data_bytes = env->GetByteArrayElements(data, /*iscopy=*/nullptr); + return base::as_bytes(base::make_span<N>(data_bytes, data_len)); +} + // GlobalData holds all the state for ongoing security key operations. Since // there are ultimately only one human user, concurrent requests are not // supported. @@ -512,6 +535,36 @@ return true; } +static jboolean JNI_CableAuthenticator_StartServerLink( + JNIEnv* env, + const JavaParamRef<jobject>& cable_authenticator, + const JavaParamRef<jbyteArray>& server_link_data_java) { + constexpr size_t kDataSize = + device::kP256X962Length + device::cablev2::kQRSecretSize; + const base::Optional<base::span<const uint8_t, kDataSize>> server_link_data = + JavaByteArrayToFixedSpan<kDataSize>(env, server_link_data_java); + + if (!server_link_data) { + FIDO_LOG(ERROR) << "Bad length server-link data length"; + return false; + } + + // Sending pairing information is disabled when doing a server-linked + // connection, thus the root secret and authenticator name will not be used. + std::array<uint8_t, device::cablev2::kRootSecretSize> dummy_root_secret = {0}; + std::string dummy_authenticator_name = ""; + GlobalData& global_data = GetGlobalData(); + global_data + .current_transaction = device::cablev2::authenticator::TransactFromQRCode( + std::make_unique<AndroidPlatform>(env, cable_authenticator), + global_data.network_context, dummy_root_secret, dummy_authenticator_name, + server_link_data + ->subspan<device::kP256X962Length, device::cablev2::kQRSecretSize>(), + server_link_data->subspan<0, device::kP256X962Length>(), base::nullopt); + + return true; +} + static ScopedJavaLocalRef<jbyteArray> JNI_CableAuthenticator_Unlink( JNIEnv* env) { std::vector<uint8_t> serialized_state;
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 4f73e753..3fefe05 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -853,12 +853,11 @@ <activity android:name="org.chromium.chrome.browser.webauth.authenticator.CableAuthenticatorActivity" android:theme="@style/Theme.Chromium.Activity.Fullscreen" android:label="@string/cablev2_activity_title" - android:exported="false"> - <!-- This has an intent filter but is not exported. This works - because the intent is sent by the Android system, not another - application. We want to limit this activity to only be invoked by - Chromium or the OS because otherwise applications could fool - Chromium into communicating with a fake USB device. --> + android:permission="com.google.android.gms.auth.cryptauth.permission.CABLEV2_SERVER_LINK" + android:exported="true"> + <!-- This activity can be started by GMSCore, and is thus exported + with a permission set, or can be started by the Android system in + the case that a USB device is attached. --> <intent-filter> <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> </intent-filter>
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 6690b9a..b126a5a 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
@@ -1505,6 +1505,9 @@ return; } + TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile()) + .notifyEvent(EventConstants.APP_MENU_BOOKMARK_STAR_ICON_PRESSED); + // Note we get user bookmark ID over just a bookmark ID here: Managed bookmarks can't be // edited. If the current URL is only bookmarked by managed bookmarks, this will return // INVALID_ID, so the code below will fall back on adding a new bookmark instead.
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 773d074..5fe23ca 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
@@ -365,6 +365,8 @@ // Adds reading list as the first top level folder. if (bookmarkId.getType() == BookmarkType.READING_LIST) { topLevelFolders.add(bookmarkId); + TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile()) + .notifyEvent(EventConstants.READ_LATER_BOTTOM_SHEET_FOLDER_SEEN); continue; } BookmarkId parent = bookmarkModel.getBookmarkById(bookmarkId).getParentId();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java index 7f12d47..4d83810 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java
@@ -15,16 +15,16 @@ /** * Helper class to manage all the logic and UI behind adding the reading list section headers in the * bookmark content UI. - * TODO(crbug/1147787): Add integration tests. */ class ReadingListSectionHeader { /** * Sorts the reading list and adds section headers if the list is a reading list. * Noop, if the list isn't a reading list. The layout rows are shown in the following order : - * 1 - Section header with title "Unread" - * 2 - Unread reading list articles. - * 3 - Section header with title "Read" - * 4 - Read reading list articles. + * 1 - Any promo header + * 2 - Section header with title "Unread" + * 3 - Unread reading list articles. + * 4 - Section header with title "Read" + * 5 - Read reading list articles. * @param listItems The list of bookmark items to be shown in the UI. * @param context The associated activity context. */ @@ -41,10 +41,11 @@ readingListStartIndex++; } - assert readingListStartIndex < listItems.size(); + // If we have no read/unread elements, exit. + if (readingListStartIndex == listItems.size()) return; sort(listItems, readingListStartIndex); - // Add a section header at the top. + // Add a section header at the top. If it is for read, exit right away. assert listItems.get(readingListStartIndex).getBookmarkItem().getId().getType() == BookmarkType.READING_LIST; boolean isRead = listItems.get(readingListStartIndex).getBookmarkItem().isRead();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/messages/ChromeMessageQueueMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/messages/ChromeMessageQueueMediator.java index e915a6c..af49c6f5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/messages/ChromeMessageQueueMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/messages/ChromeMessageQueueMediator.java
@@ -16,10 +16,12 @@ import org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.components.messages.ManagedMessageDispatcher; import org.chromium.components.messages.MessageQueueDelegate; +import org.chromium.content_public.common.BrowserControlsState; import org.chromium.ui.util.TokenHolder; /** @@ -129,7 +131,9 @@ mBrowserControlsToken = mBrowserControlsManager.getBrowserVisibilityDelegate().showControlsPersistent(); mContainerCoordinator.showMessageContainer(); - if (BrowserControlsUtils.areBrowserControlsFullyVisible(mBrowserControlsManager)) { + final Tab tab = mTabModelSelector != null ? mTabModelSelector.getCurrentTab() : null; + if (TabBrowserControlsConstraintsHelper.getConstraints(tab) == BrowserControlsState.HIDDEN + || BrowserControlsUtils.areBrowserControlsFullyVisible(mBrowserControlsManager)) { runnable.run(); } else { mBrowserControlsObserver.setOneTimeRunnableOnControlsFullyVisible(runnable);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/messages/MessageContainerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/messages/MessageContainerCoordinator.java index f98735d..b53d791 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/messages/MessageContainerCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/messages/MessageContainerCoordinator.java
@@ -54,14 +54,20 @@ } /** + * If there are no browser controls visible, the {@link MessageContainer} view should be laid + * out for this method to return a meaningful value. + * * @return The maximum translation Y value the message banner can have as a result of the * animations or the gestures. Positive values mean the message banner can be translated * upward from the top of the MessagesContainer. */ public int getMessageMaxTranslation() { - // TODO(sinansahin): We need to account for other scenarios where there are no browser - // controls visible (e.g. PWAs). - return getContainerTopOffset(); + final int containerTopOffset = getContainerTopOffset(); + if (containerTopOffset == 0) { + return mContainer.getHeight(); + } + + return containerTopOffset; } @Override @@ -77,8 +83,9 @@ /** @return Offset of the message container from the top of the screen. */ private int getContainerTopOffset() { + if (mControlsManager.getContentOffset() == 0) return 0; final Resources res = mContainer.getResources(); - return mControlsManager.getTopControlsHeight() + return mControlsManager.getContentOffset() - res.getDimensionPixelOffset(R.dimen.message_bubble_inset) - res.getDimensionPixelOffset(R.dimen.message_shadow_top_margin); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java index 23ef7b0..ffdf0de 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
@@ -155,6 +155,7 @@ mSubCoordinator.destroy(); mSubCoordinator = null; } + mUrlCoordinator.destroy(); mUrlCoordinator = null; mLocationBarLayout.removeUrlFocusChangeListener(mAutocompleteCoordinator); mAutocompleteCoordinator.destroy();
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 0356a73..41f8b68 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
@@ -669,7 +669,8 @@ * need to be updated. */ /* package */ void updateMicButtonState() { - mVoiceSearchEnabled = mVoiceRecognitionHandler.isVoiceSearchEnabled(); + mVoiceSearchEnabled = + mVoiceRecognitionHandler != null && mVoiceRecognitionHandler.isVoiceSearchEnabled(); updateButtonVisibility(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java index 73144f4..2410e74 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
@@ -222,12 +222,14 @@ new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { @Override public void onLongPress(MotionEvent e) { + if (mUrlBarDelegate == null) return; mUrlBarDelegate.gestureDetected(true); performLongClick(); } @Override public boolean onSingleTapUp(MotionEvent e) { + if (mUrlBarDelegate == null) return true; requestFocus(); mUrlBarDelegate.gestureDetected(false); return true; @@ -244,6 +246,15 @@ ApiCompatibilityUtils.disableSmartSelectionTextClassifier(this); } + public void destroy() { + setAllowFocus(false); + mUrlBarDelegate = null; + setOnFocusChangeListener(null); + mTextContextMenuDelegate = null; + mUrlTextChangeListener = null; + mTextChangedListener = null; + } + /** * Initialize the delegate that allows interaction with the Window. */ @@ -340,7 +351,8 @@ @Override public View focusSearch(int direction) { - if (direction == View.FOCUS_BACKWARD && mUrlBarDelegate.getViewForUrlBackFocus() != null) { + if (mUrlBarDelegate != null && direction == View.FOCUS_BACKWARD + && mUrlBarDelegate.getViewForUrlBackFocus() != null) { return mUrlBarDelegate.getViewForUrlBackFocus(); } else { return super.focusSearch(direction);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java index 5d27d66..ff684e3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java
@@ -37,8 +37,8 @@ int SELECT_END = 1; } - private final UrlBar mUrlBar; - private final UrlBarMediator mMediator; + private UrlBar mUrlBar; + private UrlBarMediator mMediator; /** * Constructs a coordinator for the given UrlBar view. @@ -67,6 +67,13 @@ mMediator = new UrlBarMediator(model, focusChangeCallback); } + public void destroy() { + mMediator.destroy(); + mMediator = null; + mUrlBar.destroy(); + mUrlBar = null; + } + /** @see UrlBarMediator#addUrlTextChangeListener(UrlTextChangeListener) */ public void addUrlTextChangeListener(UrlTextChangeListener listener) { mMediator.addUrlTextChangeListener(listener);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java index dee3561..c069513 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java
@@ -79,6 +79,12 @@ setUseDarkTextColors(true); } + public void destroy() { + mUrlTextChangeListeners.clear(); + mTextChangedListeners.clear(); + mOnFocusChangeCallback = (unused) -> {}; + } + /** Adds a listener for url text changes. */ public void addUrlTextChangeListener(UrlTextChangeListener listener) { mUrlTextChangeListeners.add(listener);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java index 5f964c2..f4bff20 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java
@@ -198,7 +198,7 @@ * {@link #start(Profile,String, String, boolean)}. * * <p> - * Calling this method with {@code false}, will result in + * Calling this method with {@code true}, will result in * {@link #onSuggestionsReceived(AutocompleteResult, String, long)} being called with an empty * result set. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index fe50fab..feda225 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -223,7 +223,7 @@ } public void destroy() { - stopAutocomplete(true); + stopAutocomplete(false); mDropdownViewInfoListBuilder.destroy(); if (mTabObserver != null) { mTabObserver.destroy();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java index 0387e03..e4bcdf3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java
@@ -63,7 +63,7 @@ /** Ensures selection is reset to beginning of the list. */ void resetSelection() { - setSelectedViewIndex(0); + setSelectedViewIndex(RecyclerView.NO_POSITION); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorActivity.java index c1d07ce8..4a5d8dc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorActivity.java
@@ -12,10 +12,12 @@ import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbManager; import android.os.Bundle; +import android.util.Base64; import androidx.fragment.app.Fragment; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.Log; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeBaseAppCompatActivity; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -35,10 +37,13 @@ * pulls in the dynamic feature module containing the needed code. */ public class CableAuthenticatorActivity extends ChromeBaseAppCompatActivity { + private static final String TAG = "CableAuthenticatorActivity"; static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = "show_fragment_args"; // See https://developer.android.com/guide/topics/connectivity/usb/accessory#java static final String USB_ACCESSORY_ATTACHED = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED"; + static final String SERVER_LINK_EXTRA = + "org.chromium.chrome.browser.webauth.authenticator.ServerLink"; @Override @SuppressLint("SetTextI18n") // TODO(BUG=1002262): translate @@ -71,10 +76,19 @@ // is untrusted. arguments = new Bundle(); arguments.putParcelable(UsbManager.EXTRA_ACCESSORY, accessory); + } else if (intent.hasExtra(SERVER_LINK_EXTRA)) { + // This Intent comes from GMSCore when it's triggering a server-linked connection. + final String serverLinkBase64 = intent.getStringExtra(SERVER_LINK_EXTRA); + arguments = new Bundle(); + try { + final byte[] serverLink = Base64.decode(serverLinkBase64, Base64.DEFAULT); + arguments.putByteArray(SERVER_LINK_EXTRA, serverLink); + } catch (IllegalArgumentException e) { + Log.i(TAG, "Invalid base64 in ServerLink argument"); + } } else { - // Since this Activity is not exported, this only happens when a - // notification is tapped and |EXTRA_SHOW_FRAGMENT_ARGUMENTS| thus - // comes from our own PendingIntent. + // Since this Activity is not otherwise exported, this only happens when a notification + // is tapped and |EXTRA_SHOW_FRAGMENT_ARGUMENTS| thus comes from our own PendingIntent. arguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java index e41abafa..31ce50d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java
@@ -210,6 +210,7 @@ throws InterruptedException { // Skip past the 'what-you-typed' suggestion. sendKey(KeyEvent.KEYCODE_DPAD_DOWN); + sendKey(KeyEvent.KEYCODE_DPAD_DOWN); checkUrlBarTextIs(mTile1.url.getSpec()); sendKey(KeyEvent.KEYCODE_DPAD_RIGHT); @@ -230,6 +231,7 @@ throws InterruptedException { // Skip past the 'what-you-typed' suggestion. sendKey(KeyEvent.KEYCODE_DPAD_DOWN); + sendKey(KeyEvent.KEYCODE_DPAD_DOWN); checkUrlBarTextIs(mTile1.url.getSpec()); sendKey(KeyEvent.KEYCODE_DPAD_RIGHT); @@ -250,6 +252,7 @@ throws InterruptedException { // Skip past the 'what-you-typed' suggestion. sendKey(KeyEvent.KEYCODE_DPAD_DOWN); + sendKey(KeyEvent.KEYCODE_DPAD_DOWN); checkUrlBarTextIs(mTile1.url.getSpec()); sendKey(KeyEvent.KEYCODE_DPAD_RIGHT);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java index ed09a9a..00e8194 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java
@@ -27,7 +27,7 @@ @Config(manifest = Config.NONE) public class ReadingListSectionHeaderTest { @Test - public void testAddReadingListSectionHeaders() { + public void testListWithReadUnreadItems() { Context context = ContextUtils.getApplicationContext(); String titleRead = context.getString(org.chromium.chrome.R.string.reading_list_read); String titleUnread = context.getString(org.chromium.chrome.R.string.reading_list_unread); @@ -53,6 +53,80 @@ "Expected a different item", 2, listItems.get(4).getBookmarkItem().getId().getId()); } + @Test + public void testListWithReadUnreadAndPromoItems() { + Context context = ContextUtils.getApplicationContext(); + String titleRead = context.getString(org.chromium.chrome.R.string.reading_list_read); + + List<BookmarkListEntry> listItems = new ArrayList<>(); + listItems.add(BookmarkListEntry.createSyncPromoHeader(ViewType.PERSONALIZED_SIGNIN_PROMO)); + listItems.add(createReadingListEntry(1, true)); + listItems.add(createReadingListEntry(2, true)); + ReadingListSectionHeader.maybeSortAndInsertSectionHeaders(listItems, context); + + assertEquals("Incorrect number of items in the adapter", 4, listItems.size()); + assertEquals("Expected promo section header", ViewType.PERSONALIZED_SIGNIN_PROMO, + listItems.get(0).getViewType()); + assertEquals("Expected read section header", ViewType.SECTION_HEADER, + listItems.get(1).getViewType()); + assertEquals("Expected read title text", titleRead, listItems.get(1).getHeaderTitle()); + assertEquals( + "Expected a different item", 1, listItems.get(2).getBookmarkItem().getId().getId()); + assertEquals( + "Expected a different item", 2, listItems.get(3).getBookmarkItem().getId().getId()); + } + + @Test + public void testEmptyList() { + Context context = ContextUtils.getApplicationContext(); + List<BookmarkListEntry> listItems = new ArrayList<>(); + ReadingListSectionHeader.maybeSortAndInsertSectionHeaders(listItems, context); + assertEquals("Incorrect number of items in the adapter", 0, listItems.size()); + } + + @Test + public void testNoReadUnreadItems() { + Context context = ContextUtils.getApplicationContext(); + List<BookmarkListEntry> listItems = new ArrayList<>(); + listItems.add(BookmarkListEntry.createSyncPromoHeader(ViewType.PERSONALIZED_SIGNIN_PROMO)); + ReadingListSectionHeader.maybeSortAndInsertSectionHeaders(listItems, context); + + assertEquals("Incorrect number of items in the adapter", 1, listItems.size()); + assertEquals("Expected promo section header", ViewType.PERSONALIZED_SIGNIN_PROMO, + listItems.get(0).getViewType()); + } + + @Test + public void testUnreadItemsOnly() { + Context context = ContextUtils.getApplicationContext(); + String titleUnread = context.getString(org.chromium.chrome.R.string.reading_list_unread); + + List<BookmarkListEntry> listItems = new ArrayList<>(); + listItems.add(createReadingListEntry(1, false)); + listItems.add(createReadingListEntry(2, false)); + ReadingListSectionHeader.maybeSortAndInsertSectionHeaders(listItems, context); + + assertEquals("Incorrect number of items in the adapter", 3, listItems.size()); + assertEquals( + "Expected section header", ViewType.SECTION_HEADER, listItems.get(0).getViewType()); + assertEquals("Expected unread title text", titleUnread, listItems.get(0).getHeaderTitle()); + } + + @Test + public void testReadItemsOnly() { + Context context = ContextUtils.getApplicationContext(); + String titleRead = context.getString(org.chromium.chrome.R.string.reading_list_read); + + List<BookmarkListEntry> listItems = new ArrayList<>(); + listItems.add(createReadingListEntry(1, true)); + ReadingListSectionHeader.maybeSortAndInsertSectionHeaders(listItems, context); + + assertEquals("Incorrect number of items in the adapter", 2, listItems.size()); + assertEquals( + "Expected section header", ViewType.SECTION_HEADER, listItems.get(0).getViewType()); + assertEquals("Expected read title text", titleRead, listItems.get(0).getHeaderTitle()); + } + private BookmarkListEntry createReadingListEntry(long id, boolean read) { BookmarkId bookmarkId = new BookmarkId(id, BookmarkType.READING_LIST); BookmarkItem bookmarkItem =
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 4217c74..07d2843 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10231,6 +10231,22 @@ </message> </if> + <!-- Font Access chooser --> + <if expr="not is_android"> + <message name="IDS_FONT_ACCESS_CHOOSER_PROMPT_ORIGIN" desc="The label that is used to introduce Local Font Access chooser details to the user in a popup when it is from a website."> + <ph name="Origin">$1<ex>www.google.com</ex></ph> wants to use local fonts + </message> + <message name="IDS_FONT_ACCESS_CHOOSER_NO_FONTS_FOUND_PROMPT" desc="The label shown to the user to inform them that no fonts were found matching the requirements that the application provided."> + No matching font found. + </message> + <message name="IDS_FONT_ACCESS_CHOOSER_IMPORT_BUTTON_TEXT" desc="Label on the button that closes the Local Font Access chooser popup and returns the selected fonts."> + Import + </message> + <message name="IDS_FONT_ACCESS_CHOOSER_CANCEL_BUTTON_TEXT" desc="Label on the button that closes the chooser popup without selecting an option."> + Cancel + </message> + </if> + <!-- Chrome IME API activated bubble. --> <message name="IDS_IME_API_ACTIVATED_WARNING" desc="The Warning info when an IME extension is trying to activate."> <ph name="EXTENSION_NAME">$1<ex>Gmail Checker</ex></ph> extension may collect all the text you type, including personal data like passwords and credit card numbers. Do you want to use this extension?
diff --git a/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_CANCEL_BUTTON_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_CANCEL_BUTTON_TEXT.png.sha1 new file mode 100644 index 0000000..5addd5c --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_CANCEL_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@ +166abf67c1e1b3d3bf23f40c5dba3536d60340bd \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_IMPORT_BUTTON_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_IMPORT_BUTTON_TEXT.png.sha1 new file mode 100644 index 0000000..5addd5c --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_IMPORT_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@ +166abf67c1e1b3d3bf23f40c5dba3536d60340bd \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_NO_FONTS_FOUND_PROMPT.png.sha1 b/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_NO_FONTS_FOUND_PROMPT.png.sha1 new file mode 100644 index 0000000..a15cd98 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_NO_FONTS_FOUND_PROMPT.png.sha1
@@ -0,0 +1 @@ +7ce296e147531e4214d2e2a5c7f4896236cd83aa \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_PROMPT_ORIGIN.png.sha1 b/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_PROMPT_ORIGIN.png.sha1 new file mode 100644 index 0000000..5addd5c --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_FONT_ACCESS_CHOOSER_PROMPT_ORIGIN.png.sha1
@@ -0,0 +1 @@ +166abf67c1e1b3d3bf23f40c5dba3536d60340bd \ No newline at end of file
diff --git a/chrome/app/nearby_share_strings.grdp b/chrome/app/nearby_share_strings.grdp index f47a8b1..c600af7 100644 --- a/chrome/app/nearby_share_strings.grdp +++ b/chrome/app/nearby_share_strings.grdp
@@ -122,6 +122,9 @@ <message name="IDS_NEARBY_ERROR_NO_RESPONSE" desc="Notify user that the file share failed because the receiver neither accepted nor declined the share."> The device you're sharing with didn't respond </message> + <message name="IDS_NEARBY_ERROR_NOT_ENOUGH_SPACE" desc="Notify user that the file can't be shared because there isn't enough disk space to store it. Displayed as a subtitle under a more generic file-couldn't-be-shared message."> + Not enough disk space + </message> <message name="IDS_NEARBY_ERROR_REJECTED" desc="Notify sender that receiver declined the file share."> The device you’re trying to share with did not accept </message>
diff --git a/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_ERROR_NOT_ENOUGH_SPACE.png.sha1 b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_ERROR_NOT_ENOUGH_SPACE.png.sha1 new file mode 100644 index 0000000..356d0d2 --- /dev/null +++ b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_ERROR_NOT_ENOUGH_SPACE.png.sha1
@@ -0,0 +1 @@ +7df1723c66d444204194927a80ea52f6a28d85bc \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index c7b3e2a..2afad46 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3553,6 +3553,8 @@ "first_run/first_run.h", "first_run/first_run_dialog.h", "first_run/first_run_internal.h", + "font_access/chrome_font_access_delegate.cc", + "font_access/chrome_font_access_delegate.h", "font_family_cache.cc", "font_family_cache.h", "hid/chrome_hid_delegate.cc",
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 3a7cf44..7fc8b2c 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -63,6 +63,7 @@ #include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/federated_learning/floc_id_provider.h" #include "chrome/browser/federated_learning/floc_id_provider_factory.h" +#include "chrome/browser/font_access/chrome_font_access_delegate.h" #include "chrome/browser/font_family_cache.h" #include "chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h" #include "chrome/browser/hid/chrome_hid_delegate.h" @@ -291,6 +292,7 @@ #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/file_url_loader.h" +#include "content/public/browser/font_access_delegate.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" @@ -4966,6 +4968,13 @@ return hid_delegate_.get(); } +content::FontAccessDelegate* +ChromeContentBrowserClient::GetFontAccessDelegate() { + if (!font_access_delegate_) + font_access_delegate_ = std::make_unique<ChromeFontAccessDelegate>(); + return static_cast<content::FontAccessDelegate*>(font_access_delegate_.get()); +} + std::unique_ptr<content::AuthenticatorRequestClientDelegate> ChromeContentBrowserClient::GetWebAuthenticationRequestDelegate( content::RenderFrameHost* render_frame_host) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index f4800d0..2ffb17e 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -53,6 +53,7 @@ namespace content { class BrowserContext; +class FontAccessDelegate; class QuotaPermissionContext; } // namespace content @@ -92,6 +93,7 @@ } class ChromeBluetoothDelegate; +class ChromeFontAccessDelegate; class ChromeHidDelegate; class ChromeSerialDelegate; @@ -538,6 +540,7 @@ #if !defined(OS_ANDROID) content::SerialDelegate* GetSerialDelegate() override; content::HidDelegate* GetHidDelegate() override; + content::FontAccessDelegate* GetFontAccessDelegate() override; std::unique_ptr<content::AuthenticatorRequestClientDelegate> GetWebAuthenticationRequestDelegate( content::RenderFrameHost* render_frame_host) override; @@ -789,6 +792,7 @@ #if !defined(OS_ANDROID) std::unique_ptr<ChromeSerialDelegate> serial_delegate_; std::unique_ptr<ChromeHidDelegate> hid_delegate_; + std::unique_ptr<ChromeFontAccessDelegate> font_access_delegate_; #endif std::unique_ptr<ChromeBluetoothDelegate> bluetooth_delegate_;
diff --git a/chrome/browser/chrome_main_browsertest.cc b/chrome/browser/chrome_main_browsertest.cc index b15aed2..2ee8508 100644 --- a/chrome/browser/chrome_main_browsertest.cc +++ b/chrome/browser/chrome_main_browsertest.cc
@@ -5,6 +5,7 @@ #include "base/command_line.h" #include "base/process/launch.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" @@ -19,9 +20,11 @@ #include "content/public/test/browser_test.h" #include "net/base/filename_util.h" -// These tests don't apply to the Mac version; see GetCommandLineForRelaunch +// These tests don't apply to Mac or Lacros; see GetCommandLineForRelaunch // for details. -#if !defined(OS_MAC) +#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_LACROS) +#error Not supported on this platform. +#endif class ChromeMainTest : public InProcessBrowserTest { public: @@ -112,5 +115,3 @@ ASSERT_EQ(2u, chrome::GetTotalBrowserCount()); ASSERT_EQ(1u, chrome::GetTabbedBrowserCount(profile)); } - -#endif // !OS_MAC
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 6414c65..20f674b 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -3198,8 +3198,6 @@ "policy/minimum_version_policy_test_helpers.h", "printing/printing_stubs.cc", "printing/printing_stubs.h", - "scoped_set_running_on_chromeos_for_testing.cc", - "scoped_set_running_on_chromeos_for_testing.h", "secure_channel/fake_nearby_connection_broker.cc", "secure_channel/fake_nearby_connection_broker.h", "secure_channel/fake_nearby_endpoint_finder.cc",
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc index 171012f..ad2ca59 100644 --- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
@@ -13,6 +13,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/system/sys_info.h" +#include "base/test/scoped_chromeos_version_info.h" #include "base/test/task_environment.h" #include "components/arc/bluetooth/bluetooth_type_converters.h" #include "components/arc/mojom/bluetooth.mojom.h" @@ -120,8 +121,6 @@ fake_bluetooth_instance_ = std::make_unique<FakeBluetoothInstance>(); arc_bridge_service_->bluetooth()->SetInstance( fake_bluetooth_instance_.get(), 17); - base::SysInfo::SetChromeOSVersionInfoForTest( - "CHROMEOS_ARC_ANDROID_SDK_VERSION=28", base::Time::Now()); WaitForInstanceReady(arc_bridge_service_->bluetooth()); device::BluetoothAdapterFactory::Get()->GetAdapter(base::BindOnce( @@ -279,6 +278,9 @@ // Invoke OnDiscoveryStarted to send cached device to BT instance, // and check correctness of the Advertising data sent via arc bridge. TEST_F(ArcBluetoothBridgeTest, LEDeviceFound) { + base::test::ScopedChromeOSVersionInfo version( + "CHROMEOS_ARC_ANDROID_SDK_VERSION=28", base::Time::Now()); + EXPECT_EQ(0u, fake_bluetooth_instance_->le_device_found_data().size()); AddTestDevice(); EXPECT_EQ(3u, fake_bluetooth_instance_->le_device_found_data().size()); @@ -300,8 +302,9 @@ } TEST_F(ArcBluetoothBridgeTest, LEDeviceFoundForN) { - base::SysInfo::SetChromeOSVersionInfoForTest( + base::test::ScopedChromeOSVersionInfo version( "CHROMEOS_ARC_ANDROID_SDK_VERSION=27", base::Time::Now()); + EXPECT_EQ(0u, fake_bluetooth_instance_->le_device_found_data().size()); AddTestDevice(); EXPECT_EQ(3u, fake_bluetooth_instance_->le_device_found_data().size());
diff --git a/chrome/browser/chromeos/crosapi/browser_util.cc b/chrome/browser/chromeos/crosapi/browser_util.cc index 428c6ca..9acf05d 100644 --- a/chrome/browser/chromeos/crosapi/browser_util.cc +++ b/chrome/browser/chromeos/crosapi/browser_util.cc
@@ -83,6 +83,7 @@ params->session_type = environment_provider->GetSessionType(); params->device_mode = environment_provider->GetDeviceMode(); params->interface_versions = GetInterfaceVersions(); + params->default_paths = environment_provider->GetDefaultPaths(); return params; }
diff --git a/chrome/browser/chromeos/crosapi/environment_provider.cc b/chrome/browser/chromeos/crosapi/environment_provider.cc index 28d1721..e0e1f27 100644 --- a/chrome/browser/chromeos/crosapi/environment_provider.cc +++ b/chrome/browser/chromeos/crosapi/environment_provider.cc
@@ -4,9 +4,13 @@ #include "chrome/browser/chromeos/crosapi/environment_provider.h" +#include "base/files/file_util.h" +#include "base/system/sys_info.h" +#include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profiles_state.h" +#include "chromeos/crosapi/mojom/crosapi.mojom.h" #include "chromeos/tpm/install_attributes.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/user_manager/user.h" @@ -55,4 +59,29 @@ } } +mojom::DefaultPathsPtr EnvironmentProvider::GetDefaultPaths() { + mojom::DefaultPathsPtr default_paths = mojom::DefaultPaths::New(); + // The default paths belong to ash's primary user profile. Lacros does not + // support multi-signin. + const user_manager::User* user = + user_manager::UserManager::Get()->GetPrimaryUser(); + Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user); + if (base::SysInfo::IsRunningOnChromeOS()) { + // Typically /home/chronos/u-<hash>/MyFiles. + default_paths->documents = + file_manager::util::GetMyFilesFolderForProfile(profile); + // Typically /home/chronos/u-<hash>/MyFiles/Downloads. + default_paths->downloads = + file_manager::util::GetDownloadsFolderForProfile(profile); + } else { + // On developer linux workstations the above functions do path mangling to + // support multi-signin which gets undone later in ash-specific code. This + // is awkward for Lacros development, so just provide some defaults. + base::FilePath home = base::GetHomeDir(); + default_paths->documents = home.Append("Documents"); + default_paths->downloads = home.Append("Downloads"); + } + return default_paths; +} + } // namespace crosapi
diff --git a/chrome/browser/chromeos/crosapi/environment_provider.h b/chrome/browser/chromeos/crosapi/environment_provider.h index c90bb54..d90609b 100644 --- a/chrome/browser/chromeos/crosapi/environment_provider.h +++ b/chrome/browser/chromeos/crosapi/environment_provider.h
@@ -20,6 +20,11 @@ // Virtual for tests. virtual crosapi::mojom::SessionType GetSessionType(); virtual crosapi::mojom::DeviceMode GetDeviceMode(); + + // Returns the default paths, such as Downloads and Documents (MyFiles). + // These are provided by ash because they are part of the device account, + // not the Lacros profile. + virtual crosapi::mojom::DefaultPathsPtr GetDefaultPaths(); }; } // namespace crosapi
diff --git a/chrome/browser/chromeos/crosapi/file_manager_ash.cc b/chrome/browser/chromeos/crosapi/file_manager_ash.cc index 2889cf1..7312bfb 100644 --- a/chrome/browser/chromeos/crosapi/file_manager_ash.cc +++ b/chrome/browser/chromeos/crosapi/file_manager_ash.cc
@@ -20,6 +20,8 @@ // Lacros does not support multi-signin. Lacros uses /home/chronos/user as the // base for all system-level directories but the file manager expects the raw // profile path with the /home/chronos/u-{hash} prefix. Clean up the path. +// TODO(https://crbug.com/1150702): Delete this function after all Lacros +// clients are on M89. Lacros is switching to use the raw profile path. base::FilePath ExpandPath(Profile* primary_profile, const base::FilePath& path) { return file_manager::util::ReplacePathPrefix(
diff --git a/chrome/browser/chromeos/crosapi/test_mojo_connection_manager.cc b/chrome/browser/chromeos/crosapi/test_mojo_connection_manager.cc index 99bcc8e..06a79c2 100644 --- a/chrome/browser/chromeos/crosapi/test_mojo_connection_manager.cc +++ b/chrome/browser/chromeos/crosapi/test_mojo_connection_manager.cc
@@ -9,11 +9,13 @@ #include "base/bind.h" #include "base/files/file_util.h" #include "base/logging.h" +#include "base/path_service.h" #include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "chrome/browser/chromeos/crosapi/ash_chrome_service_impl.h" #include "chrome/browser/chromeos/crosapi/browser_util.h" +#include "chrome/common/chrome_paths.h" #include "chromeos/constants/chromeos_switches.h" #include "mojo/public/cpp/platform/named_platform_channel.h" #include "mojo/public/cpp/platform/platform_channel.h" @@ -31,6 +33,12 @@ mojom::DeviceMode GetDeviceMode() override { return crosapi::mojom::DeviceMode::kConsumer; } + mojom::DefaultPathsPtr GetDefaultPaths() override { + mojom::DefaultPathsPtr paths = mojom::DefaultPaths::New(); + base::PathService::Get(chrome::DIR_USER_DOCUMENTS, &paths->documents); + base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &paths->downloads); + return paths; + } }; // TODO(crbug.com/1124494): Refactor the code to share with ARC.
diff --git a/chrome/browser/chromeos/file_manager/path_util_unittest.cc b/chrome/browser/chromeos/file_manager/path_util_unittest.cc index 6d83ac6..9e77c9e 100644 --- a/chrome/browser/chromeos/file_manager/path_util_unittest.cc +++ b/chrome/browser/chromeos/file_manager/path_util_unittest.cc
@@ -11,6 +11,7 @@ #include "base/files/file_path.h" #include "base/memory/ptr_util.h" #include "base/system/sys_info.h" +#include "base/test/scoped_running_on_chromeos.h" #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h" #include "chrome/browser/chromeos/crostini/crostini_manager.h" @@ -21,7 +22,6 @@ #include "chrome/browser/chromeos/fileapi/file_system_backend.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" @@ -49,10 +49,6 @@ namespace util { namespace { -const char kLsbRelease[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; - class FileManagerPathUtilTest : public testing::Test { public: FileManagerPathUtilTest() = default; @@ -93,8 +89,7 @@ GetDownloadsFolderForProfile(profile_.get())); // When running inside ChromeOS, it should return /home/u-{hash}/MyFiles. - chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, - base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; EXPECT_EQ("/home/chronos/u-0123456789abcdef/MyFiles", GetMyFilesFolderForProfile(profile_.get()).value()); EXPECT_EQ("/home/chronos/u-0123456789abcdef/MyFiles/Downloads", @@ -208,8 +203,7 @@ base::FilePath myfilesDownloadsFile = home.Append("MyFiles/Downloads/file.txt"); base::FilePath other("/some/other/path"); - chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, - base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; // MyFilesVolume enabled, migrate paths under Downloads. EXPECT_TRUE( MigrateFromDownloadsToMyFiles(profile_.get(), downloads, &result)); @@ -230,8 +224,7 @@ TEST_F(FileManagerPathUtilTest, MultiProfileDownloadsFolderMigration) { // MigratePathFromOldFormat is explicitly disabled on Linux build. // So we need to fake that this is real ChromeOS system. - chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, - base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; // /home/chronos/u-${HASH}/MyFiles/Downloads const FilePath kDownloadsFolder = @@ -688,8 +681,7 @@ } TEST_F(FileManagerPathUtilConvertUrlTest, ConvertPathToArcUrl_MyFiles) { - chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, - base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; GURL url; const base::FilePath myfiles = GetMyFilesFolderForProfile( chromeos::ProfileHelper::Get()->GetProfileByUserIdHashForTest( @@ -789,8 +781,7 @@ } TEST_F(FileManagerPathUtilConvertUrlTest, ConvertToContentUrls_MyFiles) { - chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, - base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; const base::FilePath myfiles = GetMyFilesFolderForProfile( chromeos::ProfileHelper::Get()->GetProfileByUserIdHashForTest( "user@gmail.com-hash"));
diff --git a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc index 18106b4..8e0c783 100644 --- a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc +++ b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
@@ -17,13 +17,13 @@ #include "base/memory/weak_ptr.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_running_on_chromeos.h" #include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h" #include "chrome/browser/chromeos/file_manager/volume_manager_observer.h" #include "chrome/browser/chromeos/file_system_provider/fake_extension_provider.h" #include "chrome/browser/chromeos/file_system_provider/service.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/constants/chromeos_features.h" @@ -44,9 +44,6 @@ namespace file_manager { namespace { -const char kLsbRelease[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; class LoggingObserver : public VolumeManagerObserver { public: @@ -1007,8 +1004,7 @@ TEST_F(VolumeManagerTest, VolumeManagerInitializeMyFilesVolume) { // Emulate running inside ChromeOS. - chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, - base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; volume_manager()->Initialize(); // Adds "Downloads" std::vector<base::WeakPtr<Volume>> volume_list = volume_manager()->GetVolumeList();
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc index 617e613..9a1477a 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -901,14 +901,6 @@ input_view_url_overridden = false; } -void InputMethodManagerImpl::StateImpl::ConnectMojoManager( - mojo::PendingReceiver<chromeos::ime::mojom::InputEngineManager> receiver) { - if (!ime_service_connector_) { - ime_service_connector_ = std::make_unique<ImeServiceConnector>(profile); - } - ime_service_connector_->SetupImeService(std::move(receiver)); -} - // ------------------------ InputMethodManagerImpl bool InputMethodManagerImpl::IsLoginKeyboard( const std::string& layout) const { @@ -1197,7 +1189,15 @@ void InputMethodManagerImpl::ConnectInputEngineManager( mojo::PendingReceiver<chromeos::ime::mojom::InputEngineManager> receiver) { DCHECK(state_); - state_->ConnectMojoManager(std::move(receiver)); + ImeServiceConnectorMap::iterator iter = + ime_service_connectors_.find(state_->profile); + if (iter == ime_service_connectors_.end()) { + auto connector_ = std::make_unique<ImeServiceConnector>(state_->profile); + iter = ime_service_connectors_ + .insert(std::make_pair(state_->profile, std::move(connector_))) + .first; + } + iter->second->SetupImeService(std::move(receiver)); } bool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const {
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.h b/chrome/browser/chromeos/input_method/input_method_manager_impl.h index 64fee58..897291f 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.h
@@ -129,11 +129,6 @@ // Reset the input view URL to the default url of the current input method. void ResetInputViewUrl(); - // Connect to an InputEngineManager instance in an IME Mojo service. - void ConnectMojoManager( - mojo::PendingReceiver<chromeos::ime::mojom::InputEngineManager> - receiver); - // ------------------------- Data members. Profile* const profile; @@ -188,8 +183,6 @@ InputMethodManager::UIStyle ui_style_ = InputMethodManager::UIStyle::kNormal; - std::unique_ptr<ImeServiceConnector> ime_service_connector_; - // Do not forget to update StateImpl::InitFrom(const StateImpl& other) and // StateImpl::Dump() when adding new data members!!! }; @@ -355,6 +348,12 @@ using ProfileEngineMap = std::map<Profile*, EngineMap, ProfileCompare>; ProfileEngineMap engine_map_; + // Map a profile to the IME service connector. + typedef std:: + map<Profile*, std::unique_ptr<ImeServiceConnector>, ProfileCompare> + ImeServiceConnectorMap; + ImeServiceConnectorMap ime_service_connectors_; + content::NotificationRegistrar notification_registrar_; DISALLOW_COPY_AND_ASSIGN(InputMethodManagerImpl);
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_mode_detector_unittest.cc b/chrome/browser/chromeos/login/demo_mode/demo_mode_detector_unittest.cc index 1e3e9ef..40ff08599 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_mode_detector_unittest.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_mode_detector_unittest.cc
@@ -8,12 +8,12 @@ #include "base/memory/ref_counted.h" #include "base/strings/string_number_conversions.h" +#include "base/test/scoped_chromeos_version_info.h" #include "base/test/scoped_command_line.h" #include "base/test/test_mock_time_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "chrome/browser/chromeos/login/ui/mock_login_display_host.h" -#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chromeos/constants/chromeos_switches.h" @@ -207,7 +207,7 @@ EXPECT_TRUE( base::Time::FromString("Wed, 24 Oct 2018 12:00:00 PDT", &release_time)); - ScopedSetRunningOnChromeOSForTesting version_info(lsb_release, release_time); + base::test::ScopedChromeOSVersionInfo version_info(lsb_release, release_time); ExpectDemoModeWillNotLaunch();
diff --git a/chrome/browser/chromeos/login/hwid_checker_unittest.cc b/chrome/browser/chromeos/login/hwid_checker_unittest.cc index 8d13cf7e..d4d744e4 100644 --- a/chrome/browser/chromeos/login/hwid_checker_unittest.cc +++ b/chrome/browser/chromeos/login/hwid_checker_unittest.cc
@@ -6,9 +6,9 @@ #include "base/system/sys_info.h" #include "base/test/scoped_command_line.h" +#include "base/test/scoped_running_on_chromeos.h" #include "base/time/time.h" #include "build/branding_buildflags.h" -#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h" #include "chromeos/system/fake_statistics_provider.h" #include "content/public/common/content_switches.h" #include "testing/gtest/include/gtest/gtest.h" @@ -139,9 +139,6 @@ } #if BUILDFLAG(GOOGLE_CHROME_BRANDING) -const char kLsbRelease[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; // Test logic for command line "test-type" switch. TEST(MachineHWIDCheckerTest, TestSwitch) { @@ -152,7 +149,7 @@ // THEN IsMachineHWIDCorrect() is always true. EXPECT_TRUE(IsMachineHWIDCorrect()); - ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; EXPECT_TRUE(IsMachineHWIDCorrect()); system::ScopedFakeStatisticsProvider fake_statistics_provider; @@ -166,7 +163,7 @@ // Test logic when not running on Chrome OS. TEST(MachineHWIDCheckerTest, NotOnChromeOS) { // GIVEN the OS is not Chrome OS. - ScopedSetRunningOnChromeOSForTesting fake_release("", base::Time()); + ASSERT_FALSE(base::SysInfo::IsRunningOnChromeOS()); // THEN IsMachineHWIDCorrect() is always true. EXPECT_TRUE(IsMachineHWIDCorrect()); @@ -182,7 +179,7 @@ // Test logic when running on Chrome OS but the HWID is not present. TEST(MachineHWIDCheckerTest, OnCrosNoHWID) { // GIVEN the OS is Chrome OS. - ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; // GIVEN the HWID is not present. system::ScopedFakeStatisticsProvider fake_statistics_provider; @@ -210,7 +207,7 @@ "DELL HORIZON MAGENTA DVT 4770"); // THEN IsMachineHWIDCorrect() is always true. - ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; EXPECT_TRUE(IsMachineHWIDCorrect()); fake_statistics_provider.SetMachineStatistic(system::kIsVmKey, system::kIsVmValueFalse); @@ -228,7 +225,7 @@ system::kIsVmValueTrue); // GIVEN the OS is Chrome OS. - ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; // THEN IsMachineHWIDCorrect() is always true. fake_statistics_provider.SetMachineStatistic(system::kHardwareClassKey, "INVALID_HWID"); @@ -245,7 +242,7 @@ // Test logic when HWID is invalid and we're not in a VM. TEST(MachineHWIDCheckerTest, InvalidHWIDInVMNotTrue) { // GIVEN the OS is Chrome OS. - ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; // GIVEN the HWID is invalid. system::ScopedFakeStatisticsProvider fake_statistics_provider;
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_files_unittest.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_files_unittest.cc index 08cf22e..5f5dc81 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_files_unittest.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_files_unittest.cc
@@ -9,6 +9,7 @@ #include "base/files/file_util.h" #include "base/test/bind.h" #include "base/test/mock_callback.h" +#include "base/test/scoped_running_on_chromeos.h" #include "chrome/browser/chromeos/crostini/crostini_test_helper.h" #include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/chromeos/guest_os/guest_os_registry_service.h" @@ -16,7 +17,6 @@ #include "chrome/browser/chromeos/plugin_vm/mock_plugin_vm_manager.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager_factory.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" -#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/test/base/testing_profile.h" @@ -35,10 +35,6 @@ testing::StrictMock<base::MockCallback< base::OnceCallback<void(const base::FilePath& dir, bool result)>>>; -const char kLsbRelease[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; - class PluginVmFilesTest : public testing::Test { protected: void SetUp() override { @@ -85,7 +81,7 @@ content::BrowserTaskEnvironment task_environment_; TestingProfile profile_; FakePluginVmFeatures fake_plugin_vm_features_; - chromeos::ScopedSetRunningOnChromeOSForTesting fake_release_{kLsbRelease, {}}; + base::test::ScopedRunningOnChromeOS running_on_chromeos_; std::string app_id_; storage::ExternalMountPoints* mount_points_; std::string mount_name_;
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.cc index d737669..300acf6 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.cc
@@ -7,13 +7,13 @@ #include "ash/public/cpp/shelf_item_delegate.h" #include "ash/public/cpp/shelf_model.h" #include "base/system/sys_info.h" +#include "base/test/scoped_running_on_chromeos.h" #include "base/time/time.h" #include "chrome/browser/chromeos/login/users/mock_user_manager.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_features.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/common/chrome_features.h" @@ -32,9 +32,6 @@ const char kPluginVmLicenseKey[] = "LICENSE_KEY"; const char kDomain[] = "example.com"; const char kDeviceId[] = "device_id"; -const char kLsbRelease[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; // For adding a fake shelf item without requiring opening an actual window. class FakeShelfItemDelegate : public ash::ShelfItemDelegate { @@ -124,9 +121,8 @@ account_id, true, user_manager::USER_TYPE_REGULAR); scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>( std::move(mock_user_manager)); - fake_release_ = - std::make_unique<chromeos::ScopedSetRunningOnChromeOSForTesting>( - kLsbRelease, base::Time::Now()); + running_on_chromeos_ = + std::make_unique<base::test::ScopedRunningOnChromeOS>(); } void PluginVmTestHelper::EnablePluginVmFeature() {
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.h index a738d16ec7..b011c9c 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.h +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_test_helper.h
@@ -10,9 +10,11 @@ class TestingProfile; -namespace chromeos { -class ScopedSetRunningOnChromeOSForTesting; -} // namespace chromeos +namespace base { +namespace test { +class ScopedRunningOnChromeOS; +} // namespace test +} // namespace base namespace user_manager { class ScopedUserManager; @@ -51,7 +53,7 @@ TestingProfile* testing_profile_; std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_; base::test::ScopedFeatureList scoped_feature_list_; - std::unique_ptr<chromeos::ScopedSetRunningOnChromeOSForTesting> fake_release_; + std::unique_ptr<base::test::ScopedRunningOnChromeOS> running_on_chromeos_; DISALLOW_COPY_AND_ASSIGN(PluginVmTestHelper); };
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc index 3cf252f..2894a87 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc +++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.cc
@@ -6,12 +6,14 @@ #include <vector> +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/privacy_screen_dlp_helper.h" #include "base/bind.h" #include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/policy/dlp/dlp_notification_helper.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" +#include "chrome/browser/ui/ash/chrome_capture_mode_delegate.h" #include "content/public/browser/visibility.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" @@ -113,19 +115,18 @@ return false; } -void DlpContentManager::OnVideoCaptureStarted(const ScreenshotArea& area, - base::OnceClosure stop_callback) { +void DlpContentManager::OnVideoCaptureStarted(const ScreenshotArea& area) { if (IsVideoCaptureRestricted(area)) { - std::move(stop_callback).Run(); + if (ash::features::IsCaptureModeEnabled()) + ChromeCaptureModeDelegate::Get()->InterruptVideoRecordingIfAny(); return; } - DCHECK(!running_video_capture_.has_value()); - running_video_capture_.emplace( - std::make_pair(area, std::move(stop_callback))); + DCHECK(!running_video_capture_area_.has_value()); + running_video_capture_area_.emplace(area); } void DlpContentManager::OnVideoCaptureStopped() { - running_video_capture_.reset(); + running_video_capture_area_.reset(); } bool DlpContentManager::IsCaptureModeInitRestricted() const { @@ -367,13 +368,13 @@ } void DlpContentManager::CheckRunningVideoCapture() { - if (!running_video_capture_.has_value()) + if (!running_video_capture_area_.has_value()) return; - const auto& area = running_video_capture_->first; - auto& stop_callback = running_video_capture_->second; - if (IsAreaRestricted(area, DlpContentRestriction::kVideoCapture)) { - std::move(stop_callback).Run(); - running_video_capture_.reset(); + if (IsAreaRestricted(*running_video_capture_area_, + DlpContentRestriction::kVideoCapture)) { + if (ash::features::IsCaptureModeEnabled()) + ChromeCaptureModeDelegate::Get()->InterruptVideoRecordingIfAny(); + running_video_capture_area_.reset(); } }
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h index 95d6a41..99200b3 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h +++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h
@@ -70,9 +70,7 @@ const content::DesktopMediaID& media_id) const; // Called when video capturing for |area| is started. - // |stop_callback| will be called when restricted content will appear there. - void OnVideoCaptureStarted(const ScreenshotArea& area, - base::OnceClosure stop_callback); + void OnVideoCaptureStarted(const ScreenshotArea& area); // Called when video capturing is stopped. void OnVideoCaptureStopped(); @@ -203,9 +201,8 @@ // Set of restriction applied to the currently visible content. DlpContentRestrictionSet on_screen_restrictions_; - // The currently running video capture are and callback to stop, if any. - base::Optional<std::pair<ScreenshotArea, base::OnceClosure>> - running_video_capture_; + // The currently running video capture area if any. + base::Optional<ScreenshotArea> running_video_capture_area_; // List of the currently running screen captures. std::vector<ScreenCaptureInfo> running_screen_captures_;
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc index 2375204..7e936b3 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc +++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc
@@ -4,11 +4,14 @@ #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h" +#include "ash/public/cpp/ash_features.h" +#include "base/test/scoped_feature_list.h" #include "base/values.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h" #include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/policy/policy_test_utils.h" +#include "chrome/browser/ui/ash/chrome_capture_mode_delegate.h" #include "chrome/browser/ui/ash/screenshot_area.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -45,7 +48,17 @@ class DlpContentManagerBrowserTest : public InProcessBrowserTest { public: - DlpContentManagerBrowserTest() {} + DlpContentManagerBrowserTest() = default; + ~DlpContentManagerBrowserTest() override = default; + + // InProcessBrowserTest: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature(ash::features::kCaptureMode); + InProcessBrowserTest::SetUp(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, ScreenshotsRestricted) { @@ -104,8 +117,6 @@ DlpContentManager* manager = DlpContentManager::Get(); aura::Window* root_window = browser()->window()->GetNativeWindow()->GetRootWindow(); - ScreenshotArea fullscreen = ScreenshotArea::CreateForPartialWindow( - root_window, root_window->bounds()); // Open first browser window. Browser* browser1 = browser(); @@ -130,7 +141,9 @@ // Start capture of the whole screen. base::RunLoop run_loop; - manager->OnVideoCaptureStarted(fullscreen, run_loop.QuitClosure()); + auto* capture_mode_delegate = ChromeCaptureModeDelegate::Get(); + capture_mode_delegate->StartObservingRestrictedContent( + root_window, root_window->bounds(), run_loop.QuitClosure()); // Move first window with confidential content to make it visible. browser1->window()->SetBounds(gfx::Rect(100, 100, 700, 700)); @@ -138,7 +151,7 @@ // Check that capture was requested to be stopped via callback. run_loop.Run(); - manager->OnVideoCaptureStopped(); + capture_mode_delegate->StopObservingRestrictedContent(); browser2->window()->Close(); } @@ -147,8 +160,6 @@ DlpContentManager* manager = DlpContentManager::Get(); aura::Window* root_window = browser()->window()->GetNativeWindow()->GetRootWindow(); - ScreenshotArea fullscreen = ScreenshotArea::CreateForPartialWindow( - root_window, root_window->bounds()); // Open first browser window. Browser* browser1 = browser(); @@ -173,7 +184,9 @@ // Start capture of the whole screen. base::RunLoop run_loop; - manager->OnVideoCaptureStarted(fullscreen, run_loop.QuitClosure()); + auto* capture_mode_delegate = ChromeCaptureModeDelegate::Get(); + capture_mode_delegate->StartObservingRestrictedContent( + root_window, root_window->bounds(), run_loop.QuitClosure()); // Move second window to make first window with confidential content visible. browser2->window()->SetBounds(gfx::Rect(150, 150, 700, 700)); @@ -181,7 +194,7 @@ // Check that capture was requested to be stopped via callback. run_loop.Run(); - manager->OnVideoCaptureStopped(); + capture_mode_delegate->StopObservingRestrictedContent(); browser2->window()->Close(); } @@ -190,8 +203,6 @@ DlpContentManager* manager = DlpContentManager::Get(); aura::Window* root_window = browser()->window()->GetNativeWindow()->GetRootWindow(); - ScreenshotArea fullscreen = ScreenshotArea::CreateForPartialWindow( - root_window, root_window->bounds()); // Open first browser window. Browser* browser1 = browser(); @@ -216,8 +227,9 @@ // Start capture of the whole screen. base::RunLoop run_loop; - manager->OnVideoCaptureStarted( - fullscreen, base::BindOnce([] { + auto* capture_mode_delegate = ChromeCaptureModeDelegate::Get(); + capture_mode_delegate->StartObservingRestrictedContent( + root_window, root_window->bounds(), base::BindOnce([] { FAIL() << "Video capture stop callback shouldn't be called"; })); @@ -225,8 +237,8 @@ browser1->window()->SetBounds(gfx::Rect(150, 150, 500, 500)); // Check that capture was not requested to be stopped via callback. - manager->OnVideoCaptureStopped(); run_loop.RunUntilIdle(); + capture_mode_delegate->StopObservingRestrictedContent(); browser2->window()->Close(); }
diff --git a/chrome/browser/chromeos/printing/history/print_job_info_proto_conversions_unittest.cc b/chrome/browser/chromeos/printing/history/print_job_info_proto_conversions_unittest.cc index c1ebe5a..f76d123 100644 --- a/chrome/browser/chromeos/printing/history/print_job_info_proto_conversions_unittest.cc +++ b/chrome/browser/chromeos/printing/history/print_job_info_proto_conversions_unittest.cc
@@ -20,7 +20,7 @@ constexpr char kVendorId[] = "iso_a3_297x420mm"; constexpr char kName[] = "name"; -constexpr char kUri[] = "ipp://192.168.1.5"; +constexpr char kUri[] = "ipp://192.168.1.5:631"; constexpr char kTitle[] = "title"; constexpr char kId[] = "id";
diff --git a/chrome/browser/chromeos/printing/print_management/print_job_info_mojom_conversions_unittest.cc b/chrome/browser/chromeos/printing/print_management/print_job_info_mojom_conversions_unittest.cc index 97a2510..ffe299c 100644 --- a/chrome/browser/chromeos/printing/print_management/print_job_info_mojom_conversions_unittest.cc +++ b/chrome/browser/chromeos/printing/print_management/print_job_info_mojom_conversions_unittest.cc
@@ -24,7 +24,7 @@ namespace { constexpr char kName[] = "name"; -constexpr char kUri[] = "ipp://192.168.1.5"; +constexpr char kUri[] = "ipp://192.168.1.5:631"; constexpr char kTitle[] = "title"; constexpr char kId[] = "id"; constexpr char kPrinterId[] = "printerId";
diff --git a/chrome/browser/chromeos/printing/printer_configurer.cc b/chrome/browser/chromeos/printing/printer_configurer.cc index f4139cb4..1cf5537 100644 --- a/chrome/browser/chromeos/printing/printer_configurer.cc +++ b/chrome/browser/chromeos/printing/printer_configurer.cc
@@ -226,7 +226,7 @@ base::MD5Context ctx; base::MD5Init(&ctx); base::MD5Update(&ctx, printer.id()); - base::MD5Update(&ctx, printer.uri().GetNormalized()); + base::MD5Update(&ctx, printer.uri().GetNormalized(false)); base::MD5Update(&ctx, printer.ppd_reference().user_supplied_ppd_url); base::MD5Update(&ctx, printer.ppd_reference().effective_make_and_model); char autoconf = printer.ppd_reference().autoconf ? 1 : 0;
diff --git a/chrome/browser/chromeos/printing/server_printers_provider_unittest.cc b/chrome/browser/chromeos/printing/server_printers_provider_unittest.cc index c7b45e3..8399c54 100644 --- a/chrome/browser/chromeos/printing/server_printers_provider_unittest.cc +++ b/chrome/browser/chromeos/printing/server_printers_provider_unittest.cc
@@ -57,7 +57,7 @@ Printer Printer2() { Printer printer("server-5da95e01216b1fe0ee1de25dc8d0a6e8"); printer.set_display_name("Color Laser - Name"); - std::string server("ipps://print-server.intranet.example.com"); + std::string server("ipps://print-server.intranet.example.com:443"); printer.set_print_server_uri(server); Uri url( "ipps://print-server.intranet.example.com/printers/Color Laser - Name"); @@ -151,12 +151,6 @@ OnServersChanged(true, print_servers); task_environment_.RunUntilIdle(); - auto first = server_printers_provider_->GetPrinters().front(); - - LOG(INFO) << first.printer.uri().GetNormalized() - << " server:" << first.printer.print_server_uri() - << " name:" << first.printer.display_name(); - EXPECT_THAT(server_printers_provider_->GetPrinters(), UnorderedElementsAre(PrinterMatcher(Printer1()), PrinterMatcher(Printer2())));
diff --git a/chrome/browser/chromeos/printing/specifics_translation_unittest.cc b/chrome/browser/chromeos/printing/specifics_translation_unittest.cc index d433668..3df67bc1 100644 --- a/chrome/browser/chromeos/printing/specifics_translation_unittest.cc +++ b/chrome/browser/chromeos/printing/specifics_translation_unittest.cc
@@ -19,7 +19,7 @@ constexpr char kManufacturer[] = "Manufacturer"; constexpr char kModel[] = "MODEL"; constexpr char kMakeAndModel[] = "Manufacturer MODEL"; -constexpr char kUri[] = "ipps://notaprinter.chromium.org/ipp/print"; +constexpr char kUri[] = "ipps://notaprinter.chromium.org:123/ipp/print"; constexpr char kUuid[] = "UUIDUUIDUUID"; const base::Time kUpdateTime = base::Time::FromInternalValue(22114455660000); @@ -49,7 +49,7 @@ EXPECT_EQ(kDisplayName, result->display_name()); EXPECT_EQ(kDescription, result->description()); EXPECT_EQ(kMakeAndModel, result->make_and_model()); - EXPECT_EQ(kUri, result->uri().GetNormalized()); + EXPECT_EQ(kUri, result->uri().GetNormalized(false)); EXPECT_EQ(kUuid, result->uuid()); EXPECT_EQ(kEffectiveMakeAndModel, @@ -125,7 +125,7 @@ EXPECT_EQ(kManufacturer, result->manufacturer()); EXPECT_EQ(kModel, result->model()); EXPECT_EQ(kMakeAndModel, result->make_and_model()); - EXPECT_EQ(kUri, result->uri().GetNormalized()); + EXPECT_EQ(kUri, result->uri().GetNormalized(false)); EXPECT_EQ(kUuid, result->uuid()); EXPECT_TRUE(result->ppd_reference().effective_make_and_model.empty());
diff --git a/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc b/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc index 10868ad..138b62e 100644 --- a/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc +++ b/chrome/browser/chromeos/printing/synced_printers_manager_unittest.cc
@@ -124,7 +124,7 @@ auto printers = manager_->GetSavedPrinters(); ASSERT_EQ(1U, printers.size()); - EXPECT_EQ(kTestUri, printers[0].uri().GetNormalized()); + EXPECT_EQ(kTestUri, printers[0].uri().GetNormalized(false)); ExpectObservedPrinterIdsAre(observer.saved_printers(), {kTestPrinterId}); }
diff --git a/chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.cc b/chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.cc deleted file mode 100644 index 57059b5..0000000 --- a/chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.cc +++ /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. - -#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h" - -#include "base/system/sys_info.h" - -namespace chromeos { - -ScopedSetRunningOnChromeOSForTesting::ScopedSetRunningOnChromeOSForTesting( - const std::string& lsb_release, - const base::Time& lsb_release_time) { - base::SysInfo::SetChromeOSVersionInfoForTest(lsb_release, lsb_release_time); -} - -ScopedSetRunningOnChromeOSForTesting::~ScopedSetRunningOnChromeOSForTesting() { - base::SysInfo::SetChromeOSVersionInfoForTest("", base::Time()); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h b/chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h deleted file mode 100644 index 84203961..0000000 --- a/chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_SCOPED_SET_RUNNING_ON_CHROMEOS_FOR_TESTING_H_ -#define CHROME_BROWSER_CHROMEOS_SCOPED_SET_RUNNING_ON_CHROMEOS_FOR_TESTING_H_ - -#include <string> - -#include "base/macros.h" -#include "base/time/time.h" - -namespace chromeos { - -// unit_tests must always reset status of modified global singletons, -// otherwise later tests will fail, because they are run in the same process. -// -// This object resets LSB-Release to empty string on destruction, forcing -// is_running_on_chromeos() to return false. -class ScopedSetRunningOnChromeOSForTesting { - public: - ScopedSetRunningOnChromeOSForTesting(const std::string& lsb_release, - const base::Time& lsb_release_time); - ~ScopedSetRunningOnChromeOSForTesting(); - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedSetRunningOnChromeOSForTesting); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_SCOPED_SET_RUNNING_ON_CHROMEOS_FOR_TESTING_H_
diff --git a/chrome/browser/extensions/activity_log/activity_log_unittest.cc b/chrome/browser/extensions/activity_log/activity_log_unittest.cc index b843c68..9f1b1f9 100644 --- a/chrome/browser/extensions/activity_log/activity_log_unittest.cc +++ b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
@@ -80,6 +80,9 @@ void ActivateExtension(const std::string& extension_id) override {} void SetActivityLoggingEnabled(bool enabled) override {} void UnloadExtension(const std::string& extension_id) override {} + void SetSessionInfo(version_info::Channel channel, + mojom::FeatureSessionType session, + bool is_lock_screen_context) override {} mojo::AssociatedReceiverSet<mojom::Renderer> receivers_; };
diff --git a/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc b/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc index a4ddb8c..f0b4942 100644 --- a/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc +++ b/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/extensions/api/tabs/tabs_util.h" +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/assistant/assistant_state.h" #include "base/metrics/histogram_macros.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" @@ -11,6 +12,7 @@ #include "chrome/browser/chromeos/arc/session/arc_session_manager.h" #include "chrome/browser/chromeos/assistant/assistant_util.h" #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h" +#include "chrome/browser/ui/ash/chrome_capture_mode_delegate.h" #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_command_controller.h" @@ -42,6 +44,11 @@ // Disallow screenshots in locked fullscreen mode. ChromeScreenshotGrabber::Get()->set_screenshots_allowed(!locked); + // Disable both screenshots and video screen captures via the capture mode + // feature. + if (ash::features::IsCaptureModeEnabled()) + ChromeCaptureModeDelegate::Get()->SetIsScreenCaptureLocked(locked); + // Reset the clipboard and kill dev tools when entering or exiting locked // fullscreen (security concerns). ui::Clipboard::GetForCurrentThread()->Clear(ui::ClipboardBuffer::kCopyPaste);
diff --git a/chrome/browser/font_access/chrome_font_access_delegate.cc b/chrome/browser/font_access/chrome_font_access_delegate.cc new file mode 100644 index 0000000..adca350 --- /dev/null +++ b/chrome/browser/font_access/chrome_font_access_delegate.cc
@@ -0,0 +1,25 @@ +// 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/font_access/chrome_font_access_delegate.h" + +#include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/font_access/font_access_chooser.h" +#include "chrome/browser/ui/font_access/font_access_chooser_controller.h" +#include "content/public/browser/render_frame_host.h" + +ChromeFontAccessDelegate::ChromeFontAccessDelegate() = default; +ChromeFontAccessDelegate::~ChromeFontAccessDelegate() = default; + +std::unique_ptr<content::FontAccessChooser> +ChromeFontAccessDelegate::RunChooser( + content::RenderFrameHost* frame, + content::FontAccessChooser::Callback callback) { + // TODO(crbug.com/1151464): Decide whether or not to extend/refactor the + // bubble view launched by chrome::ShowDeviceChooserDialog() or build a new + // one. + return std::make_unique<FontAccessChooser>(chrome::ShowDeviceChooserDialog( + frame, std::make_unique<FontAccessChooserController>( + frame, std::move(callback)))); +}
diff --git a/chrome/browser/font_access/chrome_font_access_delegate.h b/chrome/browser/font_access/chrome_font_access_delegate.h new file mode 100644 index 0000000..e6ac317 --- /dev/null +++ b/chrome/browser/font_access/chrome_font_access_delegate.h
@@ -0,0 +1,24 @@ +// 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_FONT_ACCESS_CHROME_FONT_ACCESS_DELEGATE_H_ +#define CHROME_BROWSER_FONT_ACCESS_CHROME_FONT_ACCESS_DELEGATE_H_ + +#include "content/public/browser/font_access_chooser.h" +#include "content/public/browser/font_access_delegate.h" + +class ChromeFontAccessDelegate : public content::FontAccessDelegate { + public: + ChromeFontAccessDelegate(); + ~ChromeFontAccessDelegate() override; + + ChromeFontAccessDelegate(ChromeFontAccessDelegate&) = delete; + ChromeFontAccessDelegate& operator=(ChromeFontAccessDelegate&) = delete; + + std::unique_ptr<content::FontAccessChooser> RunChooser( + content::RenderFrameHost* frame, + content::FontAccessChooser::Callback callback) override; +}; + +#endif // CHROME_BROWSER_FONT_ACCESS_CHROME_FONT_ACCESS_DELEGATE_H_
diff --git a/chrome/browser/lacros/lacros_chrome_service_delegate_impl.cc b/chrome/browser/lacros/lacros_chrome_service_delegate_impl.cc index ecae44b..79b12792 100644 --- a/chrome/browser/lacros/lacros_chrome_service_delegate_impl.cc +++ b/chrome/browser/lacros/lacros_chrome_service_delegate_impl.cc
@@ -4,8 +4,13 @@ #include "chrome/browser/lacros/lacros_chrome_service_delegate_impl.h" +#include "base/check.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" #include "base/metrics/statistics_recorder.h" +#include "base/path_service.h" +#include "base/system/sys_info.h" #include "chrome/browser/feedback/feedback_dialog_utils.h" #include "chrome/browser/lacros/feedback_util.h" #include "chrome/browser/lacros/system_logs/lacros_system_log_fetcher.h" @@ -15,6 +20,8 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/common/channel_info.h" +#include "chrome/common/chrome_paths.h" +#include "chromeos/crosapi/mojom/crosapi.mojom.h" #include "components/feedback/feedback_report.h" #include "components/feedback/feedback_util.h" #include "components/feedback/system_logs/system_logs_fetcher.h" @@ -24,12 +31,64 @@ constexpr char kHistogramsFilename[] = "lacros_histograms.txt"; +// Default directories for the ash-side primary user. +// TODO(https://crbug.com/1150702): Remove these after Lacros drops support for +// Chrome OS M89. +constexpr char kMyFilesPath[] = "/home/chronos/user/MyFiles"; +constexpr char kDefaultDownloadsPath[] = "/home/chronos/user/MyFiles/Downloads"; + +// Overrides the directory specified by |key| but does not try to create the +// directory if it does not exist. On device, the paths all exist already. For +// tests and the linux emulator, we don't want to pollute the file system. +void OverridePath(int key, const base::FilePath& path) { + // Ash should only send absolute paths. + CHECK(path.IsAbsolute()) << path; + base::PathService::OverrideAndCreateIfNeeded(key, path, /*is_absolute=*/true, + /*create=*/false); +} + } // namespace LacrosChromeServiceDelegateImpl::LacrosChromeServiceDelegateImpl() = default; LacrosChromeServiceDelegateImpl::~LacrosChromeServiceDelegateImpl() = default; +void LacrosChromeServiceDelegateImpl::OnInitialized( + const crosapi::mojom::LacrosInitParams& init_params) { + if (init_params.default_paths) { + // Set up default paths with values provided by ash. + OverridePath(chrome::DIR_USER_DOCUMENTS, + init_params.default_paths->documents); + OverridePath(chrome::DIR_DEFAULT_DOWNLOADS, + init_params.default_paths->downloads); + // "Safe" just means not configured by the user. On other platforms, the + // user can configure their default download directory to unsafe paths + // outside of chrome's control, but Chrome OS does not allow arbitrary + // path selection. + OverridePath(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, + init_params.default_paths->downloads); + } else { + // On older ash, provide some defaults. + // TODO(https://crbug.com/1150702): Remove this block after Lacros drops + // support for Chrome OS M89. + if (base::SysInfo::IsRunningOnChromeOS()) { + // On device, use /home/chronos/user paths. + OverridePath(chrome::DIR_USER_DOCUMENTS, base::FilePath(kMyFilesPath)); + OverridePath(chrome::DIR_DEFAULT_DOWNLOADS, + base::FilePath(kDefaultDownloadsPath)); + OverridePath(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, + base::FilePath(kDefaultDownloadsPath)); + } else { + // For developers on Linux desktop, just pick reasonable defaults. + base::FilePath home_dir = base::GetHomeDir(); + OverridePath(chrome::DIR_USER_DOCUMENTS, home_dir.Append("Documents")); + OverridePath(chrome::DIR_DEFAULT_DOWNLOADS, home_dir.Append("Downloads")); + OverridePath(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, + home_dir.Append("Downloads")); + } + } +} + void LacrosChromeServiceDelegateImpl::NewWindow() { // TODO(crbug.com/1102815): Find what profile should be used. Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy();
diff --git a/chrome/browser/lacros/lacros_chrome_service_delegate_impl.h b/chrome/browser/lacros/lacros_chrome_service_delegate_impl.h index 5cb8b33b..c36c2340 100644 --- a/chrome/browser/lacros/lacros_chrome_service_delegate_impl.h +++ b/chrome/browser/lacros/lacros_chrome_service_delegate_impl.h
@@ -21,6 +21,8 @@ ~LacrosChromeServiceDelegateImpl() override; // chromeos::LacrosChromeServiceDelegate: + void OnInitialized( + const crosapi::mojom::LacrosInitParams& init_params) override; void NewWindow() override; std::string GetChromeVersion() override; void GetFeedbackData(GetFeedbackDataCallback callback) override;
diff --git a/chrome/browser/lacros/lacros_chrome_service_delegate_impl_unittest.cc b/chrome/browser/lacros/lacros_chrome_service_delegate_impl_unittest.cc new file mode 100644 index 0000000..7c324be --- /dev/null +++ b/chrome/browser/lacros/lacros_chrome_service_delegate_impl_unittest.cc
@@ -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. + +#include "chrome/browser/lacros/lacros_chrome_service_delegate_impl.h" + +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/system/sys_info.h" +#include "base/test/scoped_path_override.h" +#include "chrome/common/chrome_paths.h" +#include "chromeos/crosapi/mojom/crosapi.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kLsbRelease[] = + "CHROMEOS_RELEASE_NAME=Chrome OS\n" + "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; + +// Overrides base::SysInfo::IsRunningOnChromeOS() to return true. +// TODO(jamescook): Switch to the shared helper once crrev.com/c/2538285 lands. +class ScopedIsRunningOnChromeOS { + public: + ScopedIsRunningOnChromeOS() { + base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); + } + ~ScopedIsRunningOnChromeOS() { + base::SysInfo::SetChromeOSVersionInfoForTest("", base::Time()); + } +}; + +class LacrosChromeServiceDelegateImplTest : public testing::Test { + public: + LacrosChromeServiceDelegateImplTest() = default; + LacrosChromeServiceDelegateImplTest( + const LacrosChromeServiceDelegateImplTest&) = delete; + LacrosChromeServiceDelegateImplTest& operator=( + const LacrosChromeServiceDelegateImplTest&) = delete; + ~LacrosChromeServiceDelegateImplTest() override = default; + + private: + ScopedIsRunningOnChromeOS running_on_chromeos_; + // Ensure we restore the previous paths for subsequent tests. We don't + // actually use these paths, so just point them at /tmp to avoid + // ScopedPathOverride from creating unnecessary temp directories. + base::ScopedPathOverride documents_override_{chrome::DIR_USER_DOCUMENTS, + base::FilePath("/tmp")}; + base::ScopedPathOverride downloads_override_{chrome::DIR_DEFAULT_DOWNLOADS, + base::FilePath("/tmp")}; + base::ScopedPathOverride downloads_safe_override_{ + chrome::DIR_DEFAULT_DOWNLOADS_SAFE, base::FilePath("/tmp")}; +}; + +TEST_F(LacrosChromeServiceDelegateImplTest, DefaultPaths) { + LacrosChromeServiceDelegateImpl delegate_impl; + + // Simulate ash sending some paths at startup. + auto default_paths = crosapi::mojom::DefaultPaths::New(); + default_paths->documents = base::FilePath("/test/documents"); + default_paths->downloads = base::FilePath("/test/downloads"); + auto init_params = crosapi::mojom::LacrosInitParams::New(); + init_params->default_paths = std::move(default_paths); + delegate_impl.OnInitialized(*init_params); + + // PathService has the new values. + base::FilePath path; + base::PathService::Get(chrome::DIR_USER_DOCUMENTS, &path); + EXPECT_EQ(path.AsUTF8Unsafe(), "/test/documents"); + base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &path); + EXPECT_EQ(path.AsUTF8Unsafe(), "/test/downloads"); + base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, &path); + EXPECT_EQ(path.AsUTF8Unsafe(), "/test/downloads"); +} + +// TODO(https://crbug.com/1150702): Delete this test after Lacros drops +// support for Chrome OS M89. +TEST_F(LacrosChromeServiceDelegateImplTest, DefaultPathsWithLegacyAsh) { + LacrosChromeServiceDelegateImpl delegate_impl; + + // Simulate ash not sending paths at startup. + auto init_params = crosapi::mojom::LacrosInitParams::New(); + ASSERT_TRUE(init_params->default_paths.is_null()); + delegate_impl.OnInitialized(*init_params); + + // PathService has reasonable values. + base::FilePath path; + base::PathService::Get(chrome::DIR_USER_DOCUMENTS, &path); + EXPECT_EQ(path.AsUTF8Unsafe(), "/home/chronos/user/MyFiles"); + base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &path); + EXPECT_EQ(path.AsUTF8Unsafe(), "/home/chronos/user/MyFiles/Downloads"); + base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, &path); + EXPECT_EQ(path.AsUTF8Unsafe(), "/home/chronos/user/MyFiles/Downloads"); +} + +} // namespace
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager.cc b/chrome/browser/nearby_sharing/nearby_notification_manager.cc index 12c10b3..5cafa3f 100644 --- a/chrome/browser/nearby_sharing/nearby_notification_manager.cc +++ b/chrome/browser/nearby_sharing/nearby_notification_manager.cc
@@ -170,6 +170,20 @@ : IDS_NEARBY_NOTIFICATION_SEND_FAILURE_TITLE); } +base::Optional<base::string16> GetFailureNotificationMessage( + TransferMetadata::Status status) { + switch (status) { + case TransferMetadata::Status::kTimedOut: + return l10n_util::GetStringUTF16(IDS_NEARBY_ERROR_TIME_OUT); + case TransferMetadata::Status::kNotEnoughSpace: + return l10n_util::GetStringUTF16(IDS_NEARBY_ERROR_NOT_ENOUGH_SPACE); + case TransferMetadata::Status::kUnsupportedAttachmentType: + return l10n_util::GetStringUTF16(IDS_NEARBY_ERROR_UNSUPPORTED_FILE_TYPE); + default: + return base::nullopt; + } +} + base::string16 GetConnectionRequestNotificationMessage( const ShareTarget& share_target, const TransferMetadata& transfer_metadata) { @@ -545,11 +559,11 @@ case TransferMetadata::Status::kFailed: case TransferMetadata::Status::kNotEnoughSpace: case TransferMetadata::Status::kUnsupportedAttachmentType: - ShowFailure(share_target); + ShowFailure(share_target, transfer_metadata); break; default: if (transfer_metadata.is_final_status()) - ShowFailure(share_target); + ShowFailure(share_target, transfer_metadata); break; } @@ -742,13 +756,21 @@ } } -void NearbyNotificationManager::ShowFailure(const ShareTarget& share_target) { +void NearbyNotificationManager::ShowFailure( + const ShareTarget& share_target, + const TransferMetadata& transfer_metadata) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); message_center::Notification notification = CreateNearbyNotification(kNearbyNotificationId); notification.set_title(GetFailureNotificationTitle(share_target)); + base::Optional<base::string16> message = + GetFailureNotificationMessage(transfer_metadata.status()); + if (message) { + notification.set_message(*message); + } + delegate_map_.erase(kNearbyNotificationId); notification_display_service_->Display(
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager.h b/chrome/browser/nearby_sharing/nearby_notification_manager.h index 6e446b5..71c7d37 100644 --- a/chrome/browser/nearby_sharing/nearby_notification_manager.h +++ b/chrome/browser/nearby_sharing/nearby_notification_manager.h
@@ -79,7 +79,8 @@ void ShowSuccess(const ShareTarget& share_target); // Shows a notification for send or receive failure. - void ShowFailure(const ShareTarget& share_target); + void ShowFailure(const ShareTarget& share_target, + const TransferMetadata& transfer_metadata); // Closes any currently shown transfer notification (e.g. progress or // connection).
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc b/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc index 469fbcd..b135e43 100644 --- a/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc +++ b/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
@@ -463,19 +463,39 @@ for (FileAttachment::Type type : param.file_attachments) share_target.file_attachments.push_back(CreateFileAttachment(type)); - manager()->ShowFailure(share_target); + for (std::pair<TransferMetadata::Status, int> error : + std::vector<std::pair<TransferMetadata::Status, int>>{ + {TransferMetadata::Status::kNotEnoughSpace, + IDS_NEARBY_ERROR_NOT_ENOUGH_SPACE}, + {TransferMetadata::Status::kTimedOut, IDS_NEARBY_ERROR_TIME_OUT}, + {TransferMetadata::Status::kUnsupportedAttachmentType, + IDS_NEARBY_ERROR_UNSUPPORTED_FILE_TYPE}, + {TransferMetadata::Status::kFailed, 0}, + }) { + manager()->ShowFailure( + share_target, + TransferMetadataBuilder().set_status(error.first).build()); - base::string16 expected = FormatNotificationTitle( - is_incoming ? IDS_NEARBY_NOTIFICATION_RECEIVE_FAILURE_TITLE - : IDS_NEARBY_NOTIFICATION_SEND_FAILURE_TITLE, - param, device_name); + base::string16 expected_title = FormatNotificationTitle( + is_incoming ? IDS_NEARBY_NOTIFICATION_RECEIVE_FAILURE_TITLE + : IDS_NEARBY_NOTIFICATION_SEND_FAILURE_TITLE, + param, device_name); + base::string16 expected_message = + error.second ? l10n_util::GetStringUTF16(error.second) + : base::string16(); - std::vector<message_center::Notification> notifications = - GetDisplayedNotifications(); - ASSERT_EQ(1u, notifications.size()); + std::vector<message_center::Notification> notifications = + GetDisplayedNotifications(); + ASSERT_EQ(1u, notifications.size()); - const message_center::Notification& notification = notifications[0]; - EXPECT_EQ(expected, notification.title()); + const message_center::Notification& notification = notifications[0]; + EXPECT_EQ(expected_title, notification.title()); + EXPECT_EQ(expected_message, notification.message()); + + notification_tester_->RemoveNotification( + NotificationHandler::Type::NEARBY_SHARE, notifications[0].id(), + /*by_user=*/true); + } } INSTANTIATE_TEST_SUITE_P( @@ -610,7 +630,7 @@ } TEST_F(NearbyNotificationManagerTest, ShowFailure_ShowsNotification) { - manager()->ShowFailure(ShareTarget()); + manager()->ShowFailure(ShareTarget(), TransferMetadataBuilder().build()); std::vector<message_center::Notification> notifications = GetDisplayedNotifications();
diff --git a/chrome/browser/net/chrome_network_delegate_unittest.cc b/chrome/browser/net/chrome_network_delegate_unittest.cc index d07d963..5c93fda 100644 --- a/chrome/browser/net/chrome_network_delegate_unittest.cc +++ b/chrome/browser/net/chrome_network_delegate_unittest.cc
@@ -13,6 +13,7 @@ #if defined(OS_CHROMEOS) || BUILDFLAG(IS_CHROMEOS_LACROS) #include "base/system/sys_info.h" +#include "base/test/scoped_running_on_chromeos.h" #include "base/time/time.h" #include "chrome/browser/download/download_prefs.h" #endif @@ -31,24 +32,6 @@ base::FilePath::FromUTF8Unsafe(profile_path)); } -#if defined(OS_CHROMEOS) || BUILDFLAG(IS_CHROMEOS_LACROS) -const char kLsbRelease[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; - -// TODO(jamescook): Merge with chromeos::ScopedSetRunningOnChromeOSForTesting. -// We can't use that here due to dependency issues. -class ScopedIsRunningOnChromeOS { - public: - ScopedIsRunningOnChromeOS() { - base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); - } - ~ScopedIsRunningOnChromeOS() { - base::SysInfo::SetChromeOSVersionInfoForTest("", base::Time()); - } -}; -#endif // defined(OS_CHROMEOS) || BUILDFLAG(IS_CHROMEOS_LACROS) - } // namespace TEST(ChromeNetworkDelegateStaticTest, IsAccessAllowed) { @@ -103,14 +86,24 @@ EXPECT_FALSE(IsAccessAllowed("/profile/GCache/v2", "/profile")); EXPECT_FALSE(IsAccessAllowed("/home/chronos/user/GCache/v2/id/Logs", "")); +#if !BUILDFLAG(IS_CHROMEOS_LACROS) + // TODO(https://crbug.com/1150575): The block below seems wrong. We should + // probably explicitly allow GetHomeDir().Append("Downloads") in + // ChromeNetworkDelegate::IsAccessAllowed on linux-chromeos. The default + // download directory should always be accessible, whether on linux-chromeos + // or device. The EXPECT_FALSE currently fails because ChromeTestSuite + // overrides DIR_USER_DOWNLOADS with a temp dir, which is under /tmp, which is + // always allowed. + // $HOME/Downloads is allowed for linux-chromeos, but not on devices. const std::string& home_downloads = DownloadPrefs::GetDefaultDownloadDirectory().value(); EXPECT_TRUE(IsAccessAllowed(home_downloads, "")); { - ScopedIsRunningOnChromeOS is_running_on_chromeos; + base::test::ScopedRunningOnChromeOS running_on_chromeos; EXPECT_FALSE(IsAccessAllowed(home_downloads, "")); } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) #elif defined(OS_ANDROID) // Android allows the following directories.
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc index 1a0288c..8055459 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc
@@ -210,6 +210,20 @@ optimization_target, std::move(callback), target_decision); } +void OptimizationGuideKeyedService::AddObserverForOptimizationTargetModel( + optimization_guide::proto::OptimizationTarget optimization_target, + optimization_guide::OptimizationTargetModelObserver* observer) { + // TODO(crbug/1146151): Passthrough to prediction manager. + NOTREACHED(); +} + +void OptimizationGuideKeyedService::RemoveObserverForOptimizationTargetModel( + optimization_guide::proto::OptimizationTarget optimization_target, + optimization_guide::OptimizationTargetModelObserver* observer) { + // TODO(crbug/1146151): Passthrough to prediction manager. + NOTREACHED(); +} + void OptimizationGuideKeyedService::RegisterOptimizationTypes( const std::vector<optimization_guide::proto::OptimizationType>& optimization_types) {
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service.h b/chrome/browser/optimization_guide/optimization_guide_keyed_service.h index ba6f0a3..80019ae 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service.h +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service.h
@@ -62,6 +62,12 @@ float>& client_model_feature_values, optimization_guide::OptimizationGuideTargetDecisionCallback callback) override; + void AddObserverForOptimizationTargetModel( + optimization_guide::proto::OptimizationTarget optimization_target, + optimization_guide::OptimizationTargetModelObserver* observer) override; + void RemoveObserverForOptimizationTargetModel( + optimization_guide::proto::OptimizationTarget optimization_target, + optimization_guide::OptimizationTargetModelObserver* observer) override; void RegisterOptimizationTypes( const std::vector<optimization_guide::proto::OptimizationType>& optimization_types) override;
diff --git a/chrome/browser/platform_util_lacros.cc b/chrome/browser/platform_util_lacros.cc index 33a593e..81af39f 100644 --- a/chrome/browser/platform_util_lacros.cc +++ b/chrome/browser/platform_util_lacros.cc
@@ -10,6 +10,8 @@ #include "chrome/browser/platform_util_internal.h" #include "chromeos/crosapi/mojom/file_manager.mojom.h" #include "chromeos/lacros/lacros_chrome_service_impl.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" namespace platform_util { namespace { @@ -24,11 +26,9 @@ LOG(ERROR) << "Unable to open " << path.AsUTF8Unsafe() << " " << result; } -} // namespace - -namespace internal { - -void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) { +// File manager remote can only be accessed on UI thread. +void OpenItemOnUiThread(const base::FilePath& path, OpenItemType type) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); auto* service = chromeos::LacrosChromeServiceImpl::Get(); if (service->GetInterfaceVersion(crosapi::mojom::FileManager::Uuid_) < 1) { LOG(ERROR) << "Unsupported ash version."; @@ -46,9 +46,20 @@ } } +} // namespace + +namespace internal { + +void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) { + // This function is called on a blocking thread, so open on the UI thread. + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&OpenItemOnUiThread, path, type)); +} + } // namespace internal void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); auto* service = chromeos::LacrosChromeServiceImpl::Get(); int interface_version = service->GetInterfaceVersion(crosapi::mojom::FileManager::Uuid_);
diff --git a/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc b/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc index 2bceddb..f1eba272 100644 --- a/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc +++ b/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/process/launch.h" #include "base/test/test_timeouts.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/common/chrome_result_codes.h" #include "chrome/common/chrome_switches.h" @@ -16,10 +17,10 @@ #include "content/public/common/result_codes.h" #include "content/public/test/browser_test.h" -// These tests don't apply to the Mac version; see GetCommandLineForRelaunch +// These tests don't apply to Mac or Lacros; see GetCommandLineForRelaunch // for details. -#if defined(OS_MAC) -#error This test file should not be part of the Mac build. +#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_LACROS) +#error Not supported on this platform. #endif namespace {
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html index 3e03dfd8..661ca90 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html +++ b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.html
@@ -84,10 +84,14 @@ display: inline-flex; } + .content { + height: 200px; + overflow: scroll; + } + #zeroStateContainer { display: flex; justify-content: center; - margin: 8px; } #zeroStateImageContainer { @@ -147,6 +151,10 @@ margin-block-end: 8px; } + #explanationContainer { + border-bottom: var(--cr-separator-line); + } + .explanation-section { display: flex; } @@ -159,21 +167,17 @@ } #contactList { - border-bottom: var(--cr-separator-line); border-top: var(--cr-separator-line); + padding-block-start: 8px; } #contactsHeading { font-size: 1.2rem; } - .contacts-section { - height: 72px; - } - .contact-item { display: flex; - height: 50px; + height: 40px; padding-block-end: 8px; padding-block-start: 8px; } @@ -194,8 +198,6 @@ #noContactsContainer { align-items: center; - border-bottom: var(--cr-separator-line); - border-top: var(--cr-separator-line); display: flex; flex-direction: column; padding-block-end: 16px; @@ -250,7 +252,7 @@ <!-- Zero state is shown only when no selection has been made yet. --> <template is="dom-if" if="[[showZeroState_(selectedVisibility, contactsState)]]"> - <div id="zeroStateContainer"> + <div id="zeroStateContainer" class="content"> <div id="zeroStateImageContainer"> <iron-icon id="zeroStateImage" icon="nearby-images:nearby-device-visibility"> @@ -273,7 +275,7 @@ <!-- Shown when contacts are currently being downloaded. --> <template is="dom-if" if="[[inContactsState_(contactsState, ContactsState.PENDING)]]"> - <div id="contactsPending" class="contacts-section"> + <div id="contactsPending" class="content"> <div>$i18n{nearbyShareContactVisibilityDownloading}</div> </div> </template> @@ -282,7 +284,7 @@ <template is="dom-if" if="[[inContactsState_(contactsState, ContactsState.FAILED)]]" on-dom-change="domChangeDownloadFailed_"> - <div id="contactsFailed" class="contacts-section"> + <div id="contactsFailed" class="content"> <iron-icon id="contactsFailedImage" icon="nearby-images:contacts-download-failed"> </iron-icon> @@ -292,100 +294,107 @@ </div> </template> + <!-- Show when the user has downloaded contacts but there are none.--> <template is="dom-if" - if="[[showExplanationState_(selectedVisibility, - contactsState)]]"> - <div id="explanation"> - - <div class="explanation-section"> - <iron-icon icon="nearby20:radar" class="padded-icon grey-icon"> - </iron-icon> - <div class="viz-description-section"> - <div class="cr-title-text"> - $i18n{nearbyShareContactVisibilityOthersTitle} - </div> - <div class="cr-secondary-text"> - $i18n{nearbyShareContactVisibilityOthers} - </div> - </div> + if="[[showEmptyState_(selectedVisibility, contactsState)]]"> + <div id="noContactsContainer" class="content"> + <iron-icon id="noContactsImage" + icon="nearby-images:contacts-empty"> + </iron-icon> + <div class="cr-title-text"> + $i18n{nearbyShareContactVisibilityNoContactsTitle} </div> + <div class="cr-secondary-text"> + $i18n{nearbyShareContactVisibilityNoContactsSubtitle} + </div> + </div> + </template> - <div class="explanation-section"> - <iron-icon icon="nearby20:visibility" class="padded-icon grey-icon"> - </iron-icon> - <div class="viz-description-section"> - <div class="cr-title-text"> - $i18n{nearbyShareContactVisibilityOwnTitle} + <!-- Show when contacts have downloaded and a state is selected. --> + <template is="dom-if" + if="[[showContactsContainer_(selectedVisibility, contactsState)]]"> + <div id="explanationContainer" class="content"> + + <template is="dom-if" + if="[[showExplanationState_(selectedVisibility, + contactsState)]]"> + <div id="explanation"> + + <div class="explanation-section"> + <iron-icon icon="nearby20:radar" class="padded-icon grey-icon"> + </iron-icon> + <div class="viz-description-section"> + <div class="cr-title-text"> + $i18n{nearbyShareContactVisibilityOthersTitle} + </div> + <div class="cr-secondary-text"> + $i18n{nearbyShareContactVisibilityOthers} + </div> + </div> </div> - <template is="dom-if" - if="[[isVisibility_(selectedVisibility,'all')]]"> - <div class="cr-secondary-text"> - $i18n{nearbyShareContactVisibilityOwnAll} + + <div class="explanation-section"> + <iron-icon icon="nearby20:visibility" + class="padded-icon grey-icon"> + </iron-icon> + <div class="viz-description-section"> + <div class="cr-title-text"> + $i18n{nearbyShareContactVisibilityOwnTitle} + </div> + <template is="dom-if" + if="[[isVisibility_(selectedVisibility,'all')]]"> + <div class="cr-secondary-text"> + $i18n{nearbyShareContactVisibilityOwnAll} + </div> + </template> + <template is="dom-if" + if="[[isVisibility_(selectedVisibility,'some')]]"> + <div class="cr-secondary-text"> + $i18n{nearbyShareContactVisibilityOwnSome} + </div> + </template> + <template is="dom-if" + if="[[isVisibility_(selectedVisibility,'none')]]"> + <div class="cr-secondary-text"> + $i18n{nearbyShareContactVisibilityOwnNone} + </div> + </template> </div> - </template> - <template is="dom-if" - if="[[isVisibility_(selectedVisibility,'some')]]"> - <div class="cr-secondary-text"> - $i18n{nearbyShareContactVisibilityOwnSome} - </div> - </template> - <template is="dom-if" - if="[[isVisibility_(selectedVisibility,'none')]]"> - <div class="cr-secondary-text"> - $i18n{nearbyShareContactVisibilityOwnNone} + </div> + + </div> + </template> + + <!-- Show when the user has one or more contacts downloaded. --> + <template is="dom-if" + if="[[showContactList_(selectedVisibility, + contactsState)]]"> + <div id="contactList"> + <template is="dom-repeat" items="[[contacts]]"> + <div class="contact-item" + disabled$="[[isVisibility_(selectedVisibility,'none')]]"> + <iron-icon icon="cr:person" + class="padded-icon grey-icon contact-icon"> + </iron-icon> + <div> + <div class="cr-title-text">[[item.name]]</div> + <div class="cr-secondary-text">[[item.description]]</div> + </div> + <template is="dom-if" + if="[[showContactCheckBoxes_(selectedVisibility)]]"> + <cr-toggle class="contact-toggle" checked="{{item.checked}}" + disabled="[[!isVisibility_(selectedVisibility,'some')]]" + on-click="syncContactToggleState_"> + </cr-toggle> + </template> </div> </template> </div> - </div> + </template> </div> - - <!-- Show when the user has downloaded contacts but there are none.--> - <template is="dom-if" - if="[[showEmptyState_(selectedVisibility, contactsState)]]"> - <div id="noContactsContainer"> - <iron-icon id="noContactsImage" - icon="nearby-images:contacts-empty"> - </iron-icon> - <div class="cr-title-text"> - $i18n{nearbyShareContactVisibilityNoContactsTitle} - </div> - <div class="cr-secondary-text"> - $i18n{nearbyShareContactVisibilityNoContactsSubtitle} - </div> - </div> - </template> - - <!-- Show when the user has one or more contacts downloaded. --> - <template is="dom-if" - if="[[showContactList_(selectedVisibility, - contactsState)]]"> - <iron-list id="contactList" items="[[contacts]]" - class="contacts-section"> - <template> - <div class="contact-item" - disabled$="[[isVisibility_(selectedVisibility,'none')]]"> - <iron-icon icon="cr:person" - class="padded-icon grey-icon contact-icon"> - </iron-icon> - <div> - <div class="cr-title-text">[[item.name]]</div> - <div class="cr-secondary-text">[[item.description]]</div> - </div> - <template is="dom-if" - if="[[showContactCheckBoxes_(selectedVisibility)]]"> - <cr-toggle class="contact-toggle" checked="{{item.checked}}" - disabled="[[!isVisibility_(selectedVisibility,'some')]]" - on-click="syncContactToggleState_"> - </cr-toggle> - </template> - </div> - </template> - </iron-list> - </template> - - </div> - </template> + </template> + </div> </template> <script src="nearby_contact_visibility.js"></script> </dom-module>
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js index 4fe68c17..1cd2597 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js +++ b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js
@@ -377,13 +377,28 @@ /** * @param {string} selectedVisibility * @param {string} contactsState + * @return {boolean} true when explanation container should be shown + * @private + */ + showContactsContainer_(selectedVisibility, contactsState) { + return this.showExplanationState_(selectedVisibility, contactsState) || + this.showContactList_(selectedVisibility, contactsState); + }, + + /** + * @param {string} selectedVisibility + * @param {string} contactsState * @return {boolean} true when explanation state should be shown * @private */ showExplanationState_(selectedVisibility, contactsState) { - return !this.showZeroState_(selectedVisibility, contactsState) && - !this.inContactsState_(contactsState, ContactsState.PENDING) && - !this.inContactsState_(contactsState, ContactsState.FAILED); + if (!selectedVisibility || contactsState === ContactsState.PENDING || + contactsState === ContactsState.FAILED) { + return false; + } + + return selectedVisibility === 'none' || + contactsState === ContactsState.HAS_CONTACTS; }, /**
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_shared_icons.html b/chrome/browser/resources/nearby_share/shared/nearby_shared_icons.html index 3180ef6..936a299 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_shared_icons.html +++ b/chrome/browser/resources/nearby_share/shared/nearby_shared_icons.html
@@ -51,8 +51,9 @@ <path d="M0 0h200v200H0z"></path><path d="M150.441 100.728c0 26.949-21.772 48.794-48.63 48.794-26.858 0-48.63-21.845-48.63-48.794 0-26.95 21.772-48.795 48.63-48.795 26.858 0 48.63 21.845 48.63 48.795" fill="#D2E3FC"></path><path d="M176.711 53.44l-12.39-3.317a1.021 1.021 0 0 1-.722-1.25l3.32-12.383a1.022 1.022 0 0 1 1.252-.722l12.39 3.317c.544.146.868.707.722 1.251l-3.32 12.383a1.022 1.022 0 0 1-1.252.722" fill="#34A853"></path><path d="M31.832 148.371l-9.514 5.538c-3.553 2.068-4.77 6.644-2.72 10.223 2.053 3.584 6.603 4.813 10.161 2.742l9.514-5.538c3.48-2.026 4.718-6.454 2.844-9.998l-.124-.225c-2.053-3.584-6.603-4.813-10.161-2.742zm8.425 3.736c1.505 2.627.612 5.986-1.99 7.5l-9.514 5.539c-2.597 1.511-5.918.614-7.42-2.008-1.504-2.627-.61-5.986 1.991-7.5l9.514-5.539c2.529-1.471 5.743-.66 7.297 1.804l.122.204z" fill="#EA4335" fill-rule="nonzero"></path><path d="M26.693 54.6l-5.899-5.896a2.743 2.743 0 0 1-.711-2.653l2.159-8.054a2.745 2.745 0 0 1 1.943-1.941l8.058-2.158a2.75 2.75 0 0 1 2.655.71l5.9 5.896c.693.694.965 1.705.71 2.653L39.35 51.21a2.746 2.746 0 0 1-1.943 1.942l-8.058 2.158a2.751 2.751 0 0 1-2.655-.71" fill="#FBBC05"></path><path d="M26.536 141.312l-5.553-4.145a.552.552 0 0 1-.113-.773l4.149-5.55a.552.552 0 0 1 .773-.112l5.554 4.145a.552.552 0 0 1 .112.773l-4.149 5.55a.552.552 0 0 1-.773.112" fill="#F882FF"></path><path d="M102.004 29.332c-39.453 0-71.437 31.965-71.437 71.396 0 39.43 31.984 71.395 71.437 71.395 39.453 0 71.437-31.965 71.437-71.395 0-39.431-31.983-71.396-71.437-71.396zm0 2c38.35 0 69.437 31.07 69.437 69.396s-31.088 69.395-69.437 69.395-69.437-31.07-69.437-69.395c0-38.326 31.088-69.396 69.437-69.396z" fill="#4285F4" fill-rule="nonzero"></path><path d="M104.18 73.085a8.864 8.864 0 0 0-4.738 0l-19.099 7.12c-1.232.342-2.075 1.387-2.075 2.572v14.13c0 11.668 5.686 22.805 15.688 29.978 3.332 2.39 6.297 3.737 7.855 3.737 1.558 0 4.523-1.348 7.855-3.737 10.003-7.173 15.688-18.31 15.688-29.977V82.777c0-1.185-.842-2.23-2.075-2.573l-19.099-7.12z" fill="#4285F4"></path><path d="M101.768 94.59c-3.19 0-5.789 2.668-5.789 5.945 0 3.276 2.599 5.945 5.79 5.945 3.19 0 5.789-2.669 5.789-5.945 0-3.277-2.6-5.945-5.79-5.945zm-.193 9.115c-1.81 0-3.28-1.51-3.28-3.368 0-1.86 1.47-3.37 3.28-3.37 1.81 0 3.281 1.51 3.281 3.37 0 1.859-1.47 3.368-3.28 3.368zm.193-12.682c-6.14 0-11.384 3.944-13.508 9.512 2.124 5.567 7.368 9.512 13.508 9.512 6.14 0 11.384-3.945 13.509-9.512-2.125-5.568-7.368-9.512-13.509-9.512zm-.193 16.646c-4.726 0-8.942-2.763-11-7.134 2.058-4.371 6.274-7.134 11-7.134 4.727 0 8.942 2.763 11 7.134-2.058 4.37-6.273 7.134-11 7.134z" fill="#FFF" fill-rule="nonzero"></path> </g> - <path id="a" d="M.008.144h30.71v26.652H.007z"/><path d="M3.798.549A5.982 5.982 0 0 0 .812 8.458l5.764 12.741a5.97 5.97 0 0 0 7.9 2.99 5.982 5.982 0 0 0 2.987-7.909L11.697 3.54A5.96 5.96 0 0 0 3.798.55" id="c"/><path d="M1.258 10.212c-1.955 7.205 1.886 14.751 8.58 16.855l.196.063c6.694 2.104 13.705-2.03 15.66-9.234C27.65 10.691 23.81 3.145 17.117 1.04L16.92.978a11.78 11.78 0 0 0-3.546-.549C7.907.43 2.868 4.28 1.258 10.212z" id="e"/><path id="g" d="M0 .13h36.463v36.73H0z"/><path d="M25.094.245L.89 9.568c-.687.265-1.037 1.056-.782 1.769l8.985 25.114c.255.712 1.018 1.075 1.704.811L35 27.939c.687-.265 1.037-1.056.782-1.769L26.798 1.056A1.329 1.329 0 0 0 25.555.16c-.153 0-.31.028-.461.086" id="i"/> - <g id="nearby-onboarding-splash" fill="none" fill-rule="evenodd"><path d="M0 0h200v200H0z"/><path d="M110.893 164.142l-6.065 12.062c1.606.235 2.96.506 4.06.814 4.544 1.27 10.262 2.852 15.561 5.64 7.226 3.802 10.566 4.087 10.02.856-3.964-3.923-4.913-5.674-2.848-5.254 2.065.42 5.403 1.107 10.015 2.062.624-.243.804-.791.539-1.644-.208-.67-3.266-2.054-4.064-3.237-.146-.216.396-.215 1.624.003 2.632.41 4.12.547 4.465.41 1.163-.466-.097-2.017-.003-2.827.054-.468.801-.549 1.216-.806.288-.179.267-.554.36-.741.42-.842-3.068-1.44-2.8-2.494.274-1.075 4.274-2.606 1.607-3.406-5.282-1.583-10.813.808-16.629.56-3.877-.166-9.563-.832-17.058-1.998z" fill="#D2E3FC"/><path d="M141.354 171.58l.57.095 1.311.246c1.522.274 1.905.19 2.129-.434.02-.056-.109-.25-.638-.581-.664-.415-1.721-.839-3.074-1.237a.805.805 0 1 1 .454-1.543l.57.174c3.14.992 4.78 2.126 4.204 3.732-.561 1.563-1.636 1.851-3.696 1.512l-1.341-.249c-.275-.05-.504-.09-.735-.126a12.992 12.992 0 0 0-2.067-.174 32.862 32.862 0 0 0-4.908.396.806.806 0 0 1-.92-.672.803.803 0 0 1 .673-.918 34.47 34.47 0 0 1 5.148-.414c.753-.002 1.497.064 2.32.193z" fill="#4682F4" fill-rule="nonzero"/><path d="M134.892 176.05a.803.803 0 1 1 .003-1.609l1.163.008c.546.006.966.015 1.232.028l.092.005a18.507 18.507 0 0 1 2.379.322l.654.138c.519.115 1.48.336 1.707.384l.395.079c1.162.217 1.48.119 1.591-.306.206-.791-.878-1.532-3.807-2.045a.804.804 0 1 1 .276-1.585c3.753.658 5.634 1.944 5.09 4.037-.428 1.64-1.63 1.868-3.876 1.394l-1.942-.436a18.28 18.28 0 0 0-2.16-.345l-.401-.031-.424-.016a88.28 88.28 0 0 0-1.972-.022z" fill="#4682F4" fill-rule="nonzero"/><path d="M141.644 179.567c.18-.31.013-.618-.823-1.159-1.14-.736-3.19-1.51-6.125-2.293a.806.806 0 0 1-.571-.986.803.803 0 0 1 .984-.57c3.084.825 5.27 1.649 6.583 2.498 1.565 1.01 2.102 2.273 1.225 3.504-.514.722-1.262.731-2.752.368l-.552-.143c-.57-.153-1.557-.428-1.585-.435a32.331 32.331 0 0 0-2.211-.532 19.356 19.356 0 0 0-1.642-.258c-1.193-.132-2.08-.185-2.641-.16l-.234.016-.035.06a.798.798 0 0 1-.223.222l-.095.054a.805.805 0 0 1-1.075-.374c-.503-1.04.296-1.495 1.408-1.576.672-.05 1.687.005 3.07.158.58.065 1.169.158 1.778.28.61.12 1.21.262 1.896.443l2.295.625c.494.126.85.198 1.108.22l.186.012c.018.002.028.006.031.013v.013zm-13.848-1.352a.806.806 0 0 1-1.006-.534c-.452-1.475-.264-2.833.571-3.995.9-1.253 2.656-2.153 5.813-3.27l3.54-1.22.187-.068c.695-.257 1.397-.438 2.698-.713l1.718-.36c1.35-.292 2.061-.494 2.677-.773.748-.34.941-.604.836-.965-.172-.587-3.21-.75-7.838-.247l-.935.106c-.32.038-.647.079-.985.122l-5.142.7c-.596.077-1.065.135-1.254.15-2.193.181-7.982-.704-17.529-2.658a.804.804 0 1 1 .323-1.576l2.02.409c8.168 1.631 13.228 2.373 15.054 2.223l.305-.033c1.269-.15 5.264-.712 5.497-.742l1.029-.132c.332-.04.656-.08.973-.116l1.221-.13c5.403-.544 8.286-.313 8.807 1.474.376 1.29-.324 2.248-1.715 2.88l-.285.122c-.624.255-1.323.45-2.45.7l-2.466.52c-.771.17-1.286.304-1.735.454l-1.52.534c-1.005.347-2.173.743-2.13.728-3.045 1.058-4.745 1.9-5.405 2.818-.533.743-.649 1.579-.34 2.588a.804.804 0 0 1-.534 1.004z" fill="#4682F4" fill-rule="nonzero"/><path d="M135.161 182.503c.791 1.153.728 2.38-.312 3.488-1.426 1.52-4.087.752-10.188-2.074l-3.96-1.853a66.2 66.2 0 0 0-2.227-.987c-3.772-1.591-8.276-2.854-13.51-3.787a.806.806 0 0 1-.652-.933.803.803 0 0 1 .932-.652c5.064.903 9.474 2.113 13.233 3.632l.62.257c.83.349 1.486.641 2.657 1.185l3.215 1.507 1.046.481c4.608 2.09 7.048 2.774 7.66 2.122.511-.545.531-.935.16-1.477-.356-.519-.985-1.053-2.102-1.825l-.786-.532c-1.524-1.024-2.835-2.028-3.934-3.013a.805.805 0 1 1 1.072-1.198 33.243 33.243 0 0 0 3.277 2.548l1.027.695c1.343.913 2.13 1.548 2.662 2.262l.11.154z" fill="#4682F4" fill-rule="nonzero"/><path d="M92.163 196.078c.982.182 2.643.273 3.633.406.83.112 1.619-.175 2.423-.405.803-.232.747-.847.919-1.664.695-.113 1.406-.232 2.02-.574.616-.342 1.125-.96 1.137-1.661.007-.395-.558-.19-.444-.568.073-.236.66-1.04.785-1.255.527-.906.161-2.213-.76-2.716.363-.226.476-.726.358-1.135-.118-.409-.42-.74-.742-1.018-2.532-2.183-6.36-1.812-9.443-3.116.583-.446 1.347-.564 2.022-.851.675-.287 1.338-.898 1.241-1.624-.073-.554-.585-.969-1.125-1.117-.542-.148-1.115-.088-1.674-.049-3.745.265-7.532-.417-11.249.108-.252.037-.515.083-.717.238-.27.21-3.883-1.106-3.963-.774-.482 1.974-7.031-4.966-7.839-4.154-.807.812-11.512 9.186-11.706 10.15-.164.811 14.052 7.893 15.264 8.424 2.096.917 12.76 2.606 14.612 2.948 1.548.287 3.7.12 5.248.407z" fill="#D2E3FC"/><path d="M87.628 192.91a.806.806 0 0 1 .445-1.548c4.335 1.25 7.827 1.874 10.84 1.8.923-.021 1.458-.12 1.76-.356.22-.172.26-.694.048-.846a.806.806 0 0 1-.184-1.124.803.803 0 0 1 1.122-.185c1.153.829 1.014 2.634.003 3.425-.67.523-1.447.667-2.71.697-3.209.078-6.845-.572-11.324-1.863zm-.619-10.486a.806.806 0 0 1 .433-1.551l.341.091c1.706.442 6.23 1.446 7.773 1.731.713.132 1.388.288 2.361.538l.836.219c1.116.292 1.938.623 2.638 1.14.524.388.923.874 1.114 1.442.183.543.153 1.141-.125 1.632-.527.932-1.542 1.258-2.914 1.245a10.974 10.974 0 0 1-1.039-.064l-1.324-.156c-.403-.053-.82-.12-1.435-.226l-1.496-.259-1.511-.258a35.12 35.12 0 0 1-3.64-.82.806.806 0 0 1 .433-1.552c1.282.359 2.228.567 3.841.848l3.05.523c.51.085.867.137 1.248.183l.719.084c.47.055.826.083 1.169.086.843.008 1.344-.153 1.5-.428.038-.067.044-.192 0-.324-.074-.22-.266-.454-.545-.66-.445-.328-1.011-.573-1.789-.795l-.8-.214-.913-.233c-.55-.136-1-.238-1.446-.324l-.639-.122c-2.01-.396-6.554-1.415-7.84-1.776z" fill="#4285F4" fill-rule="nonzero"/><path d="M88.364 189.969a.806.806 0 0 1 .423-1.554c2.262.617 6.487 1.543 8.684 1.896 1.54.248 2.447.295 3.257.092.322-.081.51-.183.722-.395.12-.119.2-.406.171-.674-.037-.348-.215-.568-.462-.665l-.096-.03a.806.806 0 0 1 .39-1.563c.924.232 1.649.99 1.767 2.084.078.723-.14 1.497-.636 1.99-.425.423-.87.666-1.466.815-1.087.273-2.155.217-3.902-.064-2.255-.362-6.536-1.3-8.852-1.932zm-20.049-15.742a.806.806 0 0 1-.207-1.12.803.803 0 0 1 1.118-.207l.719.491c5.425 3.677 8.916 5.295 10.089 4.886 1.98-.69 3.677-.83 6.624-.68l4.398.28.608.03.294-.001.671-.012c.994-.007 1.669.11 2.315.521.71.453 1.16 1.257 1.056 2.078-.074.587-.414 1.102-.902 1.477-.446.344-1.076.6-1.943.84l-.503.13c-.52.126-1.46.338-1.569.365a.805.805 0 0 1-.394-1.562l1.556-.361.211-.052c.82-.212 1.391-.428 1.662-.637.172-.132.272-.284.287-.401.02-.154-.107-.38-.325-.518-.287-.183-.648-.259-1.235-.268l-.204-.001-.804.013c-.117 0-.213 0-.312-.004l-1.364-.076-2.767-.185c-3.14-.198-4.788-.125-6.595.465l-.237.08c-1.954.681-5.89-1.188-12.247-5.571zm-11.4 11.051a.806.806 0 0 1 .89-1.342c5.989 3.979 11.392 6.766 16.202 8.364l.532.172c3.514 1.113 6.104 1.57 11.318 2.09l4.4.419c1.719.173 2.897.325 4.1.538l.242.044c1.209.22 1.785.266 2.39.132.619-.137 1.118-.537 1.264-.985l.028-.113a.804.804 0 1 1 1.581.295c-.221 1.193-1.273 2.098-2.527 2.376-.756.167-1.398.149-2.457-.022l-1.265-.22c-1.168-.191-2.397-.337-4.238-.513l-2.742-.256c-5.96-.571-8.723-1.028-12.579-2.25-5.1-1.614-10.81-4.525-17.139-8.73z" fill="#4285F4" fill-rule="nonzero"/><g fill-rule="nonzero"><path d="M78.868 136.46l-.531.008c-.323.008-.621.021-.894.039l-.49.038-.12.016-9.915.101-.382-.018c-3.068-.115-6.78.197-10.366 1.302-2.21.682-4.172 1.626-5.815 2.868-3.822 2.89-5.187 7.466-6.244 17.638-.966 9.309 1.07 16.723 5.068 22.384a24.107 24.107 0 0 0 3.667 4.132c.76.675 1.36 1.117 1.72 1.34.266.167.602.16.861-.005l.093-.07 14.23-12.368c.335-.292.37-.8.078-1.135a.806.806 0 0 0-1.049-.144l-.087.066-13.753 11.953-.117-.088c-.21-.16-.432-.341-.667-.542l-.24-.209a22.505 22.505 0 0 1-3.42-3.857c-3.777-5.348-5.707-12.376-4.781-21.291l.161-1.49c.988-8.676 2.303-12.65 5.453-15.032 1.481-1.12 3.276-1.983 5.318-2.613 3.194-.985 6.534-1.306 9.34-1.247l.704.024.18.009 10.07-.106.264-.026.102-.008c.311-.025.67-.044 1.071-.054a25.64 25.64 0 0 1 3.7.18c3.7.447 7.071 1.653 9.76 3.825 1.895 1.531 3.246 3.777 4.756 7.685l.373.991c.454 1.273 3.058 8.852 4.112 11.6a.805.805 0 0 0 .544.49l.109.02 8.336 1.035-7.493 14.353-.253-.054c-2.408-.554-5.444-2.118-9.083-4.702l-.422-.302c-4.065-2.937-5.343-7.106-3.845-12.686a.806.806 0 0 0-1.556-.416c-1.663 6.198-.174 11.06 4.457 14.405 4.444 3.21 8.108 5.03 11.03 5.445a.81.81 0 0 0 .77-.329l.058-.096 8.3-15.901a.804.804 0 0 0-.513-1.15l-.101-.02-9.004-1.117-.494-1.347a368.1 368.1 0 0 1-.94-2.636l-2.547-7.277c-1.739-4.697-3.268-7.372-5.58-9.24-2.953-2.386-6.604-3.692-10.58-4.173a27.422 27.422 0 0 0-3.403-.198z" fill="#4285F4"/><path d="M61.551 153.314l-.1.002a.805.805 0 0 0-.742.764l.002.1 1.185 15.019a.802.802 0 0 0 .285.552l.087.064 6.522 4.123a.803.803 0 1 0 .95-1.294l-.088-.065-6.18-3.908-1.156-14.617a.805.805 0 0 0-.657-.728l-.108-.012z" fill="#4682F4"/><path d="M63.276 165.48a.805.805 0 0 0-.101 1.601l.101.007h22.233a.805.805 0 0 0 .101-1.602l-.1-.006H63.275z" fill="#4682F4"/></g><path d="M69.765 131.356h5.865l1.533 6.908c-.569 1.266-2.293 2.186-4.332 2.186-2.094 0-3.855-.97-4.376-2.287l1.31-6.807z" fill="#CFE3FF"/><path d="M75.63 130.552h-5.865a.805.805 0 0 0-.791.652l-1.31 6.807a.803.803 0 0 0 .042.447c.666 1.684 2.762 2.796 5.125 2.796 2.296 0 4.343-1.05 5.067-2.661a.803.803 0 0 0 .051-.503l-1.533-6.908a.805.805 0 0 0-.786-.63zm-.647 1.608l1.329 5.987-.027.046c-.557.839-1.897 1.453-3.454 1.453l-.228-.004c-1.506-.058-2.771-.69-3.272-1.52l-.036-.065 1.135-5.897h4.553z" fill="#4285F4" fill-rule="nonzero"/><path d="M76.445 122.877a6.147 6.147 0 0 1 .694 8.688 6.202 6.202 0 0 1-8.72.692 6.147 6.147 0 0 1-.694-8.689 6.202 6.202 0 0 1 8.72-.69z" fill="#CFE3FF"/><path d="M67.112 123.046a6.95 6.95 0 0 0 .785 9.823 7.008 7.008 0 0 0 9.855-.781 6.95 6.95 0 0 0-.785-9.823 7.008 7.008 0 0 0-9.855.781zm8.811.444a5.344 5.344 0 0 1 .604 7.553 5.396 5.396 0 0 1-7.587.601 5.344 5.344 0 0 1-.603-7.553 5.396 5.396 0 0 1 7.586-.601z" fill="#4285F4" fill-rule="nonzero"/><path fill="#4285F4" d="M66.246 124.853h11.057l-.299-2.25-4.155-1.117-2.297.041-2.571 1.65z"/><path d="M81.62 121.472c-.335.523-.8 1.009-1.21 1.469l-1.697 1.912h-6.757l2.306-2.545c1.127-1.244 1.971-2.238 3.384-3.065 1.483-.869 3.377-1.116 4.163.034l.024.037c.355.55.274 1.401-.212 2.158" fill="#0F3EC1"/><path d="M69.625 127.974c.4-.082.79.147.921.52l.03.106c.083.405.424.766.824.886l.121.03a.804.804 0 1 1-.275 1.584 2.827 2.827 0 0 1-2.249-2.178.804.804 0 0 1 .628-.948z" fill="#4285F4" fill-rule="nonzero"/><g transform="translate(87.766 169.167)"><path d="M0 12.79L2.687 1.536A2 2 0 0 1 4.632 0h11.823a2 2 0 0 1 1.928 2.533l-3.88 14.02L0 12.79z" fill="#4682F4"/><ellipse fill="#FFF" cx="6.285" cy="2.818" rx="1.007" ry="1.001"/></g><path d="M89.666 149.902c.488.11.795.595.685 1.082l-.412 1.874a39.22 39.22 0 0 0-.172.87 23.414 23.414 0 0 0-.372 2.834c-.129 2.02-.374 3.896-.757 5.674-.484 2.245-1.087 3.591-2.423 4.63a.907.907 0 0 1-1.271-.159.904.904 0 0 1 .158-1.27c.909-.706 1.363-1.72 1.764-3.582.318-1.475.537-3.028.67-4.69l.05-.72c.053-.81.153-1.625.303-2.51l.154-.84c.123-.641.252-1.23.54-2.509a.906.906 0 0 1 .97-.702l.113.018zM159.996 35.664h-5.559a.805.805 0 0 0-.737.48l-1.71 3.862a.804.804 0 0 0 .734 1.13l9.034.036a.804.804 0 0 0 .737-1.135l-1.765-3.9a.805.805 0 0 0-.734-.473zm-.522 1.608l1.036 2.286-6.55-.027 1.001-2.26h4.513z" fill="#4285F4" fill-rule="nonzero"/><path d="M161.948 41.21l-.376-.071-1.578.03c-2.899.047-5.226.04-6.982-.021l-.323-.012c-12.927-.517-20.131 5.42-29.147 22.158a.804.804 0 0 1-.397.36l-.105.036-19.632 5.21 5.93 13.082.087.008c7.582.697 14.44-1.076 20.608-5.325l.439-.308c6.424-4.572 10.44-10.685 12.07-18.37a.805.805 0 0 1 1.576.333c-1.714 8.08-5.959 14.541-12.71 19.347-6.75 4.804-14.327 6.763-22.696 5.868a.806.806 0 0 1-.599-.374l-.05-.094-6.515-14.37a.803.803 0 0 1 .427-1.074l.1-.034 20.214-5.364.112-.206c8.97-16.498 16.507-22.78 29.546-22.514l1.744.054c1.767.045 4.052.043 6.855-.007l1.075-.021.147.01.31.056.39.08c.139.028.286.06.443.096.888.203 1.871.466 2.924.799 3.008.95 5.976 2.264 8.694 4.002 7.825 5.004 12.045 12.458 10.865 22.73-1.18 10.273-7.632 17.093-17.468 21.09-3.416 1.388-7.007 2.33-10.556 2.913a49.07 49.07 0 0 1-3.42.443l-.511.043-.742.049a.806.806 0 0 1-.826-.478l-.037-.104-5.588-19.616a.806.806 0 1 1 1.512-.542l.038.103 5.41 18.992.344-.026.251-.023a47.465 47.465 0 0 0 3.307-.428c3.438-.564 6.915-1.477 10.21-2.816 9.339-3.794 15.371-10.171 16.475-19.784 1.105-9.613-2.793-16.499-10.132-21.192-2.588-1.655-5.43-2.913-8.311-3.823a36.183 36.183 0 0 0-2.365-.662l-.431-.102a25.57 25.57 0 0 0-.606-.13z" fill="#4285F4" fill-rule="nonzero"/><g fill="#4285F4" fill-rule="nonzero"><path d="M152.34 90.536c.23.38.11.875-.27 1.106l-3.443 2.127-.68.406-.49.283c-1.488.848-3.158 1.685-5.746 2.87l-.569.254c-1.158.505-1.873.71-2.765.739-1.447.046-2.845-.649-3.411-1.88a.804.804 0 1 1 1.408-.77l.053.096c.268.583 1.048.97 1.899.944.696-.022 1.31-.216 2.46-.732l.256-.116c2.689-1.231 4.354-2.072 5.857-2.94l.451-.265.52-.312c.554-.34 2.592-1.611 3.366-2.081a.803.803 0 0 1 1.104.27z"/><path d="M145.072 91.074a.806.806 0 0 1-.333 1.09l-3.63 1.972c-.836.448-1.504.79-2.17 1.108-1.928.919-3.64 1.517-5.47 1.857-1.122.208-2.188.11-3.06-.383-1.26-.711-1.826-2.492-.811-3.658a.803.803 0 0 1 1.134-.078c.335.292.37.8.078 1.136-.266.306-.063.942.388 1.197.502.283 1.196.347 1.977.202 1.68-.312 3.263-.865 5.073-1.727l.484-.236a59.293 59.293 0 0 0 1.936-1.01l2.845-1.551.471-.253a.804.804 0 0 1 1.088.334z"/><path d="M143.99 88.052a.806.806 0 0 1-.31 1.095l-.713.41-1.405.829c-.92.536-1.538.866-2.245 1.187-1.85.84-3.59 1.482-5.303 1.933l-.75.186-.715.166c-.634.14-1.054.204-1.551.231-1.406.08-2.565-.275-3.268-1.278-.648-.92-.53-2.234.165-3.135 1.224-1.586 3.911-2.467 7.583-2.904a.805.805 0 0 1 .19 1.6c-3.254.387-5.635 1.168-6.501 2.289-.288.373-.336.919-.122 1.224.318.453.954.647 1.863.596.446-.025.84-.09 1.529-.249l.633-.15c1.79-.428 3.615-1.083 5.583-1.976l.35-.164c.58-.278 1.156-.598 2.01-1.1l.97-.575c.368-.217.627-.366.912-.526a.803.803 0 0 1 1.094.31zm4.263-12.866a.805.805 0 0 1-.813.795c-3.483-.04-7.396.654-12.402 2.014l-.606.167c-1.284.355-1.901.552-2.54.843l-.138.064c-.477.225-.785.44-.974.692-.176.233-.227.516-.15.683.127.274.612.423 1.446.41l.718-.03 6.73-.366a.805.805 0 0 1 .068 1.609l-2.754.145-3.532.2c-.362.018-.663.033-.963.046-1.563.066-2.662-.23-3.172-1.338-.347-.75-.185-1.651.324-2.328.377-.501.881-.854 1.572-1.18.695-.329 1.291-.536 2.39-.85l.546-.153c5.433-1.507 9.646-2.283 13.456-2.238.444.005.8.37.794.815z"/><path d="M142.915 84.726c.21.392.062.88-.33 1.09-4.438 2.373-7.59 3.063-12.93 2.921-.825-.022-1.339-.085-1.886-.289-.766-.285-1.391-.839-1.654-1.57-.431-1.202.238-2.558 1.377-3.236.584-.347 1.188-.525 2.052-.654l.856-.11c4.22-.512 6.293-1.111 10.039-2.917a.806.806 0 0 1 .698 1.451c-3.594 1.733-5.781 2.42-9.528 2.935l-1.56.197c-.827.107-1.321.237-1.736.483-.531.317-.826.913-.685 1.306.088.243.348.474.7.605.337.125.71.171 1.37.189 5.07.134 7.946-.495 12.13-2.732a.804.804 0 0 1 1.087.33z"/></g><path d="M142.765 48.928a.806.806 0 0 1 1.475.646c-.578 1.314-.63 2.915-.27 4.932l.073.382c.063.317.123.59.218 1.007l.38 1.656c.312 1.414.436 2.243.471 3.256l.007.314c.002.16 0 .333-.002.54l-.016 1.037c-.001.648.026 1.024.106 1.448.173.915.67 1.642 1.244 1.851l.059.017 7.962.085c7.285.062 11.603.047 12.686-.037l.063-.006.01-.03c.035-.143.06-.348.067-.61l.003-.166c.003-.9-.166-2.256-.508-4.05a.804.804 0 0 1 1.582-.301l.12.645c.697 3.868.621 5.743-.748 6.057l-.131.023c-1.028.134-5.758.155-14.565.071l-6.666-.073-.17-.02c-1.35-.31-2.299-1.612-2.59-3.158l-.054-.314c-.067-.462-.086-.912-.08-1.618l.017-1.052c.002-.173.001-.319-.002-.46l-.004-.138c-.035-1.026-.18-1.875-.58-3.608l-.273-1.183c-.063-.279-.11-.498-.157-.728l-.028-.14c-.498-2.492-.473-4.516.301-6.275z" fill="#4285F4" fill-rule="nonzero"/><g transform="translate(161.459 2.303)"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><path d="M.031 21.66c.255-2.568 2.554-4.442 5.135-4.182a4.682 4.682 0 0 1 3.421 2.037 4.695 4.695 0 0 1-.024-1.107c.255-2.568 2.554-4.442 5.13-4.181l.028.003c.964.097 1.783-.638 1.842-1.6.008-.125.02-.251.038-.378.31-2.172 2.166-3.863 4.365-4a4.6 4.6 0 0 1 1.472.143c.975.258 1.933-.483 1.994-1.484l.21-3.452c.163-2.651 3.1-4.178 5.379-2.795 2.277 1.383 2.258 4.683-.036 6.04l-3.811 2.254a1.61 1.61 0 0 0-.644 2.053c.325.718.47 1.527.384 2.366-.256 2.563-2.555 4.436-5.13 4.181l-.03-.003c-.942-.095-1.791.605-1.839 1.546a4.692 4.692 0 0 1-5.151 4.419 4.692 4.692 0 0 1-3.423-2.037c.05.36.064.73.026 1.107-.256 2.563-2.556 4.436-5.135 4.183-2.575-.26-4.457-2.55-4.201-5.113" fill="#4285F4" mask="url(#b)"/></g><path d="M161.475 26.911a6.484 6.484 0 0 1 .733 9.17c-2.341 2.733-6.464 3.06-9.21.73a6.486 6.486 0 0 1-.733-9.17 6.554 6.554 0 0 1 9.21-.73" fill="#FFF"/><path d="M151.653 27.118a7.289 7.289 0 0 0 .823 10.305c3.084 2.618 7.715 2.25 10.344-.82a7.288 7.288 0 0 0-.823-10.305c-3.084-2.617-7.714-2.25-10.344.82zm9.3.406a5.681 5.681 0 0 1 .643 8.034 5.747 5.747 0 0 1-8.076.64 5.683 5.683 0 0 1-.643-8.035 5.748 5.748 0 0 1 7.884-.796l.193.157z" fill="#4285F4" fill-rule="nonzero"/><path d="M163.92 32.616c.85-1.668-2.037-5.655-4.051-6.672-2.014-1.018-6.642-.056-7.493 1.612 1.71 1.768 8.243 4.389 10.677 4.884l.866.176z" fill="#4285F4"/><path d="M150.526 32.93a.806.806 0 0 1 1.043.18l.063.09c.277.454.758.755 1.199.755.442 0 .862-.225 1.05-.542l.05-.098a.806.806 0 0 1 1.485.623c-.418.994-1.478 1.625-2.585 1.625-1.034 0-2.02-.616-2.575-1.529a.803.803 0 0 1 .27-1.104z" fill="#4285F4" fill-rule="nonzero"/><path d="M167.507 66.135a.805.805 0 0 1 .433 1.546l-.106.029-20.582 4.257a.805.805 0 0 1-.432-1.546l.105-.029 20.582-4.257z" fill="#4682F4" fill-rule="nonzero"/><g fill="#4285F4" fill-rule="nonzero"><path d="M95.347 77.103a.806.806 0 0 1 .962-.61.803.803 0 0 1 .609.96c-.48 2.136-1.868 4.347-3.66 5.503l-.812.482c-.59.355-.932.637-1.146.966-.101.156-.136.288-.122.348.017.073.188.191.419.21.282.025.594-.046 1.156-.249l.903-.328c5.416-1.995 8.043-3.418 9.986-5.892.551-.702.944-1.426 1.083-2.05a.806.806 0 0 1 .961-.61.803.803 0 0 1 .61.959c-.199.893-.7 1.818-1.388 2.693-2.248 2.863-5.135 4.386-11.143 6.572l-.469.17c-.768.277-1.258.389-1.84.339-.864-.074-1.65-.615-1.845-1.443-.129-.545.019-1.102.34-1.595.335-.515.773-.902 1.414-1.312l.474-.287.375-.218c1.483-.863 2.725-2.788 3.133-4.608z"/><path d="M83.987 77.326c1.354-2.038 3.087-3.135 6.81-4.776l.392-.172c4.907-2.135 8.03-3.214 11.302-3.63a.803.803 0 1 1 .201 1.596c-3.076.39-6.09 1.432-10.862 3.509l-.714.315c-3.208 1.434-4.7 2.408-5.788 4.047-.354.533-.485 1.327-.337 2.025l.664 3.258c.478 2.406.985 5.058 1.1 5.804l.012.086c.109.792.274 1.145.438 1.154.259.015.718-.6 1.018-1.502.282-.847.3-1.733.109-3.212l-.21-1.433-.089-.5c-.05-.3-.087-.59-.11-.867-.137-1.667.196-2.735.589-3.205.616-.928 1.614-1.338 3.586-1.714l1.785-.313c.724-.13 1.088-.217 1.48-.347a.804.804 0 1 1 .505 1.527l-.233.074c-.464.14-.93.237-1.847.396l-.827.142-.537.098c-1.44.277-2.2.563-2.56 1.01l-.06.081c-.175.213-.379.866-.276 2.117.013.154.03.314.054.48l.143.835.16 1.09c.265 1.893.265 3.047-.135 4.247-.517 1.553-1.354 2.675-2.64 2.602-1.18-.067-1.645-.843-1.877-2.15l-.11-.699c-.251-1.478-1.239-6.519-1.707-8.723-.234-1.107-.032-2.343.57-3.25z"/><path d="M83.462 78.295a.803.803 0 1 1 1.388.814l-1.39 2.38c-1.383 2.392-2.463 4.338-3.33 6.014l-.114.229c-.108.233-.136.355-.118.421.018.067.257.263.373.279.19.026.441-.035.728-.184.611-.317 1.142-.857 1.777-1.744.438-.611.923-1.447 1.451-2.462a.803.803 0 1 1 1.428.74c-.56 1.078-1.077 1.97-1.57 2.658-.77 1.075-1.46 1.776-2.346 2.236-.558.29-1.125.427-1.689.35-.734-.1-1.514-.737-1.707-1.45-.165-.611-.026-1.073.357-1.811l.34-.65c1.108-2.1 2.53-4.606 4.422-7.82z"/></g><path d="M57.963 76.556a1.512 1.512 0 0 1 2.027-.102l.108.098 17.27 17.198 24.354-7.42a1.51 1.51 0 0 1 1.835.866l.049.136a1.51 1.51 0 0 1-.869 1.834l-.137.049-25.22 7.683a1.51 1.51 0 0 1-1.394-.273l-.112-.101-17.91-17.836a1.506 1.506 0 0 1-.001-2.132z" fill="#4285F4" fill-rule="nonzero"/><g><path d="M73.735 27.798a.957.957 0 0 1-.899-1.087 9.21 9.21 0 0 1 9.562-7.95c4.828.22 8.699 4.061 9.082 8.793a.922.922 0 0 1-.96 1.004l-16.785-.76z" fill="#F882FF"/><path d="M46.537 44.15l-7.78 3.522c-1.1.499-1.249 1.981-.268 2.67l6.939 4.87c.98.69 2.354.068 2.473-1.118l.842-8.396c.12-1.187-1.107-2.047-2.206-1.549" fill="#D2E3FC"/><path d="M45.335 46.642c-2.101-2.484-1.676-6.184.948-8.262l11.107-8.82c2.625-2.08 6.456-1.752 8.557.732s1.677 6.184-.948 8.263l-11.106 8.82c-2.625 2.08-6.456 1.75-8.558-.733" fill="#FABD04"/><g transform="rotate(-102 42.988 6.811)"><mask id="d" fill="#fff"><use xlink:href="#c"/></mask><path d="M3.01-6.275c-.34 0-.687.118-.977.375L-4.024-.53c-.856.758-.57 2.16.514 2.523L4.162 4.56c.16.053.32.078.476.078.896 0 1.644-.83 1.45-1.785L4.472-5.084a1.484 1.484 0 0 0-1.461-1.19M2.817-4.19l1.398 6.865-6.638-2.22 5.24-4.645" fill="#FFF" mask="url(#d)"/></g><path d="M43.26 66.655l-3.847-6.7a2.573 2.573 0 0 0-2.228-1.28l-7.868-.026a2.63 2.63 0 0 0-2.261 1.264l-4.022 6.673a2.504 2.504 0 0 0-.032 2.543l3.847 6.7a2.572 2.572 0 0 0 2.228 1.28l7.868.026a2.632 2.632 0 0 0 2.262-1.264l4.02-6.672a2.503 2.503 0 0 0 .033-2.544" fill="#38A953"/><path d="M42.107 102.465h0v-.002a8.461 8.461 0 0 0-1.253-1.538l-1.343-1.65a6.942 6.942 0 0 1-1.515-5.197l.28-2.386.122-1.045-.055-.007a5.94 5.94 0 0 0-.06-.752c-.492-3.26-3.588-5.485-6.915-4.972-3.328.513-5.628 3.571-5.135 6.83.037.252.097.496.165.735l-.05.024.424.96.97 2.194a6.96 6.96 0 0 1 .088 5.417l-.795 1.98a8.491 8.491 0 0 0-.741 1.845l-.001.002h0a8.374 8.374 0 0 0-.038 4.236c1.006 4.032 4.942 6.764 9.169 6.373 5.048-.468 8.615-4.991 7.886-9.824a8.323 8.323 0 0 0-1.203-3.223z" stroke="#D2E3FC" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M40.532 135.356c-7.25-.375-12.761-6.448-12.311-13.564l.013-.21c.449-7.116 6.69-12.581 13.939-12.206 7.25.375 12.761 6.448 12.311 13.564l-.013.21c-.45 7.117-6.69 12.581-13.939 12.206" fill="#EA4335"/><g transform="rotate(-103 70.313 56.882)"><mask id="f" fill="#fff"><use xlink:href="#e"/></mask><path d="M28.924.89c-4.53.083-8.37 3.754-8.984 8.531-.727 5.66 3.137 10.797 8.463 11.23a8.667 8.667 0 0 0 3.378-.392l.274-.097.373-.145c.485-.2.925-.425 1.339-.683l.258-.17 1.826-.942a5.58 5.58 0 0 1 4.559-.274l3.188 1.201.11.034c.11.026.223.031.331.016l.02-.004.258.04c.092.013.183.022.275.03 3.737.304 6.968-2.686 7.245-6.64.278-3.947-2.488-7.413-6.216-7.717l-.31-.016h-.227l-.028-.01a.899.899 0 0 0-.324-.035l-.156.024-3.276.663-.275.048c-1.467.221-2.962-.153-4.2-1.061l-1.68-1.235-.225-.203a9.26 9.26 0 0 0-1.183-.869l-.317-.186A8.772 8.772 0 0 0 29.265.889h-.341zm.35 1.81a6.957 6.957 0 0 1 2.96.745l.296.157c.515.29.993.642 1.427 1.049l.083.068 1.714 1.26c1.723 1.265 3.848 1.744 5.905 1.328l3.01-.61.078.011.055.002.056-.001a4.46 4.46 0 0 1 .615.002c2.71.22 4.77 2.8 4.56 5.787-.21 2.979-2.592 5.184-5.294 4.964a4.622 4.622 0 0 1-.611-.097l-.111-.017-.079-.003-2.89-1.09a7.39 7.39 0 0 0-6.029.36l-1.87.968-.095.056a7.217 7.217 0 0 1-1.55.802l-.298.103a6.838 6.838 0 0 1-2.657.304c-4.266-.347-7.413-4.532-6.814-9.196.502-3.911 3.616-6.887 7.222-6.954l.316.001z" fill="#FFF" fill-rule="nonzero" mask="url(#f)"/></g></g><g><g transform="rotate(9 44.073 633.419)"><mask id="h" fill="#fff"><use xlink:href="#g"/></mask><path d="M35.644 27.522l-24.76 9.258a1.253 1.253 0 0 1-1.614-.745L.079 11.095a1.268 1.268 0 0 1 .74-1.627L25.58.21c.65-.243 1.372.09 1.614.745l9.191 24.94a1.268 1.268 0 0 1-.74 1.627" fill="#4285F4" mask="url(#h)"/></g><path d="M121.048 11.073a4.033 4.033 0 0 0-1.246.577l-.217.161c-.247.196-.47.42-.664.668l-.548.544a2.164 2.164 0 0 1-1.531.64h-1.374l-.094.007a.686.686 0 0 0-.177.052l-.072.014-.12.03a3.055 3.055 0 0 0-2.149 3.73 3.024 3.024 0 0 0 3.71 2.157l.2-.064.06-.007a.65.65 0 0 0 .13-.042l.178-.099 1.076-.625a2.152 2.152 0 0 1 1.64-.217l.815.22c.218.091.522.173.835.22.667.097 1.35.027 2-.215 1.854-.691 2.95-2.67 2.562-4.618-.461-2.313-2.759-3.742-5.014-3.133zm3.732 3.388c.263 1.322-.485 2.672-1.737 3.139a2.723 2.723 0 0 1-1.965-.019l-.888-.244a3.459 3.459 0 0 0-2.636.35l-1.052.609-.072.024a1.717 1.717 0 0 1-2.31-1.157 1.748 1.748 0 0 1 1.224-2.136l.065-.016c.045-.01.094-.018.15-.025l.069-.016 1.215-.001a3.47 3.47 0 0 0 2.456-1.024l.598-.601.106-.127a3.04 3.04 0 0 1 .4-.388l.16-.117a2.734 2.734 0 0 1 4.217 1.749zm-21.012-1.449a3.139 3.139 0 0 0-2.443 3.69 3.11 3.11 0 0 0 3.669 2.451 3.139 3.139 0 0 0 2.442-3.689 3.111 3.111 0 0 0-3.668-2.452zm2.387 2.706a1.832 1.832 0 0 1-1.422 2.155 1.803 1.803 0 0 1-2.126-1.426 1.833 1.833 0 0 1 1.422-2.155 1.803 1.803 0 0 1 2.09 1.281l.036.145z" fill="#FFF" fill-rule="nonzero"/><g transform="rotate(9 43.883 633.603)"><mask id="j" fill="#fff"><use xlink:href="#i"/></mask><path d="M13.402 18.342a.654.654 0 0 1 .782-.355l.09.035 25.268 11.894a.653.653 0 0 1-.467 1.217l-.09-.035-24.67-11.613-6.724 14.77a.654.654 0 0 1-.775.357l-.09-.033a.653.653 0 0 1-.358-.775l.034-.09 7-15.372z" fill="#FFF" fill-rule="nonzero" mask="url(#j)"/></g></g></g> + <g id="nearby-onboarding-splash" fill="none" fill-rule="evenodd"> + <path d="M0 0h200v200H0z"/><path d="M110.893 164.142l-6.065 12.062c1.606.235 2.96.506 4.06.814 4.544 1.27 10.262 2.852 15.561 5.64 7.226 3.802 10.566 4.087 10.02.856-3.964-3.923-4.913-5.674-2.848-5.254 2.065.42 5.403 1.107 10.015 2.062.624-.243.804-.791.539-1.644-.208-.67-3.266-2.054-4.064-3.237-.146-.216.396-.215 1.624.003 2.632.41 4.12.547 4.465.41 1.163-.466-.097-2.017-.003-2.827.054-.468.801-.549 1.216-.806.288-.179.267-.554.36-.741.42-.842-3.068-1.44-2.8-2.494.274-1.075 4.274-2.606 1.607-3.406-5.282-1.583-10.813.808-16.629.56-3.877-.166-9.563-.832-17.058-1.998z" fill="#D2E3FC"/><path d="M141.354 171.58l.57.095 1.311.246c1.522.274 1.905.19 2.129-.434.02-.056-.109-.25-.638-.581-.664-.415-1.721-.839-3.074-1.237a.805.805 0 1 1 .454-1.543l.57.174c3.14.992 4.78 2.126 4.204 3.732-.561 1.563-1.636 1.851-3.696 1.512l-1.341-.249c-.275-.05-.504-.09-.735-.126a12.992 12.992 0 0 0-2.067-.174 32.862 32.862 0 0 0-4.908.396.806.806 0 0 1-.92-.672.803.803 0 0 1 .673-.918 34.47 34.47 0 0 1 5.148-.414c.753-.002 1.497.064 2.32.193z" fill="#4682F4" fill-rule="nonzero"/><path d="M134.892 176.05a.803.803 0 1 1 .003-1.609l1.163.008c.546.006.966.015 1.232.028l.092.005a18.507 18.507 0 0 1 2.379.322l.654.138c.519.115 1.48.336 1.707.384l.395.079c1.162.217 1.48.119 1.591-.306.206-.791-.878-1.532-3.807-2.045a.804.804 0 1 1 .276-1.585c3.753.658 5.634 1.944 5.09 4.037-.428 1.64-1.63 1.868-3.876 1.394l-1.942-.436a18.28 18.28 0 0 0-2.16-.345l-.401-.031-.424-.016a88.28 88.28 0 0 0-1.972-.022z" fill="#4682F4" fill-rule="nonzero"/><path d="M141.644 179.567c.18-.31.013-.618-.823-1.159-1.14-.736-3.19-1.51-6.125-2.293a.806.806 0 0 1-.571-.986.803.803 0 0 1 .984-.57c3.084.825 5.27 1.649 6.583 2.498 1.565 1.01 2.102 2.273 1.225 3.504-.514.722-1.262.731-2.752.368l-.552-.143c-.57-.153-1.557-.428-1.585-.435a32.331 32.331 0 0 0-2.211-.532 19.356 19.356 0 0 0-1.642-.258c-1.193-.132-2.08-.185-2.641-.16l-.234.016-.035.06a.798.798 0 0 1-.223.222l-.095.054a.805.805 0 0 1-1.075-.374c-.503-1.04.296-1.495 1.408-1.576.672-.05 1.687.005 3.07.158.58.065 1.169.158 1.778.28.61.12 1.21.262 1.896.443l2.295.625c.494.126.85.198 1.108.22l.186.012c.018.002.028.006.031.013v.013zm-13.848-1.352a.806.806 0 0 1-1.006-.534c-.452-1.475-.264-2.833.571-3.995.9-1.253 2.656-2.153 5.813-3.27l3.54-1.22.187-.068c.695-.257 1.397-.438 2.698-.713l1.718-.36c1.35-.292 2.061-.494 2.677-.773.748-.34.941-.604.836-.965-.172-.587-3.21-.75-7.838-.247l-.935.106c-.32.038-.647.079-.985.122l-5.142.7c-.596.077-1.065.135-1.254.15-2.193.181-7.982-.704-17.529-2.658a.804.804 0 1 1 .323-1.576l2.02.409c8.168 1.631 13.228 2.373 15.054 2.223l.305-.033c1.269-.15 5.264-.712 5.497-.742l1.029-.132c.332-.04.656-.08.973-.116l1.221-.13c5.403-.544 8.286-.313 8.807 1.474.376 1.29-.324 2.248-1.715 2.88l-.285.122c-.624.255-1.323.45-2.45.7l-2.466.52c-.771.17-1.286.304-1.735.454l-1.52.534c-1.005.347-2.173.743-2.13.728-3.045 1.058-4.745 1.9-5.405 2.818-.533.743-.649 1.579-.34 2.588a.804.804 0 0 1-.534 1.004z" fill="#4682F4" fill-rule="nonzero"/><path d="M135.161 182.503c.791 1.153.728 2.38-.312 3.488-1.426 1.52-4.087.752-10.188-2.074l-3.96-1.853a66.2 66.2 0 0 0-2.227-.987c-3.772-1.591-8.276-2.854-13.51-3.787a.806.806 0 0 1-.652-.933.803.803 0 0 1 .932-.652c5.064.903 9.474 2.113 13.233 3.632l.62.257c.83.349 1.486.641 2.657 1.185l3.215 1.507 1.046.481c4.608 2.09 7.048 2.774 7.66 2.122.511-.545.531-.935.16-1.477-.356-.519-.985-1.053-2.102-1.825l-.786-.532c-1.524-1.024-2.835-2.028-3.934-3.013a.805.805 0 1 1 1.072-1.198 33.243 33.243 0 0 0 3.277 2.548l1.027.695c1.343.913 2.13 1.548 2.662 2.262l.11.154z" fill="#4682F4" fill-rule="nonzero"/><path d="M92.163 196.078c.982.182 2.643.273 3.633.406.83.112 1.619-.175 2.423-.405.803-.232.747-.847.919-1.664.695-.113 1.406-.232 2.02-.574.616-.342 1.125-.96 1.137-1.661.007-.395-.558-.19-.444-.568.073-.236.66-1.04.785-1.255.527-.906.161-2.213-.76-2.716.363-.226.476-.726.358-1.135-.118-.409-.42-.74-.742-1.018-2.532-2.183-6.36-1.812-9.443-3.116.583-.446 1.347-.564 2.022-.851.675-.287 1.338-.898 1.241-1.624-.073-.554-.585-.969-1.125-1.117-.542-.148-1.115-.088-1.674-.049-3.745.265-7.532-.417-11.249.108-.252.037-.515.083-.717.238-.27.21-3.883-1.106-3.963-.774-.482 1.974-7.031-4.966-7.839-4.154-.807.812-11.512 9.186-11.706 10.15-.164.811 14.052 7.893 15.264 8.424 2.096.917 12.76 2.606 14.612 2.948 1.548.287 3.7.12 5.248.407z" fill="#D2E3FC"/><path d="M87.628 192.91a.806.806 0 0 1 .445-1.548c4.335 1.25 7.827 1.874 10.84 1.8.923-.021 1.458-.12 1.76-.356.22-.172.26-.694.048-.846a.806.806 0 0 1-.184-1.124.803.803 0 0 1 1.122-.185c1.153.829 1.014 2.634.003 3.425-.67.523-1.447.667-2.71.697-3.209.078-6.845-.572-11.324-1.863zm-.619-10.486a.806.806 0 0 1 .433-1.551l.341.091c1.706.442 6.23 1.446 7.773 1.731.713.132 1.388.288 2.361.538l.836.219c1.116.292 1.938.623 2.638 1.14.524.388.923.874 1.114 1.442.183.543.153 1.141-.125 1.632-.527.932-1.542 1.258-2.914 1.245a10.974 10.974 0 0 1-1.039-.064l-1.324-.156c-.403-.053-.82-.12-1.435-.226l-1.496-.259-1.511-.258a35.12 35.12 0 0 1-3.64-.82.806.806 0 0 1 .433-1.552c1.282.359 2.228.567 3.841.848l3.05.523c.51.085.867.137 1.248.183l.719.084c.47.055.826.083 1.169.086.843.008 1.344-.153 1.5-.428.038-.067.044-.192 0-.324-.074-.22-.266-.454-.545-.66-.445-.328-1.011-.573-1.789-.795l-.8-.214-.913-.233c-.55-.136-1-.238-1.446-.324l-.639-.122c-2.01-.396-6.554-1.415-7.84-1.776z" fill="#4285F4" fill-rule="nonzero"/><path d="M88.364 189.969a.806.806 0 0 1 .423-1.554c2.262.617 6.487 1.543 8.684 1.896 1.54.248 2.447.295 3.257.092.322-.081.51-.183.722-.395.12-.119.2-.406.171-.674-.037-.348-.215-.568-.462-.665l-.096-.03a.806.806 0 0 1 .39-1.563c.924.232 1.649.99 1.767 2.084.078.723-.14 1.497-.636 1.99-.425.423-.87.666-1.466.815-1.087.273-2.155.217-3.902-.064-2.255-.362-6.536-1.3-8.852-1.932zm-20.049-15.742a.806.806 0 0 1-.207-1.12.803.803 0 0 1 1.118-.207l.719.491c5.425 3.677 8.916 5.295 10.089 4.886 1.98-.69 3.677-.83 6.624-.68l4.398.28.608.03.294-.001.671-.012c.994-.007 1.669.11 2.315.521.71.453 1.16 1.257 1.056 2.078-.074.587-.414 1.102-.902 1.477-.446.344-1.076.6-1.943.84l-.503.13c-.52.126-1.46.338-1.569.365a.805.805 0 0 1-.394-1.562l1.556-.361.211-.052c.82-.212 1.391-.428 1.662-.637.172-.132.272-.284.287-.401.02-.154-.107-.38-.325-.518-.287-.183-.648-.259-1.235-.268l-.204-.001-.804.013c-.117 0-.213 0-.312-.004l-1.364-.076-2.767-.185c-3.14-.198-4.788-.125-6.595.465l-.237.08c-1.954.681-5.89-1.188-12.247-5.571zm-11.4 11.051a.806.806 0 0 1 .89-1.342c5.989 3.979 11.392 6.766 16.202 8.364l.532.172c3.514 1.113 6.104 1.57 11.318 2.09l4.4.419c1.719.173 2.897.325 4.1.538l.242.044c1.209.22 1.785.266 2.39.132.619-.137 1.118-.537 1.264-.985l.028-.113a.804.804 0 1 1 1.581.295c-.221 1.193-1.273 2.098-2.527 2.376-.756.167-1.398.149-2.457-.022l-1.265-.22c-1.168-.191-2.397-.337-4.238-.513l-2.742-.256c-5.96-.571-8.723-1.028-12.579-2.25-5.1-1.614-10.81-4.525-17.139-8.73z" fill="#4285F4" fill-rule="nonzero"/><g fill-rule="nonzero"><path d="M78.868 136.46l-.531.008c-.323.008-.621.021-.894.039l-.49.038-.12.016-9.915.101-.382-.018c-3.068-.115-6.78.197-10.366 1.302-2.21.682-4.172 1.626-5.815 2.868-3.822 2.89-5.187 7.466-6.244 17.638-.966 9.309 1.07 16.723 5.068 22.384a24.107 24.107 0 0 0 3.667 4.132c.76.675 1.36 1.117 1.72 1.34.266.167.602.16.861-.005l.093-.07 14.23-12.368c.335-.292.37-.8.078-1.135a.806.806 0 0 0-1.049-.144l-.087.066-13.753 11.953-.117-.088c-.21-.16-.432-.341-.667-.542l-.24-.209a22.505 22.505 0 0 1-3.42-3.857c-3.777-5.348-5.707-12.376-4.781-21.291l.161-1.49c.988-8.676 2.303-12.65 5.453-15.032 1.481-1.12 3.276-1.983 5.318-2.613 3.194-.985 6.534-1.306 9.34-1.247l.704.024.18.009 10.07-.106.264-.026.102-.008c.311-.025.67-.044 1.071-.054a25.64 25.64 0 0 1 3.7.18c3.7.447 7.071 1.653 9.76 3.825 1.895 1.531 3.246 3.777 4.756 7.685l.373.991c.454 1.273 3.058 8.852 4.112 11.6a.805.805 0 0 0 .544.49l.109.02 8.336 1.035-7.493 14.353-.253-.054c-2.408-.554-5.444-2.118-9.083-4.702l-.422-.302c-4.065-2.937-5.343-7.106-3.845-12.686a.806.806 0 0 0-1.556-.416c-1.663 6.198-.174 11.06 4.457 14.405 4.444 3.21 8.108 5.03 11.03 5.445a.81.81 0 0 0 .77-.329l.058-.096 8.3-15.901a.804.804 0 0 0-.513-1.15l-.101-.02-9.004-1.117-.494-1.347a368.1 368.1 0 0 1-.94-2.636l-2.547-7.277c-1.739-4.697-3.268-7.372-5.58-9.24-2.953-2.386-6.604-3.692-10.58-4.173a27.422 27.422 0 0 0-3.403-.198z" fill="#4285F4"/><path d="M61.551 153.314l-.1.002a.805.805 0 0 0-.742.764l.002.1 1.185 15.019a.802.802 0 0 0 .285.552l.087.064 6.522 4.123a.803.803 0 1 0 .95-1.294l-.088-.065-6.18-3.908-1.156-14.617a.805.805 0 0 0-.657-.728l-.108-.012z" fill="#4682F4"/><path d="M63.276 165.48a.805.805 0 0 0-.101 1.601l.101.007h22.233a.805.805 0 0 0 .101-1.602l-.1-.006H63.275z" fill="#4682F4"/></g><path d="M69.765 131.356h5.865l1.533 6.908c-.569 1.266-2.293 2.186-4.332 2.186-2.094 0-3.855-.97-4.376-2.287l1.31-6.807z" fill="#CFE3FF"/><path d="M75.63 130.552h-5.865a.805.805 0 0 0-.791.652l-1.31 6.807a.803.803 0 0 0 .042.447c.666 1.684 2.762 2.796 5.125 2.796 2.296 0 4.343-1.05 5.067-2.661a.803.803 0 0 0 .051-.503l-1.533-6.908a.805.805 0 0 0-.786-.63zm-.647 1.608l1.329 5.987-.027.046c-.557.839-1.897 1.453-3.454 1.453l-.228-.004c-1.506-.058-2.771-.69-3.272-1.52l-.036-.065 1.135-5.897h4.553z" fill="#4285F4" fill-rule="nonzero"/><path d="M76.445 122.877a6.147 6.147 0 0 1 .694 8.688 6.202 6.202 0 0 1-8.72.692 6.147 6.147 0 0 1-.694-8.689 6.202 6.202 0 0 1 8.72-.69z" fill="#CFE3FF"/><path d="M67.112 123.046a6.95 6.95 0 0 0 .785 9.823 7.008 7.008 0 0 0 9.855-.781 6.95 6.95 0 0 0-.785-9.823 7.008 7.008 0 0 0-9.855.781zm8.811.444a5.344 5.344 0 0 1 .604 7.553 5.396 5.396 0 0 1-7.587.601 5.344 5.344 0 0 1-.603-7.553 5.396 5.396 0 0 1 7.586-.601z" fill="#4285F4" fill-rule="nonzero"/><path fill="#4285F4" d="M66.246 124.853h11.057l-.299-2.25-4.155-1.117-2.297.041-2.571 1.65z"/><path d="M81.62 121.472c-.335.523-.8 1.009-1.21 1.469l-1.697 1.912h-6.757l2.306-2.545c1.127-1.244 1.971-2.238 3.384-3.065 1.483-.869 3.377-1.116 4.163.034l.024.037c.355.55.274 1.401-.212 2.158" fill="#0F3EC1"/><path d="M69.625 127.974c.4-.082.79.147.921.52l.03.106c.083.405.424.766.824.886l.121.03a.804.804 0 1 1-.275 1.584 2.827 2.827 0 0 1-2.249-2.178.804.804 0 0 1 .628-.948z" fill="#4285F4" fill-rule="nonzero"/><g transform="translate(87.766 169.167)"><path d="M0 12.79L2.687 1.536A2 2 0 0 1 4.632 0h11.823a2 2 0 0 1 1.928 2.533l-3.88 14.02L0 12.79z" fill="#4682F4"/><ellipse fill="#FFF" cx="6.285" cy="2.818" rx="1.007" ry="1.001"/></g><path d="M89.666 149.902c.488.11.795.595.685 1.082l-.412 1.874a39.22 39.22 0 0 0-.172.87 23.414 23.414 0 0 0-.372 2.834c-.129 2.02-.374 3.896-.757 5.674-.484 2.245-1.087 3.591-2.423 4.63a.907.907 0 0 1-1.271-.159.904.904 0 0 1 .158-1.27c.909-.706 1.363-1.72 1.764-3.582.318-1.475.537-3.028.67-4.69l.05-.72c.053-.81.153-1.625.303-2.51l.154-.84c.123-.641.252-1.23.54-2.509a.906.906 0 0 1 .97-.702l.113.018zM159.996 35.664h-5.559a.805.805 0 0 0-.737.48l-1.71 3.862a.804.804 0 0 0 .734 1.13l9.034.036a.804.804 0 0 0 .737-1.135l-1.765-3.9a.805.805 0 0 0-.734-.473zm-.522 1.608l1.036 2.286-6.55-.027 1.001-2.26h4.513z" fill="#4285F4" fill-rule="nonzero"/><path d="M161.948 41.21l-.376-.071-1.578.03c-2.899.047-5.226.04-6.982-.021l-.323-.012c-12.927-.517-20.131 5.42-29.147 22.158a.804.804 0 0 1-.397.36l-.105.036-19.632 5.21 5.93 13.082.087.008c7.582.697 14.44-1.076 20.608-5.325l.439-.308c6.424-4.572 10.44-10.685 12.07-18.37a.805.805 0 0 1 1.576.333c-1.714 8.08-5.959 14.541-12.71 19.347-6.75 4.804-14.327 6.763-22.696 5.868a.806.806 0 0 1-.599-.374l-.05-.094-6.515-14.37a.803.803 0 0 1 .427-1.074l.1-.034 20.214-5.364.112-.206c8.97-16.498 16.507-22.78 29.546-22.514l1.744.054c1.767.045 4.052.043 6.855-.007l1.075-.021.147.01.31.056.39.08c.139.028.286.06.443.096.888.203 1.871.466 2.924.799 3.008.95 5.976 2.264 8.694 4.002 7.825 5.004 12.045 12.458 10.865 22.73-1.18 10.273-7.632 17.093-17.468 21.09-3.416 1.388-7.007 2.33-10.556 2.913a49.07 49.07 0 0 1-3.42.443l-.511.043-.742.049a.806.806 0 0 1-.826-.478l-.037-.104-5.588-19.616a.806.806 0 1 1 1.512-.542l.038.103 5.41 18.992.344-.026.251-.023a47.465 47.465 0 0 0 3.307-.428c3.438-.564 6.915-1.477 10.21-2.816 9.339-3.794 15.371-10.171 16.475-19.784 1.105-9.613-2.793-16.499-10.132-21.192-2.588-1.655-5.43-2.913-8.311-3.823a36.183 36.183 0 0 0-2.365-.662l-.431-.102a25.57 25.57 0 0 0-.606-.13z" fill="#4285F4" fill-rule="nonzero"/><g fill="#4285F4" fill-rule="nonzero"><path d="M152.34 90.536c.23.38.11.875-.27 1.106l-3.443 2.127-.68.406-.49.283c-1.488.848-3.158 1.685-5.746 2.87l-.569.254c-1.158.505-1.873.71-2.765.739-1.447.046-2.845-.649-3.411-1.88a.804.804 0 1 1 1.408-.77l.053.096c.268.583 1.048.97 1.899.944.696-.022 1.31-.216 2.46-.732l.256-.116c2.689-1.231 4.354-2.072 5.857-2.94l.451-.265.52-.312c.554-.34 2.592-1.611 3.366-2.081a.803.803 0 0 1 1.104.27z"/><path d="M145.072 91.074a.806.806 0 0 1-.333 1.09l-3.63 1.972c-.836.448-1.504.79-2.17 1.108-1.928.919-3.64 1.517-5.47 1.857-1.122.208-2.188.11-3.06-.383-1.26-.711-1.826-2.492-.811-3.658a.803.803 0 0 1 1.134-.078c.335.292.37.8.078 1.136-.266.306-.063.942.388 1.197.502.283 1.196.347 1.977.202 1.68-.312 3.263-.865 5.073-1.727l.484-.236a59.293 59.293 0 0 0 1.936-1.01l2.845-1.551.471-.253a.804.804 0 0 1 1.088.334z"/><path d="M143.99 88.052a.806.806 0 0 1-.31 1.095l-.713.41-1.405.829c-.92.536-1.538.866-2.245 1.187-1.85.84-3.59 1.482-5.303 1.933l-.75.186-.715.166c-.634.14-1.054.204-1.551.231-1.406.08-2.565-.275-3.268-1.278-.648-.92-.53-2.234.165-3.135 1.224-1.586 3.911-2.467 7.583-2.904a.805.805 0 0 1 .19 1.6c-3.254.387-5.635 1.168-6.501 2.289-.288.373-.336.919-.122 1.224.318.453.954.647 1.863.596.446-.025.84-.09 1.529-.249l.633-.15c1.79-.428 3.615-1.083 5.583-1.976l.35-.164c.58-.278 1.156-.598 2.01-1.1l.97-.575c.368-.217.627-.366.912-.526a.803.803 0 0 1 1.094.31zm4.263-12.866a.805.805 0 0 1-.813.795c-3.483-.04-7.396.654-12.402 2.014l-.606.167c-1.284.355-1.901.552-2.54.843l-.138.064c-.477.225-.785.44-.974.692-.176.233-.227.516-.15.683.127.274.612.423 1.446.41l.718-.03 6.73-.366a.805.805 0 0 1 .068 1.609l-2.754.145-3.532.2c-.362.018-.663.033-.963.046-1.563.066-2.662-.23-3.172-1.338-.347-.75-.185-1.651.324-2.328.377-.501.881-.854 1.572-1.18.695-.329 1.291-.536 2.39-.85l.546-.153c5.433-1.507 9.646-2.283 13.456-2.238.444.005.8.37.794.815z"/><path d="M142.915 84.726c.21.392.062.88-.33 1.09-4.438 2.373-7.59 3.063-12.93 2.921-.825-.022-1.339-.085-1.886-.289-.766-.285-1.391-.839-1.654-1.57-.431-1.202.238-2.558 1.377-3.236.584-.347 1.188-.525 2.052-.654l.856-.11c4.22-.512 6.293-1.111 10.039-2.917a.806.806 0 0 1 .698 1.451c-3.594 1.733-5.781 2.42-9.528 2.935l-1.56.197c-.827.107-1.321.237-1.736.483-.531.317-.826.913-.685 1.306.088.243.348.474.7.605.337.125.71.171 1.37.189 5.07.134 7.946-.495 12.13-2.732a.804.804 0 0 1 1.087.33z"/></g><path d="M142.765 48.928a.806.806 0 0 1 1.475.646c-.578 1.314-.63 2.915-.27 4.932l.073.382c.063.317.123.59.218 1.007l.38 1.656c.312 1.414.436 2.243.471 3.256l.007.314c.002.16 0 .333-.002.54l-.016 1.037c-.001.648.026 1.024.106 1.448.173.915.67 1.642 1.244 1.851l.059.017 7.962.085c7.285.062 11.603.047 12.686-.037l.063-.006.01-.03c.035-.143.06-.348.067-.61l.003-.166c.003-.9-.166-2.256-.508-4.05a.804.804 0 0 1 1.582-.301l.12.645c.697 3.868.621 5.743-.748 6.057l-.131.023c-1.028.134-5.758.155-14.565.071l-6.666-.073-.17-.02c-1.35-.31-2.299-1.612-2.59-3.158l-.054-.314c-.067-.462-.086-.912-.08-1.618l.017-1.052c.002-.173.001-.319-.002-.46l-.004-.138c-.035-1.026-.18-1.875-.58-3.608l-.273-1.183c-.063-.279-.11-.498-.157-.728l-.028-.14c-.498-2.492-.473-4.516.301-6.275z" fill="#4285F4" fill-rule="nonzero"/><g transform="translate(161.459 2.303)"><mask id="b" fill="#fff"><path id="a" d="M.008.144h30.71v26.652H.007z"/></mask><path d="M.031 21.66c.255-2.568 2.554-4.442 5.135-4.182a4.682 4.682 0 0 1 3.421 2.037 4.695 4.695 0 0 1-.024-1.107c.255-2.568 2.554-4.442 5.13-4.181l.028.003c.964.097 1.783-.638 1.842-1.6.008-.125.02-.251.038-.378.31-2.172 2.166-3.863 4.365-4a4.6 4.6 0 0 1 1.472.143c.975.258 1.933-.483 1.994-1.484l.21-3.452c.163-2.651 3.1-4.178 5.379-2.795 2.277 1.383 2.258 4.683-.036 6.04l-3.811 2.254a1.61 1.61 0 0 0-.644 2.053c.325.718.47 1.527.384 2.366-.256 2.563-2.555 4.436-5.13 4.181l-.03-.003c-.942-.095-1.791.605-1.839 1.546a4.692 4.692 0 0 1-5.151 4.419 4.692 4.692 0 0 1-3.423-2.037c.05.36.064.73.026 1.107-.256 2.563-2.556 4.436-5.135 4.183-2.575-.26-4.457-2.55-4.201-5.113" fill="#4285F4" mask="url(#b)"/></g><path d="M161.475 26.911a6.484 6.484 0 0 1 .733 9.17c-2.341 2.733-6.464 3.06-9.21.73a6.486 6.486 0 0 1-.733-9.17 6.554 6.554 0 0 1 9.21-.73" fill="#FFF"/><path d="M151.653 27.118a7.289 7.289 0 0 0 .823 10.305c3.084 2.618 7.715 2.25 10.344-.82a7.288 7.288 0 0 0-.823-10.305c-3.084-2.617-7.714-2.25-10.344.82zm9.3.406a5.681 5.681 0 0 1 .643 8.034 5.747 5.747 0 0 1-8.076.64 5.683 5.683 0 0 1-.643-8.035 5.748 5.748 0 0 1 7.884-.796l.193.157z" fill="#4285F4" fill-rule="nonzero"/><path d="M163.92 32.616c.85-1.668-2.037-5.655-4.051-6.672-2.014-1.018-6.642-.056-7.493 1.612 1.71 1.768 8.243 4.389 10.677 4.884l.866.176z" fill="#4285F4"/><path d="M150.526 32.93a.806.806 0 0 1 1.043.18l.063.09c.277.454.758.755 1.199.755.442 0 .862-.225 1.05-.542l.05-.098a.806.806 0 0 1 1.485.623c-.418.994-1.478 1.625-2.585 1.625-1.034 0-2.02-.616-2.575-1.529a.803.803 0 0 1 .27-1.104z" fill="#4285F4" fill-rule="nonzero"/><path d="M167.507 66.135a.805.805 0 0 1 .433 1.546l-.106.029-20.582 4.257a.805.805 0 0 1-.432-1.546l.105-.029 20.582-4.257z" fill="#4682F4" fill-rule="nonzero"/><g fill="#4285F4" fill-rule="nonzero"><path d="M95.347 77.103a.806.806 0 0 1 .962-.61.803.803 0 0 1 .609.96c-.48 2.136-1.868 4.347-3.66 5.503l-.812.482c-.59.355-.932.637-1.146.966-.101.156-.136.288-.122.348.017.073.188.191.419.21.282.025.594-.046 1.156-.249l.903-.328c5.416-1.995 8.043-3.418 9.986-5.892.551-.702.944-1.426 1.083-2.05a.806.806 0 0 1 .961-.61.803.803 0 0 1 .61.959c-.199.893-.7 1.818-1.388 2.693-2.248 2.863-5.135 4.386-11.143 6.572l-.469.17c-.768.277-1.258.389-1.84.339-.864-.074-1.65-.615-1.845-1.443-.129-.545.019-1.102.34-1.595.335-.515.773-.902 1.414-1.312l.474-.287.375-.218c1.483-.863 2.725-2.788 3.133-4.608z"/><path d="M83.987 77.326c1.354-2.038 3.087-3.135 6.81-4.776l.392-.172c4.907-2.135 8.03-3.214 11.302-3.63a.803.803 0 1 1 .201 1.596c-3.076.39-6.09 1.432-10.862 3.509l-.714.315c-3.208 1.434-4.7 2.408-5.788 4.047-.354.533-.485 1.327-.337 2.025l.664 3.258c.478 2.406.985 5.058 1.1 5.804l.012.086c.109.792.274 1.145.438 1.154.259.015.718-.6 1.018-1.502.282-.847.3-1.733.109-3.212l-.21-1.433-.089-.5c-.05-.3-.087-.59-.11-.867-.137-1.667.196-2.735.589-3.205.616-.928 1.614-1.338 3.586-1.714l1.785-.313c.724-.13 1.088-.217 1.48-.347a.804.804 0 1 1 .505 1.527l-.233.074c-.464.14-.93.237-1.847.396l-.827.142-.537.098c-1.44.277-2.2.563-2.56 1.01l-.06.081c-.175.213-.379.866-.276 2.117.013.154.03.314.054.48l.143.835.16 1.09c.265 1.893.265 3.047-.135 4.247-.517 1.553-1.354 2.675-2.64 2.602-1.18-.067-1.645-.843-1.877-2.15l-.11-.699c-.251-1.478-1.239-6.519-1.707-8.723-.234-1.107-.032-2.343.57-3.25z"/><path d="M83.462 78.295a.803.803 0 1 1 1.388.814l-1.39 2.38c-1.383 2.392-2.463 4.338-3.33 6.014l-.114.229c-.108.233-.136.355-.118.421.018.067.257.263.373.279.19.026.441-.035.728-.184.611-.317 1.142-.857 1.777-1.744.438-.611.923-1.447 1.451-2.462a.803.803 0 1 1 1.428.74c-.56 1.078-1.077 1.97-1.57 2.658-.77 1.075-1.46 1.776-2.346 2.236-.558.29-1.125.427-1.689.35-.734-.1-1.514-.737-1.707-1.45-.165-.611-.026-1.073.357-1.811l.34-.65c1.108-2.1 2.53-4.606 4.422-7.82z"/></g><path d="M57.963 76.556a1.512 1.512 0 0 1 2.027-.102l.108.098 17.27 17.198 24.354-7.42a1.51 1.51 0 0 1 1.835.866l.049.136a1.51 1.51 0 0 1-.869 1.834l-.137.049-25.22 7.683a1.51 1.51 0 0 1-1.394-.273l-.112-.101-17.91-17.836a1.506 1.506 0 0 1-.001-2.132z" fill="#4285F4" fill-rule="nonzero"/><g><path d="M73.735 27.798a.957.957 0 0 1-.899-1.087 9.21 9.21 0 0 1 9.562-7.95c4.828.22 8.699 4.061 9.082 8.793a.922.922 0 0 1-.96 1.004l-16.785-.76z" fill="#F882FF"/><path d="M46.537 44.15l-7.78 3.522c-1.1.499-1.249 1.981-.268 2.67l6.939 4.87c.98.69 2.354.068 2.473-1.118l.842-8.396c.12-1.187-1.107-2.047-2.206-1.549" fill="#D2E3FC"/><path d="M45.335 46.642c-2.101-2.484-1.676-6.184.948-8.262l11.107-8.82c2.625-2.08 6.456-1.752 8.557.732s1.677 6.184-.948 8.263l-11.106 8.82c-2.625 2.08-6.456 1.75-8.558-.733" fill="#FABD04"/><g transform="rotate(-102 42.988 6.811)"><mask id="d" fill="#fff"><path id="c" d="M3.798.549A5.982 5.982 0 0 0 .812 8.458l5.764 12.741a5.97 5.97 0 0 0 7.9 2.99 5.982 5.982 0 0 0 2.987-7.909L11.697 3.54A5.96 5.96 0 0 0 3.798.55"/></mask><path d="M3.01-6.275c-.34 0-.687.118-.977.375L-4.024-.53c-.856.758-.57 2.16.514 2.523L4.162 4.56c.16.053.32.078.476.078.896 0 1.644-.83 1.45-1.785L4.472-5.084a1.484 1.484 0 0 0-1.461-1.19M2.817-4.19l1.398 6.865-6.638-2.22 5.24-4.645" fill="#FFF" mask="url(#d)"/></g><path d="M43.26 66.655l-3.847-6.7a2.573 2.573 0 0 0-2.228-1.28l-7.868-.026a2.63 2.63 0 0 0-2.261 1.264l-4.022 6.673a2.504 2.504 0 0 0-.032 2.543l3.847 6.7a2.572 2.572 0 0 0 2.228 1.28l7.868.026a2.632 2.632 0 0 0 2.262-1.264l4.02-6.672a2.503 2.503 0 0 0 .033-2.544" fill="#38A953"/><path d="M42.107 102.465h0v-.002a8.461 8.461 0 0 0-1.253-1.538l-1.343-1.65a6.942 6.942 0 0 1-1.515-5.197l.28-2.386.122-1.045-.055-.007a5.94 5.94 0 0 0-.06-.752c-.492-3.26-3.588-5.485-6.915-4.972-3.328.513-5.628 3.571-5.135 6.83.037.252.097.496.165.735l-.05.024.424.96.97 2.194a6.96 6.96 0 0 1 .088 5.417l-.795 1.98a8.491 8.491 0 0 0-.741 1.845l-.001.002h0a8.374 8.374 0 0 0-.038 4.236c1.006 4.032 4.942 6.764 9.169 6.373 5.048-.468 8.615-4.991 7.886-9.824a8.323 8.323 0 0 0-1.203-3.223z" stroke="#D2E3FC" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M40.532 135.356c-7.25-.375-12.761-6.448-12.311-13.564l.013-.21c.449-7.116 6.69-12.581 13.939-12.206 7.25.375 12.761 6.448 12.311 13.564l-.013.21c-.45 7.117-6.69 12.581-13.939 12.206" fill="#EA4335"/><g transform="rotate(-103 70.313 56.882)"><mask id="f" fill="#fff"><path id="e" d="M1.258 10.212c-1.955 7.205 1.886 14.751 8.58 16.855l.196.063c6.694 2.104 13.705-2.03 15.66-9.234C27.65 10.691 23.81 3.145 17.117 1.04L16.92.978a11.78 11.78 0 0 0-3.546-.549C7.907.43 2.868 4.28 1.258 10.212z"/></mask><path d="M28.924.89c-4.53.083-8.37 3.754-8.984 8.531-.727 5.66 3.137 10.797 8.463 11.23a8.667 8.667 0 0 0 3.378-.392l.274-.097.373-.145c.485-.2.925-.425 1.339-.683l.258-.17 1.826-.942a5.58 5.58 0 0 1 4.559-.274l3.188 1.201.11.034c.11.026.223.031.331.016l.02-.004.258.04c.092.013.183.022.275.03 3.737.304 6.968-2.686 7.245-6.64.278-3.947-2.488-7.413-6.216-7.717l-.31-.016h-.227l-.028-.01a.899.899 0 0 0-.324-.035l-.156.024-3.276.663-.275.048c-1.467.221-2.962-.153-4.2-1.061l-1.68-1.235-.225-.203a9.26 9.26 0 0 0-1.183-.869l-.317-.186A8.772 8.772 0 0 0 29.265.889h-.341zm.35 1.81a6.957 6.957 0 0 1 2.96.745l.296.157c.515.29.993.642 1.427 1.049l.083.068 1.714 1.26c1.723 1.265 3.848 1.744 5.905 1.328l3.01-.61.078.011.055.002.056-.001a4.46 4.46 0 0 1 .615.002c2.71.22 4.77 2.8 4.56 5.787-.21 2.979-2.592 5.184-5.294 4.964a4.622 4.622 0 0 1-.611-.097l-.111-.017-.079-.003-2.89-1.09a7.39 7.39 0 0 0-6.029.36l-1.87.968-.095.056a7.217 7.217 0 0 1-1.55.802l-.298.103a6.838 6.838 0 0 1-2.657.304c-4.266-.347-7.413-4.532-6.814-9.196.502-3.911 3.616-6.887 7.222-6.954l.316.001z" fill="#FFF" fill-rule="nonzero" mask="url(#f)"/></g></g><g><g transform="rotate(9 44.073 633.419)"><mask id="h" fill="#fff"><path id="g" d="M0 .13h36.463v36.73H0z"/></mask><path d="M35.644 27.522l-24.76 9.258a1.253 1.253 0 0 1-1.614-.745L.079 11.095a1.268 1.268 0 0 1 .74-1.627L25.58.21c.65-.243 1.372.09 1.614.745l9.191 24.94a1.268 1.268 0 0 1-.74 1.627" fill="#4285F4" mask="url(#h)"/></g><path d="M121.048 11.073a4.033 4.033 0 0 0-1.246.577l-.217.161c-.247.196-.47.42-.664.668l-.548.544a2.164 2.164 0 0 1-1.531.64h-1.374l-.094.007a.686.686 0 0 0-.177.052l-.072.014-.12.03a3.055 3.055 0 0 0-2.149 3.73 3.024 3.024 0 0 0 3.71 2.157l.2-.064.06-.007a.65.65 0 0 0 .13-.042l.178-.099 1.076-.625a2.152 2.152 0 0 1 1.64-.217l.815.22c.218.091.522.173.835.22.667.097 1.35.027 2-.215 1.854-.691 2.95-2.67 2.562-4.618-.461-2.313-2.759-3.742-5.014-3.133zm3.732 3.388c.263 1.322-.485 2.672-1.737 3.139a2.723 2.723 0 0 1-1.965-.019l-.888-.244a3.459 3.459 0 0 0-2.636.35l-1.052.609-.072.024a1.717 1.717 0 0 1-2.31-1.157 1.748 1.748 0 0 1 1.224-2.136l.065-.016c.045-.01.094-.018.15-.025l.069-.016 1.215-.001a3.47 3.47 0 0 0 2.456-1.024l.598-.601.106-.127a3.04 3.04 0 0 1 .4-.388l.16-.117a2.734 2.734 0 0 1 4.217 1.749zm-21.012-1.449a3.139 3.139 0 0 0-2.443 3.69 3.11 3.11 0 0 0 3.669 2.451 3.139 3.139 0 0 0 2.442-3.689 3.111 3.111 0 0 0-3.668-2.452zm2.387 2.706a1.832 1.832 0 0 1-1.422 2.155 1.803 1.803 0 0 1-2.126-1.426 1.833 1.833 0 0 1 1.422-2.155 1.803 1.803 0 0 1 2.09 1.281l.036.145z" fill="#FFF" fill-rule="nonzero"/><g transform="rotate(9 43.883 633.603)"><mask id="j" fill="#fff"><path id="i" d="M25.094.245L.89 9.568c-.687.265-1.037 1.056-.782 1.769l8.985 25.114c.255.712 1.018 1.075 1.704.811L35 27.939c.687-.265 1.037-1.056.782-1.769L26.798 1.056A1.329 1.329 0 0 0 25.555.16c-.153 0-.31.028-.461.086"/></mask><path d="M13.402 18.342a.654.654 0 0 1 .782-.355l.09.035 25.268 11.894a.653.653 0 0 1-.467 1.217l-.09-.035-24.67-11.613-6.724 14.77a.654.654 0 0 1-.775.357l-.09-.033a.653.653 0 0 1-.358-.775l.034-.09 7-15.372z" fill="#FFF" fill-rule="nonzero" mask="url(#j)"/></g></g> + </g> </defs> </svg> </iron-iconset-svg>
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html b/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html index 244af76..a33e9cb 100644 --- a/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html +++ b/chrome/browser/resources/nearby_share/shared/nearby_visibility_page.html
@@ -18,6 +18,10 @@ margin-inline-start: 24px; overflow: hidden; } + + nearby-contact-visibility { + width: 100%; + } </style> <nearby-page-template title="$i18n{nearbyShareVisibilityPageTitle}" sub-title="$i18n{nearbyShareVisibilityPageSubtitle}"
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 29b9d6d3..a781ab8 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -349,6 +349,8 @@ "chromeos/nearby_share_page/nearby_share_subpage.m.js", "chromeos/nearby_share_page/types.m.js", "chromeos/on_startup_page/on_startup_page.m.js", + "chromeos/os_a11y_page/tts_subpage.m.js", + "chromeos/os_a11y_page/tts_subpage_browser_proxy.m.js", "chromeos/os_about_page/channel_switcher_dialog.m.js", "chromeos/os_about_page/detailed_build_info.m.js", "chromeos/os_about_page/device_name_browser_proxy.m.js", @@ -436,6 +438,7 @@ "controls/settings_boolean_control_behavior.m.js", "controls/settings_dropdown_menu.m.js", "controls/settings_radio_group.m.js", + "controls/settings_slider.m.js", "controls/settings_textarea.m.js", "controls/settings_toggle_button.m.js", "extension_control_browser_proxy.m.js",
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn index 61a612c..c404ade 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/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("//chrome/browser/resources/settings/chromeos/os_settings.gni") import("//third_party/closure_compiler/compile_js.gni") js_type_check("closure_compile") { @@ -108,7 +109,7 @@ js_type_check("closure_compile_module") { is_polymer3 = true deps = [ - # ":externs.m", + ":externs.m", # ":manage_a11y_page.m", ":manage_a11y_page_browser_proxy.m", @@ -118,7 +119,7 @@ # ":switch_access_subpage.m", ":switch_access_subpage_browser_proxy.m", - # ":tts_subpage.m" + ":tts_subpage.m", ":tts_subpage_browser_proxy.m", ] } @@ -179,7 +180,19 @@ js_library("tts_subpage.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.m.js" ] deps = [ - # TODO: Fill those in. + ":tts_subpage_browser_proxy.m", + "//chrome/browser/resources/settings:router.m", + "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m", + "//chrome/browser/resources/settings/chromeos:os_route.m", + "//chrome/browser/resources/settings/controls:settings_slider.m", + "//chrome/browser/resources/settings/languages_page:languages_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_button:cr_button.m", + "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button.m", + "//ui/webui/resources/cr_elements/cr_input:cr_input.m", + "//ui/webui/resources/cr_elements/cr_slider:cr_slider.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":tts_subpage_module" ] } @@ -225,6 +238,8 @@ js_file = "tts_subpage.js" html_file = "tts_subpage.html" html_type = "dom-module" + auto_imports = os_settings_auto_imports + namespace_rewrites = os_settings_namespace_rewrites } import("//ui/webui/resources/tools/js_modulizer.gni")
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.html index 44657c4..87532bb5 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage.html
@@ -3,17 +3,17 @@ <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_slider/cr_slider.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/md_select_css.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="../../controls/settings_slider.html"> +<link rel="import" href="../../languages_page/languages_browser_proxy.html"> +<link rel="import" href="../../router.html"> +<link rel="import" href="../../settings_shared_css.html"> <link rel="import" href="../deep_linking_behavior.html"> <link rel="import" href="../os_route.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="../../i18n_setup.html"> -<link rel="import" href="../../languages_page/languages_browser_proxy.html"> -<link rel="import" href="../../settings_shared_css.html"> <link rel="import" href="tts_subpage_browser_proxy.html"> <dom-module id="settings-tts-subpage">
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 199bba6d..b7869bf 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -112,6 +112,7 @@ "chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_account_manager_browser_proxy.html|NearbyAccountManagerBrowserProxy,NearbyAccountManagerBrowserProxyImpl", "chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_manager.html|setReceiveManagerForTesting,getReceiveManager,observeReceiveManager", "chrome/browser/resources/settings/chromeos/nearby_share_page/types.html|NearbyShareDataUsage,dataUsageStringToEnum", + "chrome/browser/resources/settings/chromeos/os_a11y_page/tts_subpage_browser_proxy.html|TtsSubpageBrowserProxy,TtsSubpageBrowserProxyImpl", "chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.html|generateOptions,getFirstPartyInputMethodEngineId,getOptionLabelName,getOptionMenuItems,getOptionUiType,getOptionUrl,hasOptionsPageInSettings,InputToolCode,isNumberValue,OPTION_DEFAULT,OptionType,UiType", "chrome/browser/resources/settings/chromeos/os_languages_page/languages_metrics_proxy.html|LanguagesMetricsProxy, LanguagesMetricsProxyImpl, LanguagesPageInteraction", "chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_browser_proxy.html|FingerprintInfo,FingerprintBrowserProxy,FingerprintResultType,FingerprintBrowserProxyImpl,FingerprintAttempt,FingerprintScan", @@ -151,6 +152,7 @@ "chrome/browser/resources/settings/about_page/about_page_browser_proxy.html|AboutPageBrowserProxyImpl,AboutPageUpdateInfo,AboutPageBrowserProxy,browserChannelToI18nId,VersionInfo,ChannelInfo,BrowserChannel,isTargetChannelMoreStable,UpdateStatus,UpdateStatusChangedEvent,RegulatoryInfo,TPMFirmwareUpdateStatusChangedEvent", "chrome/browser/resources/settings/chromeos/os_about_page/device_name_browser_proxy.html|DeviceNameBrowserProxy,DeviceNameBrowserProxyImpl", "chrome/browser/resources/settings/chromeos/os_settings_page/main_page_behavior.html|MainPageBehavior", + "ui/webui/resources/cr_elements/cr_slider/cr_slider.html|SliderTick", "ui/webui/resources/html/parse_html_subset.html|parseHtmlSubset", ]
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js index 90ba34e..94c54df 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.js +++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -24,6 +24,7 @@ import '../prefs/prefs.m.js'; import './personalization_page/personalization_page.m.js'; import './personalization_page/change_picture.m.js'; +import './os_a11y_page/tts_subpage.m.js'; import './os_people_page/account_manager.m.js'; import './os_people_page/kerberos_accounts.m.js'; import './parental_controls_page/parental_controls_page.m.js'; @@ -58,6 +59,7 @@ export {Account, NearbyAccountManagerBrowserProxy, NearbyAccountManagerBrowserProxyImpl} from './nearby_share_page/nearby_account_manager_browser_proxy.m.js'; export {getReceiveManager, observeReceiveManager, setReceiveManagerForTesting} from './nearby_share_page/nearby_share_receive_manager.m.js'; export {dataUsageStringToEnum, NearbyShareDataUsage} from './nearby_share_page/types.m.js'; +export {TtsSubpageBrowserProxy, TtsSubpageBrowserProxyImpl} from './os_a11y_page/tts_subpage_browser_proxy.m.js'; export {DeviceNameBrowserProxy, DeviceNameBrowserProxyImpl} from './os_about_page/device_name_browser_proxy.m.js'; export {KerberosAccountsBrowserProxyImpl, KerberosConfigErrorCode, KerberosErrorType} from './os_people_page/kerberos_accounts_browser_proxy.m.js'; export {OsSyncBrowserProxyImpl} from './os_people_page/os_sync_browser_proxy.m.js';
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index e41d9d8e..0c3fc53 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -21,6 +21,7 @@ #include "base/time/time.h" #include "base/util/memory_pressure/fake_memory_pressure_monitor.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/defaults.h" #include "chrome/browser/first_run/first_run.h" @@ -1479,10 +1480,11 @@ ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 1); } -#if !defined(OS_CHROMEOS) && !defined(OS_MAC) -// This test doesn't apply to the Mac version; see GetCommandLineForRelaunch +#if !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_LACROS) && \ + !BUILDFLAG(IS_CHROMEOS_ASH) +// This test doesn't apply to Mac or Lacros; see GetCommandLineForRelaunch // for details. It was disabled for a long time so might never have worked on -// ChromeOS. +// Chrome OS Ash. // Launches an app window, closes tabbed browser, launches and makes sure // we restore the tabbed browser url. @@ -1511,7 +1513,8 @@ new_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); } -#endif // !defined(OS_CHROMEOS) && !defined(OS_MAC) +#endif // !!defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_LACROS) && + // !BUILDFLAG(IS_CHROMEOS_ASH) // Creates two windows, closes one, restores, make sure only one window open. IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoWindowsCloseOneRestoreOnlyOne) {
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_api.cc b/chrome/browser/speech/extension_api/tts_engine_extension_api.cc index ebd066b..0013511 100644 --- a/chrome/browser/speech/extension_api/tts_engine_extension_api.cc +++ b/chrome/browser/speech/extension_api/tts_engine_extension_api.cc
@@ -34,6 +34,10 @@ #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" #include "ui/base/l10n/l10n_util.h" +#if defined(OS_CHROMEOS) +#include "chrome/common/extensions/extension_constants.h" +#endif + using extensions::EventRouter; using extensions::Extension; using extensions::ExtensionSystem; @@ -345,6 +349,29 @@ #endif } +bool TtsExtensionEngine::IsBuiltInTtsEngineInitialized( + content::BrowserContext* browser_context) { + if (!browser_context || disable_built_in_tts_engine_for_testing_) + return true; + +#if defined(OS_CHROMEOS) + std::vector<content::VoiceData> voices; + GetVoices(browser_context, &voices); + bool saw_google_tts = false; + bool saw_espeak = false; + for (const auto& voice : voices) { + saw_google_tts |= + voice.engine_id == extension_misc::kGoogleSpeechSynthesisExtensionId; + saw_espeak |= + voice.engine_id == extension_misc::kEspeakSpeechSynthesisExtensionId; + } + return saw_google_tts && saw_espeak; +#else + // Vacuously; no built in engines on other platforms yet. TODO: network tts? + return true; +#endif +} + ExtensionFunction::ResponseAction ExtensionTtsEngineUpdateVoicesFunction::Run() { base::ListValue* voices_data = nullptr;
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_api.h b/chrome/browser/speech/extension_api/tts_engine_extension_api.h index 23f8f83..a124f2f 100644 --- a/chrome/browser/speech/extension_api/tts_engine_extension_api.h +++ b/chrome/browser/speech/extension_api/tts_engine_extension_api.h
@@ -36,6 +36,8 @@ void Pause(content::TtsUtterance* utterance) override; void Resume(content::TtsUtterance* utterance) override; bool LoadBuiltInTtsEngine(content::BrowserContext* browser_context) override; + bool IsBuiltInTtsEngineInitialized( + content::BrowserContext* browser_context) override; void DisableBuiltInTTSEngineForTesting() { disable_built_in_tts_engine_for_testing_ = true;
diff --git a/chrome/browser/speech/extension_api/tts_extension_apitest.cc b/chrome/browser/speech/extension_api/tts_extension_apitest.cc index d7087f9..7f5c1d0 100644 --- a/chrome/browser/speech/extension_api/tts_extension_apitest.cc +++ b/chrome/browser/speech/extension_api/tts_extension_apitest.cc
@@ -259,6 +259,7 @@ content::TtsController* tts_controller = content::TtsController::GetInstance(); tts_controller->SetTtsPlatform(&mock_platform_impl_); + TtsExtensionEngine::GetInstance()->DisableBuiltInTTSEngineForTesting(); tts_controller->SetTtsEngineDelegate(TtsExtensionEngine::GetInstance()); }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index c8bad73..f3c2a97 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -961,6 +961,10 @@ "find_bar/find_bar_platform_helper.h", "focus_tab_after_navigation_helper.cc", "focus_tab_after_navigation_helper.h", + "font_access/font_access_chooser.cc", + "font_access/font_access_chooser.h", + "font_access/font_access_chooser_controller.cc", + "font_access/font_access_chooser_controller.h", "global_error/global_error.cc", "global_error/global_error.h", "global_error/global_error_bubble_view_base.h",
diff --git a/chrome/browser/ui/ash/chrome_capture_mode_delegate.cc b/chrome/browser/ui/ash/chrome_capture_mode_delegate.cc index ba0845b..73d8d6a 100644 --- a/chrome/browser/ui/ash/chrome_capture_mode_delegate.cc +++ b/chrome/browser/ui/ash/chrome_capture_mode_delegate.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/launch_utils.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/platform_util.h" @@ -29,6 +30,8 @@ namespace { +ChromeCaptureModeDelegate* g_instance = nullptr; + ScreenshotArea ConvertToScreenshotArea(const aura::Window* window, const gfx::Rect& bounds) { return window->IsRootWindow() @@ -36,11 +39,39 @@ : ScreenshotArea::CreateForWindow(window); } +bool IsScreenCaptureDisabledByPolicy() { + return g_browser_process->local_state()->GetBoolean( + prefs::kDisableScreenshots); +} + } // namespace -ChromeCaptureModeDelegate::ChromeCaptureModeDelegate() = default; +ChromeCaptureModeDelegate::ChromeCaptureModeDelegate() { + DCHECK_EQ(g_instance, nullptr); + g_instance = this; +} -ChromeCaptureModeDelegate::~ChromeCaptureModeDelegate() = default; +ChromeCaptureModeDelegate::~ChromeCaptureModeDelegate() { + DCHECK_EQ(g_instance, this); + g_instance = nullptr; +} + +// static +ChromeCaptureModeDelegate* ChromeCaptureModeDelegate::Get() { + DCHECK(g_instance); + return g_instance; +} + +void ChromeCaptureModeDelegate::SetIsScreenCaptureLocked(bool locked) { + is_screen_capture_locked_ = locked; + if (is_screen_capture_locked_) + InterruptVideoRecordingIfAny(); +} + +void ChromeCaptureModeDelegate::InterruptVideoRecordingIfAny() { + if (interrupt_video_recording_callback_) + std::move(interrupt_video_recording_callback_).Run(); +} base::FilePath ChromeCaptureModeDelegate::GetActiveUserDownloadsDir() const { DCHECK(chromeos::LoginState::Get()->IsUserLoggedIn()); @@ -86,12 +117,19 @@ } bool ChromeCaptureModeDelegate::IsCaptureModeInitRestricted() const { - return policy::DlpContentManager::Get()->IsCaptureModeInitRestricted(); + return is_screen_capture_locked_ || IsScreenCaptureDisabledByPolicy() || + policy::DlpContentManager::Get()->IsCaptureModeInitRestricted(); } bool ChromeCaptureModeDelegate::IsCaptureAllowed(const aura::Window* window, const gfx::Rect& bounds, bool for_video) const { + if (is_screen_capture_locked_) + return false; + + if (IsScreenCaptureDisabledByPolicy()) + return false; + policy::DlpContentManager* dlp_content_manager = policy::DlpContentManager::Get(); const ScreenshotArea area = ConvertToScreenshotArea(window, bounds); @@ -103,11 +141,16 @@ const aura::Window* window, const gfx::Rect& bounds, base::OnceClosure stop_callback) { + // The order here matters, since DlpContentManager::OnVideoCaptureStarted() + // may call InterruptVideoRecordingIfAny() right away, so the callback must be + // set first. + interrupt_video_recording_callback_ = std::move(stop_callback); policy::DlpContentManager::Get()->OnVideoCaptureStarted( - ConvertToScreenshotArea(window, bounds), std::move(stop_callback)); + ConvertToScreenshotArea(window, bounds)); } void ChromeCaptureModeDelegate::StopObservingRestrictedContent() { + interrupt_video_recording_callback_.Reset(); policy::DlpContentManager::Get()->OnVideoCaptureStopped(); }
diff --git a/chrome/browser/ui/ash/chrome_capture_mode_delegate.h b/chrome/browser/ui/ash/chrome_capture_mode_delegate.h index c725348..c550d6d 100644 --- a/chrome/browser/ui/ash/chrome_capture_mode_delegate.h +++ b/chrome/browser/ui/ash/chrome_capture_mode_delegate.h
@@ -18,6 +18,16 @@ delete; ~ChromeCaptureModeDelegate() override; + static ChromeCaptureModeDelegate* Get(); + + // Sets |is_screen_capture_locked_| to the given |locked|, and interrupts any + // on going video capture. + void SetIsScreenCaptureLocked(bool locked); + + // Interrupts an on going video recording if any, due to some restricted + // content showing up on the screen, or if screen capture becomes locked. + void InterruptVideoRecordingIfAny(); + // ash::CaptureModeDelegate: base::FilePath GetActiveUserDownloadsDir() const override; void ShowScreenCaptureItemInFolder(const base::FilePath& file_path) override; @@ -37,6 +47,19 @@ override; void BindAudioStreamFactory( mojo::PendingReceiver<audio::mojom::StreamFactory> receiver) override; + + private: + // Used to temporarily disable capture mode in certain cases for which neither + // a device policy, nor DLP will be triggered. For example, Some extension + // APIs can request that a tab operate in a locked fullscreen mode, and in + // that, capturing the screen is disabled. + bool is_screen_capture_locked_ = false; + + // A callback to terminate an on going video recording on ash side due to a + // restricted content showing up on the screen, or screen capture becoming + // locked. + // This is only non-null during recording. + base::OnceClosure interrupt_video_recording_callback_; }; #endif // CHROME_BROWSER_UI_ASH_CHROME_CAPTURE_MODE_DELEGATE_H_
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.cc b/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.cc index 2c8f902..56d6efb 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.h" +#include "ash/public/cpp/holding_space/holding_space_color_provider.h" #include "ash/public/cpp/image_downloader.h" #include "base/bind.h" #include "base/callback_helpers.h" @@ -20,6 +21,8 @@ #include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/extensions/api/messaging/native_message_port.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/ash/holding_space/holding_space_util.h" +#include "chromeos/ui/vector_icons/vector_icons.h" #include "extensions/browser/api/messaging/channel_endpoint.h" #include "extensions/browser/api/messaging/message_service.h" #include "extensions/browser/api/messaging/native_message_host.h" @@ -32,6 +35,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image_skia.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/skia_util.h" #include "url/gurl.h" @@ -44,6 +48,9 @@ constexpr char kNativeMessageHostName[] = "com.google.holding_space_thumbnail_loader"; +// The DIP size for the folder icon. +const size_t kFolderIconDipSize = 20; + using ThumbnailDataCallback = base::OnceCallback<void(const std::string& data)>; // Handles a parsed message sent from image loader extension in response to a @@ -189,8 +196,9 @@ HoldingSpaceThumbnailLoader::ThumbnailRequest::ThumbnailRequest( const base::FilePath& item_path, - const gfx::Size& size) - : item_path(item_path), size(size) {} + const gfx::Size& size, + float scale_factor) + : item_path(item_path), size(size), scale_factor(scale_factor) {} HoldingSpaceThumbnailLoader::ThumbnailRequest::~ThumbnailRequest() = default; @@ -223,8 +231,16 @@ return; } + // Short-circuit icons for folders. if (file_info.is_directory) { - std::move(callback).Run(nullptr); + std::move(callback).Run( + holding_space_util::CreatePlaceholderImage( + gfx::CreateVectorIcon( + chromeos::kFiletypeFolderIcon, + request.scale_factor * kFolderIconDipSize, + HoldingSpaceColorProvider::Get()->GetFileIconColor()), + request.size) + .bitmap()); return; }
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.h b/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.h index 3b3c8fd..401d5e7 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.h +++ b/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader.h
@@ -38,7 +38,9 @@ // Thumbnail request data that will be forwarded to the image loader. struct ThumbnailRequest { - ThumbnailRequest(const base::FilePath& item_path, const gfx::Size& size); + ThumbnailRequest(const base::FilePath& item_path, + const gfx::Size& size, + float scale_factor); ~ThumbnailRequest(); // The absolute item file path. @@ -46,6 +48,9 @@ // The desired bitmap size. const gfx::Size size; + + // The scale factor for which the bitmap is being generated. + float scale_factor; }; // Returns a weak pointer to this instance.
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader_browsertest.cc b/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader_browsertest.cc index a30eff2..f357afe 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader_browsertest.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_thumbnail_loader_browsertest.cc
@@ -166,7 +166,8 @@ base::RunLoop run_loop; ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request( - GetTestPath(TestPath::kNonExistent), gfx::Size(48, 48)); + GetTestPath(TestPath::kNonExistent), gfx::Size(48, 48), + /*scale_factor=*/1.0f); loader->Load(request, base::BindLambdaForTesting([&run_loop](const SkBitmap* bitmap) { EXPECT_FALSE(bitmap); @@ -180,14 +181,33 @@ ASSERT_TRUE(loader); base::RunLoop run_loop; + SkBitmap bitmap; ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request( - GetTestPath(TestPath::kEmptyDir), gfx::Size(48, 48)); - loader->Load(request, - base::BindLambdaForTesting([&run_loop](const SkBitmap* bitmap) { - EXPECT_FALSE(bitmap); - run_loop.Quit(); - })); + GetTestPath(TestPath::kEmptyDir), gfx::Size(48, 48), + /*scale_factor=*/1.0f); + loader->Load(request, base::BindOnce(&CopyBitmapAndRunClosure, + run_loop.QuitClosure(), &bitmap)); run_loop.Run(); + EXPECT_FALSE(bitmap.isNull()); + EXPECT_EQ(48, bitmap.width()); + EXPECT_EQ(48, bitmap.height()); +} + +IN_PROC_BROWSER_TEST_F(HoldingSpaceThumbnailLoaderTest, LoadFolderScale2) { + ash::HoldingSpaceThumbnailLoader* loader = GetThumbnailLoader(); + ASSERT_TRUE(loader); + + base::RunLoop run_loop; + SkBitmap bitmap; + ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request( + GetTestPath(TestPath::kEmptyDir), gfx::Size(48, 48), + /*scale_factor=*/2.0f); + loader->Load(request, base::BindOnce(&CopyBitmapAndRunClosure, + run_loop.QuitClosure(), &bitmap)); + run_loop.Run(); + EXPECT_FALSE(bitmap.isNull()); + EXPECT_EQ(48, bitmap.width()); + EXPECT_EQ(48, bitmap.height()); } IN_PROC_BROWSER_TEST_F(HoldingSpaceThumbnailLoaderTest, LoadJpg) { @@ -197,7 +217,7 @@ SkBitmap bitmap; base::RunLoop run_loop; ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request( - GetTestPath(TestPath::kJpg), gfx::Size(48, 48)); + GetTestPath(TestPath::kJpg), gfx::Size(48, 48), /*scale_factor=*/1.0f); loader->Load(request, base::BindOnce(&CopyBitmapAndRunClosure, run_loop.QuitClosure(), &bitmap)); run_loop.Run(); @@ -213,7 +233,8 @@ base::RunLoop run_loop; ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request( - GetTestPath(TestPath::kBrokenJpg), gfx::Size(48, 48)); + GetTestPath(TestPath::kBrokenJpg), gfx::Size(48, 48), + /*scale_factor=*/1.0f); loader->Load(request, base::BindLambdaForTesting([&run_loop](const SkBitmap* bitmap) { EXPECT_FALSE(bitmap); @@ -229,7 +250,7 @@ SkBitmap bitmap; base::RunLoop run_loop; ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request( - GetTestPath(TestPath::kPng), gfx::Size(48, 48)); + GetTestPath(TestPath::kPng), gfx::Size(48, 48), /*scale_factor=*/1.0f); loader->Load(request, base::BindOnce(&CopyBitmapAndRunClosure, run_loop.QuitClosure(), &bitmap)); run_loop.Run(); @@ -243,7 +264,7 @@ ASSERT_TRUE(loader); ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request( - GetTestPath(TestPath::kPng), gfx::Size(48, 48)); + GetTestPath(TestPath::kPng), gfx::Size(48, 48), /*scale_factor=*/1.0f); SkBitmap bitmap1; base::RunLoop run_loop1; @@ -284,14 +305,14 @@ SkBitmap bitmap1; ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request1( - GetTestPath(TestPath::kPng), gfx::Size(48, 48)); + GetTestPath(TestPath::kPng), gfx::Size(48, 48), /*scale_factor=*/1.0f); base::RunLoop run_loop1; loader->Load(request1, base::BindOnce(&CopyBitmapAndRunClosure, run_loop1.QuitClosure(), &bitmap1)); SkBitmap bitmap2; ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request2( - GetTestPath(TestPath::kPng), gfx::Size(96, 96)); + GetTestPath(TestPath::kPng), gfx::Size(96, 96), /*scale_factor=*/2.0f); base::RunLoop run_loop2; loader->Load(request2, base::BindOnce(&CopyBitmapAndRunClosure, run_loop2.QuitClosure(), &bitmap2)); @@ -299,7 +320,7 @@ SkBitmap bitmap3; base::RunLoop run_loop3; ash::HoldingSpaceThumbnailLoader::ThumbnailRequest request3( - GetTestPath(TestPath::kJpg), gfx::Size(48, 48)); + GetTestPath(TestPath::kJpg), gfx::Size(48, 48), /*scale_factor=*/1.0f); loader->Load(request3, base::BindOnce(&CopyBitmapAndRunClosure, run_loop3.QuitClosure(), &bitmap3));
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_util.cc b/chrome/browser/ui/ash/holding_space/holding_space_util.cc index 61f94b4..3ab9fb5 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_util.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_util.cc
@@ -43,14 +43,7 @@ } const SkColor color = HoldingSpaceColorProvider::Get()->GetFileIconColor(); - - // NOTE: We superimpose the file type icon for `file_path` over a transparent - // bitmap in order to center it within the placeholder image at a fixed size. - SkBitmap bitmap; - bitmap.allocN32Pixels(size.width(), size.height()); - return gfx::ImageSkiaOperations::CreateSuperimposedImage( - gfx::ImageSkia::CreateFrom1xBitmap(bitmap), - GetIconForPath(file_path, color)); + return CreatePlaceholderImage(GetIconForPath(file_path, color), size); } } // namespace @@ -190,13 +183,24 @@ base::BindRepeating( [](const base::WeakPtr<HoldingSpaceThumbnailLoader>& thumbnail_loader, const base::FilePath& file_path, const gfx::Size& size, - HoldingSpaceImage::BitmapCallback callback) { + float scale_factor, HoldingSpaceImage::BitmapCallback callback) { if (thumbnail_loader) - thumbnail_loader->Load({file_path, size}, std::move(callback)); + thumbnail_loader->Load({file_path, size, scale_factor}, + std::move(callback)); }, thumbnail_loader->GetWeakPtr(), file_path)); } +gfx::ImageSkia CreatePlaceholderImage(const gfx::ImageSkia& file_type_image, + const gfx::Size& size) { + // NOTE: We superimpose the file type icon for `file_path` over a transparent + // bitmap in order to center it within the placeholder image at a fixed size. + SkBitmap bitmap; + bitmap.allocN32Pixels(size.width(), size.height()); + return gfx::ImageSkiaOperations::CreateSuperimposedImage( + gfx::ImageSkia::CreateFrom1xBitmap(bitmap), file_type_image); +} + void SetNowForTesting(base::Optional<base::Time> now) { now_for_testing = now; }
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_util.h b/chrome/browser/ui/ash/holding_space/holding_space_util.h index 7ed4c75..d64e11f9 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_util.h +++ b/chrome/browser/ui/ash/holding_space/holding_space_util.h
@@ -19,6 +19,11 @@ class FilePath; } // namespace base +namespace gfx { +class ImageSkia; +class Size; +} // namespace gfx + namespace ash { class HoldingSpaceImage; @@ -74,6 +79,11 @@ HoldingSpaceItem::Type type, const base::FilePath& file_path); +// Given a base image for a file type, returns a placeholder image to be used in +// the holding space UI. +gfx::ImageSkia CreatePlaceholderImage(const gfx::ImageSkia& file_type_image, + const gfx::Size& size); + void SetNowForTesting(base::Optional<base::Time> now); } // namespace holding_space_util
diff --git a/chrome/browser/ui/ash/recording_service_browsertest.cc b/chrome/browser/ui/ash/recording_service_browsertest.cc index 72547e8..f2e4b3d 100644 --- a/chrome/browser/ui/ash/recording_service_browsertest.cc +++ b/chrome/browser/ui/ash/recording_service_browsertest.cc
@@ -129,6 +129,12 @@ // To improve the test efficiency, we set the display to a small size. display::test::DisplayManagerTestApi(ash::ShellTestApi().display_manager()) .UpdateDisplay("300x200"); + // To avoid flaky tests, we disable audio recording, since the bots won't + // capture any audio and won't produce any audio frames. This will cause the + // muxer to discard video frames if it expects audio frames but got none, + // which may cause the produced webm file to be empty. See issues + // https://crbug.com/1151167 and https://crbug.com/1151418. + ash::CaptureModeTestApi().SetAudioRecordingEnabled(false); } aura::Window* GetBrowserWindow() const { @@ -207,3 +213,15 @@ test_api.SetUserSelectedRegion(gfx::Rect(50, 200)); FinishVideoRecordingTest(&test_api); } + +// Tests that recording will be interrupted once screen capture becomes locked. +IN_PROC_BROWSER_TEST_F(RecordingServiceBrowserTest, + RecordingInterruptedOnCaptureLocked) { + ash::CaptureModeTestApi test_api; + test_api.StartForFullscreen(/*for_video=*/true); + test_api.PerformCapture(); + WaitForMilliseconds(1000); + ChromeCaptureModeDelegate::Get()->SetIsScreenCaptureLocked(true); + const base::FilePath video_path = WaitForVideoFileToBeSaved(); + VerifyVideoFileAndDelete(video_path); +}
diff --git a/chrome/browser/ui/font_access/OWNERS b/chrome/browser/ui/font_access/OWNERS new file mode 100644 index 0000000..4c791d4 --- /dev/null +++ b/chrome/browser/ui/font_access/OWNERS
@@ -0,0 +1,4 @@ +file://content/browser/font_access/OWNERS + +# TEAM: storage-dev@chromium.org +# COMPONENT: Blink>Storage>FontAccess
diff --git a/chrome/browser/ui/font_access/font_access_chooser.cc b/chrome/browser/ui/font_access/font_access_chooser.cc new file mode 100644 index 0000000..9cf97e3c --- /dev/null +++ b/chrome/browser/ui/font_access/font_access_chooser.cc
@@ -0,0 +1,9 @@ +// 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/ui/font_access/font_access_chooser.h" +#include "content/public/browser/font_access_chooser.h" + +FontAccessChooser::FontAccessChooser(base::OnceClosure close_callback) + : closure_runner_(std::move(close_callback)) {}
diff --git a/chrome/browser/ui/font_access/font_access_chooser.h b/chrome/browser/ui/font_access/font_access_chooser.h new file mode 100644 index 0000000..ecdb6c7 --- /dev/null +++ b/chrome/browser/ui/font_access/font_access_chooser.h
@@ -0,0 +1,20 @@ +// 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_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_H_ +#define CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_H_ + +#include "base/callback_helpers.h" +#include "content/public/browser/font_access_chooser.h" + +class FontAccessChooser : public content::FontAccessChooser { + public: + explicit FontAccessChooser(base::OnceClosure close_callback); + ~FontAccessChooser() override = default; + + private: + base::ScopedClosureRunner closure_runner_; +}; + +#endif // CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_H_
diff --git a/chrome/browser/ui/font_access/font_access_chooser_controller.cc b/chrome/browser/ui/font_access/font_access_chooser_controller.cc new file mode 100644 index 0000000..0a4bedd --- /dev/null +++ b/chrome/browser/ui/font_access/font_access_chooser_controller.cc
@@ -0,0 +1,142 @@ +// 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/ui/font_access/font_access_chooser_controller.h" + +#include "base/strings/utf_string_conversions.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/font_access_chooser.h" +#include "content/public/browser/font_access_context.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/web_contents.h" +#include "third_party/blink/public/mojom/font_access/font_access.mojom-shared.h" +#include "ui/base/l10n/l10n_util.h" + +namespace { + +content::FontAccessContext* GetChooserContext(content::RenderFrameHost* frame) { + return frame->GetStoragePartition()->GetFontAccessContext(); +} + +} // namespace + +FontAccessChooserController::FontAccessChooserController( + content::RenderFrameHost* frame, + content::FontAccessChooser::Callback callback) + : ChooserController(frame, + IDS_FONT_ACCESS_CHOOSER_PROMPT_ORIGIN, + // Extensions are not supported. This is stub text. + IDS_FONT_ACCESS_CHOOSER_PROMPT_ORIGIN), + callback_(std::move(callback)) { + DCHECK(frame); + + content::FontAccessContext* chooser_context = GetChooserContext(frame); + if (chooser_context == nullptr) { + std::move(callback_).Run( + blink::mojom::FontEnumerationStatus::kUnexpectedError, {}); + return; + } + + chooser_context->FindAllFonts( + base::BindOnce(&FontAccessChooserController::DidFindAllFonts, + weak_factory_.GetWeakPtr())); +} + +FontAccessChooserController::~FontAccessChooserController() { + if (callback_) { + std::move(callback_).Run( + blink::mojom::FontEnumerationStatus::kUnexpectedError, {}); + } +} + +base::string16 FontAccessChooserController::GetNoOptionsText() const { + return l10n_util::GetStringUTF16( + IDS_FONT_ACCESS_CHOOSER_NO_FONTS_FOUND_PROMPT); +} + +base::string16 FontAccessChooserController::GetOkButtonLabel() const { + return l10n_util::GetStringUTF16(IDS_FONT_ACCESS_CHOOSER_IMPORT_BUTTON_TEXT); +} + +size_t FontAccessChooserController::NumOptions() const { + return items_.size(); +} + +base::string16 FontAccessChooserController::GetOption(size_t index) const { + DCHECK_LT(index, items_.size()); + DCHECK(base::Contains(font_metadata_map_, items_[index])); + + return base::UTF8ToUTF16(items_[index]); +} + +bool FontAccessChooserController::ShouldShowHelpButton() const { + return false; +} + +bool FontAccessChooserController::ShouldShowReScanButton() const { + return false; +} + +bool FontAccessChooserController::BothButtonsAlwaysEnabled() const { + // Import button is disabled if there isn't at least one selection. + return false; +} + +bool FontAccessChooserController::AllowMultipleSelection() const { + return true; +} + +bool FontAccessChooserController::TableViewAlwaysDisabled() const { + return false; +} + +void FontAccessChooserController::Select(const std::vector<size_t>& indices) { + DCHECK_GT(indices.size(), 0u); + + std::vector<blink::mojom::FontMetadataPtr> fonts; + + for (auto& index : indices) { + DCHECK_LT(index, items_.size()); + auto found = font_metadata_map_.find(items_[index]); + if (found == font_metadata_map_.end()) { + continue; + } + fonts.push_back(found->second.Clone()); + } + + std::move(callback_).Run(blink::mojom::FontEnumerationStatus::kOk, + std::move(fonts)); +} + +void FontAccessChooserController::Cancel() { + std::move(callback_).Run(blink::mojom::FontEnumerationStatus::kCanceled, {}); +} + +void FontAccessChooserController::Close() { + std::move(callback_).Run(blink::mojom::FontEnumerationStatus::kCanceled, {}); +} + +void FontAccessChooserController::OpenHelpCenterUrl() const { + NOTIMPLEMENTED(); +} + +void FontAccessChooserController::DidFindAllFonts( + blink::mojom::FontEnumerationStatus status, + std::vector<blink::mojom::FontMetadata> fonts) { + for (auto& font : fonts) { + auto found = font_metadata_map_.find(font.postscript_name); + // If the font is already in the map, skip it. + if (found != font_metadata_map_.end()) { + continue; + } + items_.push_back(font.postscript_name); + font_metadata_map_[font.postscript_name] = std::move(font); + } + if (view()) + view()->OnOptionsInitialized(); + + if (ready_callback_for_testing_) + std::move(ready_callback_for_testing_).Run(); +}
diff --git a/chrome/browser/ui/font_access/font_access_chooser_controller.h b/chrome/browser/ui/font_access/font_access_chooser_controller.h new file mode 100644 index 0000000..e6e737a --- /dev/null +++ b/chrome/browser/ui/font_access/font_access_chooser_controller.h
@@ -0,0 +1,65 @@ +// 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_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_CONTROLLER_H_ +#define CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_CONTROLLER_H_ + +#include "chrome/browser/chooser_controller/chooser_controller.h" +#include "content/public/browser/font_access_chooser.h" +#include "content/public/browser/render_frame_host.h" +#include "third_party/blink/public/mojom/font_access/font_access.mojom-shared.h" +#include "third_party/blink/public/mojom/font_access/font_access.mojom.h" + +namespace content { + +class RenderFrameHost; + +} // namespace content + +class FontAccessChooserController : public ChooserController { + public: + FontAccessChooserController(content::RenderFrameHost* render_frame_host, + content::FontAccessChooser::Callback callback); + ~FontAccessChooserController() override; + + // Disallow copy and assign. + FontAccessChooserController(FontAccessChooserController&) = delete; + FontAccessChooserController& operator=(FontAccessChooserController&) = delete; + + // ChooserController: + base::string16 GetNoOptionsText() const override; + base::string16 GetOkButtonLabel() const override; + size_t NumOptions() const override; + base::string16 GetOption(size_t index) const override; + + bool ShouldShowHelpButton() const override; + bool ShouldShowReScanButton() const override; + bool BothButtonsAlwaysEnabled() const override; + bool TableViewAlwaysDisabled() const override; + bool AllowMultipleSelection() const override; + + void Select(const std::vector<size_t>& indices) override; + void Cancel() override; + void Close() override; + void OpenHelpCenterUrl() const override; + + void SetReadyCallbackForTesting(base::Callback<void()> callback) { + ready_callback_for_testing_ = callback; + } + + private: + void DidFindAllFonts(blink::mojom::FontEnumerationStatus status, + std::vector<blink::mojom::FontMetadata> fonts); + content::FontAccessChooser::Callback callback_; + base::Callback<void()> ready_callback_for_testing_; + + std::map<std::string, blink::mojom::FontMetadata> font_metadata_map_; + // An ordered list of font names that determines the order of items in the + // chooser. + std::vector<std::string> items_; + + base::WeakPtrFactory<FontAccessChooserController> weak_factory_{this}; +}; + +#endif // CHROME_BROWSER_UI_FONT_ACCESS_FONT_ACCESS_CHOOSER_CONTROLLER_H_
diff --git a/chrome/browser/ui/font_access/font_access_chooser_controller_unittest.cc b/chrome/browser/ui/font_access/font_access_chooser_controller_unittest.cc new file mode 100644 index 0000000..cd63892 --- /dev/null +++ b/chrome/browser/ui/font_access/font_access_chooser_controller_unittest.cc
@@ -0,0 +1,121 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/font_access/font_access_chooser_controller.h" + +#include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/chooser_controller/mock_chooser_controller_view.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" + +class FontAccessChooserControllerTest : public ChromeRenderViewHostTestHarness { + public: + FontAccessChooserControllerTest() { + scoped_feature_list_.InitAndEnableFeature(blink::features::kFontAccess); + } + + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + mock_font_chooser_view_ = std::make_unique<MockChooserControllerView>(); + } + + protected: + std::unique_ptr<MockChooserControllerView> mock_font_chooser_view_; + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(FontAccessChooserControllerTest, MultiSelectTest) { + base::RunLoop run_loop; + FontAccessChooserController controller( + main_rfh(), base::BindLambdaForTesting( + [&](blink::mojom::FontEnumerationStatus status, + std::vector<blink::mojom::FontMetadataPtr> items) { + EXPECT_EQ(status, + blink::mojom::FontEnumerationStatus::kOk); + EXPECT_EQ(items.size(), 2u); + run_loop.Quit(); + })); + + base::RunLoop readiness_loop; + controller.SetReadyCallbackForTesting( + base::BindLambdaForTesting([&]() { readiness_loop.Quit(); })); + readiness_loop.Run(); + + controller.set_view(mock_font_chooser_view_.get()); + EXPECT_GT(controller.NumOptions(), 1u) + << "FontAccessChooserController has more than 2 options"; + controller.Select(std::vector<size_t>({0, 1})); + run_loop.Run(); +} + +TEST_F(FontAccessChooserControllerTest, CancelTest) { + base::RunLoop run_loop; + FontAccessChooserController controller( + main_rfh(), + base::BindLambdaForTesting( + [&](blink::mojom::FontEnumerationStatus status, + std::vector<blink::mojom::FontMetadataPtr> items) { + EXPECT_EQ(status, blink::mojom::FontEnumerationStatus::kCanceled); + EXPECT_EQ(items.size(), 0u); + run_loop.Quit(); + })); + + base::RunLoop readiness_loop; + controller.SetReadyCallbackForTesting( + base::BindLambdaForTesting([&]() { readiness_loop.Quit(); })); + readiness_loop.Run(); + + controller.set_view(mock_font_chooser_view_.get()); + controller.Cancel(); + run_loop.Run(); +} + +TEST_F(FontAccessChooserControllerTest, CloseTest) { + base::RunLoop run_loop; + FontAccessChooserController controller( + main_rfh(), + base::BindLambdaForTesting( + [&](blink::mojom::FontEnumerationStatus status, + std::vector<blink::mojom::FontMetadataPtr> items) { + EXPECT_EQ(status, blink::mojom::FontEnumerationStatus::kCanceled); + EXPECT_EQ(items.size(), 0u); + run_loop.Quit(); + })); + + base::RunLoop readiness_loop; + controller.SetReadyCallbackForTesting( + base::BindLambdaForTesting([&]() { readiness_loop.Quit(); })); + readiness_loop.Run(); + + controller.set_view(mock_font_chooser_view_.get()); + controller.Close(); + run_loop.Run(); +} + +TEST_F(FontAccessChooserControllerTest, DestructorTest) { + base::RunLoop run_loop; + std::unique_ptr<FontAccessChooserController> controller = + std::make_unique<FontAccessChooserController>( + main_rfh(), + base::BindLambdaForTesting( + [&](blink::mojom::FontEnumerationStatus status, + std::vector<blink::mojom::FontMetadataPtr> items) { + EXPECT_EQ( + status, + blink::mojom::FontEnumerationStatus::kUnexpectedError); + EXPECT_EQ(items.size(), 0u); + run_loop.Quit(); + })); + + base::RunLoop readiness_loop; + controller->SetReadyCallbackForTesting( + base::BindLambdaForTesting([&]() { readiness_loop.Quit(); })); + readiness_loop.Run(); + + controller.reset(); + run_loop.Run(); +}
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc index b05bf1b..474a14a 100644 --- a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc
@@ -12,11 +12,11 @@ #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" +#include "base/test/scoped_running_on_chromeos.h" #include "chrome/browser/chromeos/arc/session/arc_session_manager.h" #include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h" #include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h" #include "chrome/browser/chromeos/file_manager/path_util.h" -#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h" #include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h" #include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h" #include "chrome/common/chrome_paths.h" @@ -38,10 +38,6 @@ namespace { -const char kLsbRelease[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; - class TestStorageHandler : public StorageHandler { public: explicit TestStorageHandler(Profile* profile, @@ -104,8 +100,7 @@ // Create and register My files directory. // By emulating chromeos running, GetMyFilesFolderForProfile will return the // profile's temporary location instead of $HOME/Downloads. - chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease, - base::Time()); + base::test::ScopedRunningOnChromeOS running_on_chromeos; const base::FilePath my_files_path = file_manager::util::GetMyFilesFolderForProfile(profile_); CHECK(base::CreateDirectory(my_files_path));
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc index 482213b..677aabf 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -385,7 +385,10 @@ qr_generator_key.emplace(); crypto::RandBytes(*qr_generator_key); qr_string = device::cablev2::qr::Encode(*qr_generator_key); - paired_phones = GetCablePairings(); + + if (!cable_extension_provided) { + paired_phones = GetCablePairings(); + } have_paired_phones = !paired_phones.empty(); mojo::Remote<device::mojom::UsbDeviceManager> usb_device_manager; @@ -396,7 +399,7 @@ SystemNetworkContextManager::GetInstance()->GetContext()); } - if (pairings.empty() && !qr_generator_key) { + if (!cable_extension_provided && !qr_generator_key) { return; } @@ -655,6 +658,10 @@ bool ChromeAuthenticatorRequestDelegate::ShouldPermitCableExtension( const url::Origin& origin) { + if (base::FeatureList::IsEnabled(device::kWebAuthCableExtensionAnywhere)) { + return true; + } + // Because the future of the caBLE extension might be that we transition // everything to QR-code or sync-based pairing, we don't want use of the // extension to spread without consideration. Therefore it's limited to
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index b92205a..c0f6e77 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1605895128-ea3f86e674d4361d5284b25de8910e19181b674b.profdata +chrome-linux-master-1605916713-42186a780bbf4a6606356f169d60384bd3619cf2.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index c1e70c2..f614359 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1605895128-00d55e6bb356ebbc13be21f27095ad3409f51b0e.profdata +chrome-mac-master-1605916713-5c2651f0c6431583f545a63fcbde858a51a7c7b1.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8e1ce21..3fafcf5 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1605873573-36e181f5df5da0c9aa7b43458275355d6ec5a576.profdata +chrome-win32-master-1605905851-758120749a95f1789e143f45329cd7e7ce463c52.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index a222678..146be17 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1605884021-38c8ae5c2e6706d9e606dfe2bcddc4d1100361a4.profdata +chrome-win64-master-1605905851-000df8c5d9233d8cd72a75f96d63436b1fbb2537.profdata
diff --git a/chrome/common/chrome_paths_lacros.cc b/chrome/common/chrome_paths_lacros.cc index bfffdd1..8c177dd 100644 --- a/chrome/common/chrome_paths_lacros.cc +++ b/chrome/common/chrome_paths_lacros.cc
@@ -6,6 +6,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/logging.h" #include "base/system/sys_info.h" #include "chromeos/crosapi/cpp/crosapi_constants.h" @@ -29,23 +30,17 @@ } bool GetUserDocumentsDirectory(base::FilePath* result) { - if (base::SysInfo::IsRunningOnChromeOS()) { - *result = base::FilePath(crosapi::kMyFilesPath); - } else { - // For developers on Linux desktop, just pick a reasonable default. - *result = base::GetHomeDir().Append("Documents"); - } - return true; + // NOTE: Lacros overrides the path with a value from ash early in startup. See + // crosapi::mojom::LacrosInitParams. + LOG(FATAL) << "Path not initialized"; + return false; } bool GetUserDownloadsDirectorySafe(base::FilePath* result) { - if (base::SysInfo::IsRunningOnChromeOS()) { - *result = base::FilePath(crosapi::kDefaultDownloadsPath); - } else { - // For developers on Linux desktop, just pick a reasonable default. - *result = base::GetHomeDir().Append("Downloads"); - } - return true; + // NOTE: Lacros overrides the path with a value from ash early in startup. See + // crosapi::mojom::LacrosInitParams. + LOG(FATAL) << "Path not initialized"; + return false; } bool GetUserDownloadsDirectory(base::FilePath* result) {
diff --git a/chrome/common/chrome_paths_lacros_unittest.cc b/chrome/common/chrome_paths_lacros_unittest.cc index a30f446..f8e2da4 100644 --- a/chrome/common/chrome_paths_lacros_unittest.cc +++ b/chrome/common/chrome_paths_lacros_unittest.cc
@@ -5,32 +5,16 @@ #include "chrome/common/chrome_paths_internal.h" #include "base/files/file_path.h" -#include "base/system/sys_info.h" -#include "base/time/time.h" +#include "base/test/scoped_running_on_chromeos.h" #include "chromeos/crosapi/cpp/crosapi_constants.h" #include "testing/gtest/include/gtest/gtest.h" namespace chrome { namespace { -const char kLsbRelease[] = - "CHROMEOS_RELEASE_NAME=Chrome OS\n" - "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"; - -// Overrides base::SysInfo::IsRunningOnChromeOS() to return true. -class ScopedIsRunningOnChromeOS { - public: - ScopedIsRunningOnChromeOS() { - base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); - } - ~ScopedIsRunningOnChromeOS() { - base::SysInfo::SetChromeOSVersionInfoForTest("", base::Time()); - } -}; - TEST(ChromePaths, UserDataDirectoryIsInsideEncryptedPartition) { // Force paths to behave like they do on device. - ScopedIsRunningOnChromeOS is_running_on_chromeos; + base::test::ScopedRunningOnChromeOS running_on_chromeos; base::FilePath user_data_dir; ASSERT_TRUE(GetDefaultUserDataDirectory(&user_data_dir)); // The Lacros user data directory contains profile information, including
diff --git a/chrome/services/sharing/nearby/BUILD.gn b/chrome/services/sharing/nearby/BUILD.gn index 2f01472..b45f5fc 100644 --- a/chrome/services/sharing/nearby/BUILD.gn +++ b/chrome/services/sharing/nearby/BUILD.gn
@@ -10,6 +10,8 @@ "nearby_connections.h", "nearby_connections_conversions.cc", "nearby_connections_conversions.h", + "nearby_connections_stream_buffer_manager.cc", + "nearby_connections_stream_buffer_manager.h", "platform.cc", ] @@ -29,7 +31,10 @@ source_set("unit_tests") { testonly = true - sources = [ "nearby_connections_unittest.cc" ] + sources = [ + "nearby_connections_stream_buffer_manager_unittest.cc", + "nearby_connections_unittest.cc", + ] deps = [ ":nearby",
diff --git a/chrome/services/sharing/nearby/nearby_connections.cc b/chrome/services/sharing/nearby/nearby_connections.cc index a7f71f1..181cc5b 100644 --- a/chrome/services/sharing/nearby/nearby_connections.cc +++ b/chrome/services/sharing/nearby/nearby_connections.cc
@@ -407,8 +407,8 @@ // Capturing Core* is safe as Core owns PayloadListener. PayloadListener payload_listener = { .payload_cb = - [remote, core = GetCore(service_id)](const std::string& endpoint_id, - Payload payload) { + [&, remote, core = GetCore(service_id)]( + const std::string& endpoint_id, Payload payload) { if (!remote) return; @@ -444,15 +444,16 @@ break; } case Payload::Type::kStream: - // Stream payload is not supported. + buffer_manager_.StartTrackingPayload(std::move(payload)); + break; case Payload::Type::kUnknown: core->CancelPayload(payload.GetId(), /*callback=*/{}); return; } }, .payload_progress_cb = - [remote](const std::string& endpoint_id, - const PayloadProgressInfo& info) { + [&, remote](const std::string& endpoint_id, + const PayloadProgressInfo& info) { if (!remote) return; @@ -463,6 +464,41 @@ mojom::PayloadTransferUpdate::New( info.payload_id, PayloadStatusToMojom(info.status), info.total_bytes, info.bytes_transferred)); + + if (!buffer_manager_.IsTrackingPayload(info.payload_id)) + return; + + switch (info.status) { + case PayloadProgressInfo::Status::kFailure: + FALLTHROUGH; + case PayloadProgressInfo::Status::kCanceled: + buffer_manager_.StopTrackingFailedPayload(info.payload_id); + break; + + case PayloadProgressInfo::Status::kInProgress: + // Note that |info.bytes_transferred| is a cumulative measure of + // bytes that have been sent so far in the payload. + buffer_manager_.HandleBytesTransferred(info.payload_id, + info.bytes_transferred); + break; + + case PayloadProgressInfo::Status::kSuccess: + // When kSuccess is passed, we are guaranteed to have received a + // previous kInProgress update with the same |bytes_transferred| + // value. + // Since we have completed fetching the full payload, return the + // completed payload as a "bytes" payload. + remote->OnPayloadReceived( + endpoint_id, + mojom::Payload::New( + info.payload_id, + mojom::PayloadContent::NewBytes( + mojom::BytesPayload::New(ByteArrayToMojom( + buffer_manager_ + .GetCompletePayloadAndStopTracking( + info.payload_id)))))); + break; + } }}; GetCore(service_id)
diff --git a/chrome/services/sharing/nearby/nearby_connections.h b/chrome/services/sharing/nearby/nearby_connections.h index 3f1b513..68b3255 100644 --- a/chrome/services/sharing/nearby/nearby_connections.h +++ b/chrome/services/sharing/nearby/nearby_connections.h
@@ -19,6 +19,7 @@ #include "base/synchronization/lock.h" #include "base/task/post_task.h" #include "base/thread_annotations.h" +#include "chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager.h" #include "chromeos/services/nearby/public/mojom/nearby_connections.mojom.h" #include "chromeos/services/nearby/public/mojom/webrtc_signaling_messenger.mojom.h" #include "device/bluetooth/public/mojom/adapter.mojom.h" @@ -176,6 +177,10 @@ // ServiceController instance. base::flat_map<std::string, std::unique_ptr<Core>> service_id_to_core_map_; + // Handles incoming stream payloads. This object buffers partial streams as + // they arrive and provides a getter for the final buffer when it is complete. + NearbyConnectionsStreamBufferManager buffer_manager_; + // input_file_map_ is accessed from background threads. base::Lock input_file_lock_; // A map of payload_id to file for InputFile.
diff --git a/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager.cc b/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager.cc new file mode 100644 index 0000000..e4d1746 --- /dev/null +++ b/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager.cc
@@ -0,0 +1,105 @@ +// 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/services/sharing/nearby/nearby_connections_stream_buffer_manager.h" + +#include <utility> + +#include "chrome/browser/nearby_sharing/logging/logging.h" +#include "third_party/nearby/src/cpp/platform/base/exception.h" +#include "third_party/nearby/src/cpp/platform/base/input_stream.h" + +namespace location { +namespace nearby { +namespace connections { + +NearbyConnectionsStreamBufferManager::PayloadWithBuffer::PayloadWithBuffer( + Payload payload) + : payload(std::move(payload)) {} + +NearbyConnectionsStreamBufferManager::NearbyConnectionsStreamBufferManager() = + default; + +NearbyConnectionsStreamBufferManager::~NearbyConnectionsStreamBufferManager() = + default; + +void NearbyConnectionsStreamBufferManager::StartTrackingPayload( + Payload payload) { + int64_t payload_id = payload.GetId(); + NS_LOG(VERBOSE) << "Starting to track stream payload with ID " << payload_id; + + id_to_payload_with_buffer_map_[payload_id] = + std::make_unique<PayloadWithBuffer>(std::move(payload)); +} + +bool NearbyConnectionsStreamBufferManager::IsTrackingPayload( + int64_t payload_id) const { + return base::Contains(id_to_payload_with_buffer_map_, payload_id); +} + +void NearbyConnectionsStreamBufferManager::StopTrackingFailedPayload( + int64_t payload_id) { + id_to_payload_with_buffer_map_.erase(payload_id); + NS_LOG(VERBOSE) << "Stopped tracking payload with ID " << payload_id << " " + << "and cleared internal memory."; +} + +void NearbyConnectionsStreamBufferManager::HandleBytesTransferred( + int64_t payload_id, + int64_t cumulative_bytes_transferred_so_far) { + auto it = id_to_payload_with_buffer_map_.find(payload_id); + if (it == id_to_payload_with_buffer_map_.end()) { + NS_LOG(ERROR) << "Attempted to handle stream bytes for payload with ID " + << payload_id << ", but this payload was not being tracked."; + return; + } + + PayloadWithBuffer* payload_with_buffer = it->second.get(); + + // We only need to read the new bytes which have not already been inserted + // into the buffer. + size_t bytes_to_read = + cumulative_bytes_transferred_so_far - payload_with_buffer->buffer.size(); + + InputStream* stream = payload_with_buffer->payload.AsStream(); + if (!stream) { + NS_LOG(ERROR) << "Payload with ID " << payload_id << " is not a stream " + << "payload; transfer has failed."; + StopTrackingFailedPayload(payload_id); + return; + } + + ExceptionOr<ByteArray> bytes = stream->Read(bytes_to_read); + if (!bytes.ok()) { + NS_LOG(ERROR) << "Payload with ID " << payload_id << " encountered " + << "exception while reading; transfer has failed."; + StopTrackingFailedPayload(payload_id); + return; + } + + payload_with_buffer->buffer += static_cast<std::string>(bytes.result()); +} + +ByteArray +NearbyConnectionsStreamBufferManager::GetCompletePayloadAndStopTracking( + int64_t payload_id) { + auto it = id_to_payload_with_buffer_map_.find(payload_id); + if (it == id_to_payload_with_buffer_map_.end()) { + NS_LOG(ERROR) << "Attempted to get complete payload with ID " << payload_id + << ", but this payload was not being tracked."; + return ByteArray(); + } + + ByteArray complete_payload(it->second->buffer); + + // Close stream and erase internal state before returning payload. + it->second->payload.AsStream()->Close(); + id_to_payload_with_buffer_map_.erase(it); + + return complete_payload; +} + +} // namespace connections +} // namespace nearby +} // namespace location
diff --git a/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager.h b/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager.h new file mode 100644 index 0000000..28bc273 --- /dev/null +++ b/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager.h
@@ -0,0 +1,73 @@ +// 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_SERVICES_SHARING_NEARBY_NEARBY_CONNECTIONS_STREAM_BUFFER_MANAGER_H_ +#define CHROME_SERVICES_SHARING_NEARBY_NEARBY_CONNECTIONS_STREAM_BUFFER_MANAGER_H_ + +#include <memory> +#include <unordered_map> + +#include "third_party/nearby/src/cpp/core/payload.h" +#include "third_party/nearby/src/cpp/platform/base/byte_array.h" + +namespace location { +namespace nearby { +namespace connections { + +// Manages payloads with type "stream" received over Nearby Connections. Streams +// over a certain size are delivered in chunks and need to be reassembled upon +// completion. +// +// Clients should start tracking a payload via StartTrackingPayload(). When +// more bytes have been transferred, clients should invoke +// HandleBytesTransferred(), passing the cumulative number of bytes that have +// been transferred. When all bytes have finished being transferred, clients +// should invoke GetCompletePayloadAndStopTracking() to get the complete, +// reassembled payload. +// +// If a payload has failed or been canceled, clients should invoke +// StopTrackingFailedPayload() so that this class can clean up its internal +// buffer. +class NearbyConnectionsStreamBufferManager { + public: + NearbyConnectionsStreamBufferManager(); + ~NearbyConnectionsStreamBufferManager(); + + // Starts tracking the given payload. + void StartTrackingPayload(Payload payload); + + // Returns whether a payload with the provided ID is being tracked. + bool IsTrackingPayload(int64_t payload_id) const; + + // Stops tracking the payload with the provided ID and cleans up internal + // memory being used to buffer the partially-completed transfer. + void StopTrackingFailedPayload(int64_t payload_id); + + // Processes incoming bytes by reading from the input stream. + void HandleBytesTransferred(int64_t payload_id, + int64_t cumulative_bytes_transferred_so_far); + + // Returns the completed buffer and deletes internal buffers. + ByteArray GetCompletePayloadAndStopTracking(int64_t payload_id); + + private: + struct PayloadWithBuffer { + explicit PayloadWithBuffer(Payload payload); + + Payload payload; + + // Partially-complete buffer which contains the bytes which have been read + // up to this point. + std::string buffer; + }; + + std::unordered_map<int64_t, std::unique_ptr<PayloadWithBuffer>> + id_to_payload_with_buffer_map_; +}; + +} // namespace connections +} // namespace nearby +} // namespace location + +#endif // CHROME_SERVICES_SHARING_NEARBY_NEARBY_CONNECTIONS_STREAM_BUFFER_MANAGER_H_
diff --git a/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager_unittest.cc b/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager_unittest.cc new file mode 100644 index 0000000..b9bcac75 --- /dev/null +++ b/chrome/services/sharing/nearby/nearby_connections_stream_buffer_manager_unittest.cc
@@ -0,0 +1,152 @@ +// 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/services/sharing/nearby/nearby_connections_stream_buffer_manager.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/nearby/src/cpp/core/payload.h" +#include "third_party/nearby/src/cpp/platform/base/byte_array.h" +#include "third_party/nearby/src/cpp/platform/base/exception.h" +#include "third_party/nearby/src/cpp/platform/base/input_stream.h" + +namespace location { +namespace nearby { +namespace connections { +namespace { + +class FakeStream : public InputStream { + public: + FakeStream() = default; + ~FakeStream() override = default; + + ExceptionOr<ByteArray> Read(std::int64_t size) override { + if (should_throw_exception) + return ExceptionOr<ByteArray>(Exception::kIo); + return ExceptionOr<ByteArray>(ByteArray(std::string(size, '\0'))); + } + + Exception Close() override { + if (should_throw_exception) + return {.value = Exception::kIo}; + return {.value = Exception::kSuccess}; + } + + bool should_throw_exception = false; +}; + +} // namespace + +class NearbyConnectionsStreamBufferManagerTest : public testing::Test { + protected: + NearbyConnectionsStreamBufferManagerTest() = default; + ~NearbyConnectionsStreamBufferManagerTest() override = default; + + Payload CreatePayload(int64_t payload_id, FakeStream** fake_stream) { + auto stream = std::make_unique<FakeStream>(); + FakeStream* stream_ptr = stream.get(); + + *fake_stream = stream_ptr; + + Payload payload(payload_id, + [stream_ptr]() -> InputStream& { return *stream_ptr; }); + + fake_streams_.emplace_back(std::move(stream)); + return payload; + } + + NearbyConnectionsStreamBufferManager buffer_manager_; + + private: + std::vector<std::unique_ptr<FakeStream>> fake_streams_; +}; + +TEST_F(NearbyConnectionsStreamBufferManagerTest, Success) { + FakeStream* stream; + Payload payload = CreatePayload(/*payload_id=*/1, &stream); + + buffer_manager_.StartTrackingPayload(std::move(payload)); + EXPECT_TRUE(buffer_manager_.IsTrackingPayload(/*payload_id=*/1)); + + buffer_manager_.HandleBytesTransferred( + /*payload_id=*/1, + /*cumulative_bytes_transferred_so_far=*/1980); + buffer_manager_.HandleBytesTransferred( + /*payload_id=*/1, + /*cumulative_bytes_transferred_so_far=*/2500); + + ByteArray array = + buffer_manager_.GetCompletePayloadAndStopTracking(/*payload_id=*/1); + EXPECT_FALSE(buffer_manager_.IsTrackingPayload(/*payload_id=*/1)); + EXPECT_EQ(2500u, array.size()); +} + +TEST_F(NearbyConnectionsStreamBufferManagerTest, Success_MultipleStreams) { + FakeStream* stream1; + Payload payload1 = CreatePayload(/*payload_id=*/1, &stream1); + + FakeStream* stream2; + Payload payload2 = CreatePayload(/*payload_id=*/2, &stream2); + + buffer_manager_.StartTrackingPayload(std::move(payload1)); + EXPECT_TRUE(buffer_manager_.IsTrackingPayload(/*payload_id=*/1)); + + buffer_manager_.StartTrackingPayload(std::move(payload2)); + EXPECT_TRUE(buffer_manager_.IsTrackingPayload(/*payload_id=*/2)); + + buffer_manager_.HandleBytesTransferred( + /*payload_id=*/1, + /*cumulative_bytes_transferred_so_far=*/1980); + buffer_manager_.HandleBytesTransferred( + /*payload_id=*/2, + /*cumulative_bytes_transferred_so_far=*/1980); + buffer_manager_.HandleBytesTransferred( + /*payload_id=*/1, + /*cumulative_bytes_transferred_so_far=*/2500); + buffer_manager_.HandleBytesTransferred( + /*payload_id=*/2, + /*cumulative_bytes_transferred_so_far=*/3000); + + ByteArray array1 = + buffer_manager_.GetCompletePayloadAndStopTracking(/*payload_id=*/1); + EXPECT_FALSE(buffer_manager_.IsTrackingPayload(/*payload_id=*/1)); + EXPECT_EQ(2500u, array1.size()); + + ByteArray array2 = + buffer_manager_.GetCompletePayloadAndStopTracking(/*payload_id=*/2); + EXPECT_FALSE(buffer_manager_.IsTrackingPayload(/*payload_id=*/2)); + EXPECT_EQ(3000u, array2.size()); +} + +TEST_F(NearbyConnectionsStreamBufferManagerTest, Failure) { + FakeStream* stream; + Payload payload = CreatePayload(/*payload_id=*/1, &stream); + + buffer_manager_.StartTrackingPayload(std::move(payload)); + EXPECT_TRUE(buffer_manager_.IsTrackingPayload(/*payload_id=*/1)); + + buffer_manager_.HandleBytesTransferred( + /*payload_id=*/1, + /*cumulative_bytes_transferred_so_far=*/1980); + buffer_manager_.StopTrackingFailedPayload(/*payload_id=*/1); + EXPECT_FALSE(buffer_manager_.IsTrackingPayload(/*payload_id=*/1)); +} + +TEST_F(NearbyConnectionsStreamBufferManagerTest, Exception) { + FakeStream* stream; + Payload payload = CreatePayload(/*payload_id=*/1, &stream); + + buffer_manager_.StartTrackingPayload(std::move(payload)); + EXPECT_TRUE(buffer_manager_.IsTrackingPayload(/*payload_id=*/1)); + + stream->should_throw_exception = true; + buffer_manager_.HandleBytesTransferred( + /*payload_id=*/1, + /*cumulative_bytes_transferred_so_far=*/1980); + + EXPECT_FALSE(buffer_manager_.IsTrackingPayload(/*payload_id=*/1)); +} + +} // namespace connections +} // namespace nearby +} // namespace location
diff --git a/chrome/services/sharing/nearby/nearby_connections_unittest.cc b/chrome/services/sharing/nearby/nearby_connections_unittest.cc index 6f74d00..3c22d77 100644 --- a/chrome/services/sharing/nearby/nearby_connections_unittest.cc +++ b/chrome/services/sharing/nearby/nearby_connections_unittest.cc
@@ -1304,20 +1304,42 @@ AcceptConnection(fake_payload_listener, endpoint_data.remote_endpoint_id); accepted_run_loop.Run(); + base::RunLoop payload_run_loop; fake_payload_listener.payload_cb = base::BindLambdaForTesting( - [](const std::string& endpoint_id, mojom::PayloadPtr payload) { - NOTREACHED(); + [&](const std::string& endpoint_id, mojom::PayloadPtr payload) { + EXPECT_EQ(endpoint_data.remote_endpoint_id, endpoint_id); + EXPECT_EQ(kPayloadId, payload->id); + ASSERT_TRUE(payload->content->is_bytes()); + EXPECT_EQ(expected_payload, payload->content->get_bytes()->bytes); + payload_run_loop.Quit(); }); - EXPECT_CALL(*service_controller_ptr_, - CancelPayload(testing::_, testing::Eq(kPayloadId))) - .WillOnce(testing::Return(Status{Status::kSuccess})); - + std::string expected_payload_str(expected_payload.begin(), + expected_payload.end()); testing::NiceMock<MockInputStream> input_stream; + EXPECT_CALL(input_stream, Read(_)) + .WillOnce( + Return(ExceptionOr<ByteArray>(ByteArray(expected_payload_str)))); + EXPECT_CALL(input_stream, Close()); + client_proxy->OnPayload( endpoint_data.remote_endpoint_id, Payload(kPayloadId, [&input_stream]() -> InputStream& { return input_stream; })); + client_proxy->OnPayloadProgress( + endpoint_data.remote_endpoint_id, + {.payload_id = kPayloadId, + .status = PayloadProgressInfo::Status::kInProgress, + .total_bytes = expected_payload.size(), + .bytes_transferred = expected_payload.size()}); + client_proxy->OnPayloadProgress( + endpoint_data.remote_endpoint_id, + {.payload_id = kPayloadId, + .status = PayloadProgressInfo::Status::kSuccess, + .total_bytes = expected_payload.size(), + .bytes_transferred = expected_payload.size()}); + + payload_run_loop.Run(); } } // namespace connections
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 23671f6..5956bde 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -989,7 +989,6 @@ "../browser/chrome_cross_origin_opener_policy_browsertest.cc", "../browser/chrome_do_not_track_browsertest.cc", "../browser/chrome_find_request_manager_browsertest.cc", - "../browser/chrome_main_browsertest.cc", "../browser/chrome_navigation_browsertest.cc", "../browser/chrome_origin_trials_browsertest.cc", "../browser/chrome_security_exploit_browsertest.cc", @@ -1271,7 +1270,6 @@ "../browser/previews/previews_test_util.cc", "../browser/previews/previews_test_util.h", "../browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc", - "../browser/process_singleton_browsertest.cc", "../browser/profile_resetter/profile_resetter_browsertest.cc", "../browser/profiles/host_zoom_map_browsertest.cc", "../browser/profiles/profile_activity_metrics_recorder_browsertest.cc", @@ -1611,12 +1609,21 @@ ] } + if (is_linux && !is_chromeos_lacros) { + sources += [ + "../browser/chrome_main_browsertest.cc", + "../browser/process_singleton_browsertest.cc", + ] + } + if (is_chromeos) { sources += [ + "../browser/chrome_main_browsertest.cc", "../browser/chromeos/login/saml/test_client_cert_saml_idp_mixin.cc", "../browser/chromeos/login/saml/test_client_cert_saml_idp_mixin.h", "../browser/chromeos/scoped_test_system_nss_key_slot_mixin.cc", "../browser/chromeos/scoped_test_system_nss_key_slot_mixin.h", + "../browser/process_singleton_browsertest.cc", "../browser/sessions/session_restore_browsertest_chromeos.cc", "../browser/ui/browser_navigator_browsertest_chromeos.cc", "../browser/ui/settings_window_manager_browsertest_chromeos.cc", @@ -1628,8 +1635,10 @@ if (is_win) { sources += [ + "../browser/chrome_main_browsertest.cc", "../browser/importer/edge_importer_browsertest_win.cc", "../browser/importer/ie_importer_browsertest_win.cc", + "../browser/process_singleton_browsertest.cc", "../browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc", "../browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc", "../browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc", @@ -2952,9 +2961,6 @@ # Mac, which does not use hunspell by default. "../browser/spellchecker/spellcheck_service_browsertest.cc", - # ProcessSingletonMac doesn"t do anything. - "../browser/process_singleton_browsertest.cc", - # TaskManagerView is not used or built on Mac. "../browser/ui/views/task_manager_view_browsertest.cc", ] @@ -3087,7 +3093,7 @@ if (enable_extensions && !is_chromeos) { sources += [ "../browser/extensions/api/cloud_print_private/cloud_print_private_apitest.cc" ] } - if (!is_mac && !is_chromeos) { + if (!is_mac && !is_chromeos_ash && !is_chromeos_lacros) { sources += [ # This test depends on GetCommandLineForRelaunch, which is not # available on Mac. It is also not intended to run on ChromeOS. @@ -4551,6 +4557,7 @@ "../browser/ui/extensions/extension_message_bubble_bridge_unittest.cc", "../browser/ui/extensions/extension_settings_overridden_dialog_unittest.cc", "../browser/ui/extensions/settings_overridden_params_providers_unittest.cc", + "../browser/ui/font_access/font_access_chooser_controller_unittest.cc", "../browser/ui/global_error/global_error_service_unittest.cc", "../browser/ui/global_media_controls/cast_media_notification_item_unittest.cc", "../browser/ui/global_media_controls/cast_media_notification_provider_unittest.cc", @@ -4868,10 +4875,10 @@ } } - # TODO(crbug.com/1052397): Rename chromeos_is_browser_only to is_lacros. - if (chromeos_is_browser_only) { + if (is_chromeos_lacros) { assert(enable_native_notifications) sources += [ + "../browser/lacros/lacros_chrome_service_delegate_impl_unittest.cc", "../browser/notifications/notification_platform_bridge_lacros_unittest.cc", "../common/chrome_paths_lacros_unittest.cc", ]
diff --git a/chrome/test/base/chrome_test_suite.cc b/chrome/test/base/chrome_test_suite.cc index f2b9df7..5008ae5 100644 --- a/chrome/test/base/chrome_test_suite.cc +++ b/chrome/test/base/chrome_test_suite.cc
@@ -14,6 +14,7 @@ #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "chrome/app/chrome_main_delegate.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/signin/account_consistency_mode_manager.h" @@ -31,6 +32,11 @@ #include "chromeos/constants/chromeos_paths.h" #endif +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "base/check.h" +#include "base/files/file_util.h" +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + #if defined(OS_MAC) #include "base/mac/bundle_locations.h" #include "base/mac/scoped_nsautorelease_pool.h" @@ -99,6 +105,18 @@ path = path.Append(chrome::kFrameworkName); base::mac::SetOverrideFrameworkBundlePath(path); #endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // The lacros binary receives certain paths from ash very early in startup and + // overrides the path service entries. Simulate that behavior here. See + // chrome_paths_lacros.cc for details. The specific path doesn't matter as + // long as it exists. + CHECK(scoped_temp_dir_.CreateUniqueTempDir()); + base::FilePath temp_path = scoped_temp_dir_.GetPath(); + base::PathService::Override(chrome::DIR_USER_DOCUMENTS, temp_path); + base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS, temp_path); + base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, temp_path); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) } void ChromeTestSuite::Shutdown() {
diff --git a/chrome/test/base/chrome_test_suite.h b/chrome/test/base/chrome_test_suite.h index b2a2e0a8..fcfd82d 100644 --- a/chrome/test/base/chrome_test_suite.h +++ b/chrome/test/base/chrome_test_suite.h
@@ -9,8 +9,13 @@ #include <string> #include "base/files/file_path.h" +#include "build/chromeos_buildflags.h" #include "content/public/test/content_test_suite_base.h" +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "base/files/scoped_temp_dir.h" +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + // Test suite for unit and browser tests. Creates services needed by both. // See also ChromeUnitTestSuite for additional services created for unit tests. class ChromeTestSuite : public content::ContentTestSuiteBase { @@ -31,6 +36,11 @@ // Alternative path to browser binaries. base::FilePath browser_dir_; + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // Used for download and documents path overrides. + base::ScopedTempDir scoped_temp_dir_; +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) }; #endif // CHROME_TEST_BASE_CHROME_TEST_SUITE_H_
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index e2bf63d..281dbd4 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -540,7 +540,7 @@ browser->window()->Show(); } -#if !defined(OS_MAC) +#if !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_LACROS) base::CommandLine InProcessBrowserTest::GetCommandLineForRelaunch() { base::CommandLine new_command_line( base::CommandLine::ForCurrentProcess()->GetProgram()); @@ -561,7 +561,7 @@ } return new_command_line; } -#endif +#endif // !defined(OS_MAC) && !BUILDFLAG(IS_CHROMEOS_LACROS) base::FilePath InProcessBrowserTest::GetChromeTestDataDir() const { return base::FilePath(FILE_PATH_LITERAL("chrome/test/data"));
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h index 1025cad..58aa8ec 100644 --- a/chrome/test/base/in_process_browser_test.h +++ b/chrome/test/base/in_process_browser_test.h
@@ -14,6 +14,7 @@ #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_base.h" #include "testing/gtest/include/gtest/gtest.h" @@ -247,13 +248,14 @@ // the navigation to complete, and show the browser's window. void AddBlankTabAndShow(Browser* browser); -#if !defined OS_MAC +#if !defined OS_MAC && !BUILDFLAG(IS_CHROMEOS_LACROS) // Return a CommandLine object that is used to relaunch the browser_test // binary as a browser process. This function is deliberately not defined on // the Mac because re-using an existing browser process when launching from // the command line isn't a concept that we support on the Mac; AppleEvents // are the Mac solution for the same need. Any test based on these functions - // doesn't apply to the Mac. + // doesn't apply to the Mac. Likewise, Lacros is always launched by ash, and + // not by the the process restarting itself. base::CommandLine GetCommandLineForRelaunch(); #endif
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index c28bd70..e02731d 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -286,6 +286,10 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/bluetooth_page_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cellular_networks_list_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cellular_setup_dialog_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_test_utils.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_entry_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/date_time_page_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/fake_bluetooth_private.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/fake_bluetooth.m.js", @@ -313,6 +317,7 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/network_summary_item_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/network_summary_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/on_startup_page_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_about_page_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_edit_dictionary_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_files_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_languages_page_tests.m.js", @@ -322,13 +327,15 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_printing_page_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_search_page_test.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/smb_shares_page_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/parental_controls_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/people_page_account_manager_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/people_page_change_picture_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/people_page_kerberos_accounts_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/personalization_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/smart_inputs_page_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/smb_shares_page_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_cups_printers_browser_proxy.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_multidevice_browser_proxy.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_languages_browser_proxy.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.m.js", @@ -339,13 +346,7 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/tether_connection_dialog_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/timezone_selector_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/timezone_subpage_test.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_cups_printers_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_test_utils.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_entry_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_about_page_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/tts_subpage_test.m.js", ] } defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js index 86937663..e814cf9e 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js
@@ -19,6 +19,12 @@ let eSimPage; let eSimManagerRemote; + async function flushAsync() { + Polymer.dom.flush(); + // Use setTimeout to wait for the next macrotask. + return new Promise(resolve => setTimeout(resolve)); + } + setup(function() { eSimManagerRemote = new cellular_setup.FakeESimManagerRemote(); cellular_setup.setESimManagerRemoteForTesting(eSimManagerRemote); @@ -30,41 +36,164 @@ Polymer.dom.flush(); }); - test('Forward navigation goes to final page', function() { - const profileDiscoveryPage = eSimPage.$$('#profileDiscoveryPage'); + test('No eSIM profile flow', async function() { + eSimManagerRemote.addEuiccForTest(0); + + const profileLoadingPage = eSimPage.$$('#profileLoadingPage'); + const activationCodePage = eSimPage.$$('#activationCodePage'); const finalPage = eSimPage.$$('#finalPage'); - assertTrue(!!profileDiscoveryPage); + assertTrue(!!profileLoadingPage); + assertTrue(!!activationCodePage); assertTrue(!!finalPage); + // Loading page should be showing. assertTrue( eSimPage.selectedESimPageName_ === - cellular_setup.ESimPageName.PROFILE_DISCOVERY && - eSimPage.selectedESimPageName_ === profileDiscoveryPage.id); + cellular_setup.ESimPageName.PROFILE_LOADING && + eSimPage.selectedESimPageName_ === profileLoadingPage.id); + + await flushAsync(); + + // Should now be at the activation code page. + assertTrue( + eSimPage.selectedESimPageName_ === + cellular_setup.ESimPageName.ACTIVATION_CODE && + eSimPage.selectedESimPageName_ === activationCodePage.id); + // Insert an activation code. + activationCodePage.$$('#activationCode').value = 'ACTIVATION_CODE'; + + // Next button should now be enabled. + assertTrue( + eSimPage.buttonState.next === + cellularSetup.ButtonState.SHOWN_AND_ENABLED); eSimPage.navigateForward(); Polymer.dom.flush(); - // TODO(crbug.com/1093185) Update this test when the navigation between - // profile discovery and activation code pages is wired up. + // Should now be at the final page. assertTrue( eSimPage.selectedESimPageName_ === cellular_setup.ESimPageName.FINAL && eSimPage.selectedESimPageName_ === finalPage.id); }); + test('Single eSIM profile flow', async function() { + eSimManagerRemote.addEuiccForTest(1); - // TODO(crbug.com/1093185) Update this test when the navigation between - // profile discovery and activation code pages is wired up. - test('Enable done button', function() { - assertTrue(eSimPage.buttonState.done === cellularSetup.ButtonState.HIDDEN); + const profileLoadingPage = eSimPage.$$('#profileLoadingPage'); + const finalPage = eSimPage.$$('#finalPage'); + assertTrue(!!profileLoadingPage); + assertTrue(!!finalPage); + + // Loading page should be showing. + assertTrue( + eSimPage.selectedESimPageName_ === + cellular_setup.ESimPageName.PROFILE_LOADING && + eSimPage.selectedESimPageName_ === profileLoadingPage.id); + + await flushAsync(); + + // Should go directly to final page. + assertTrue( + eSimPage.selectedESimPageName_ === cellular_setup.ESimPageName.FINAL && + eSimPage.selectedESimPageName_ === finalPage.id); + }); + + test('Multiple eSIM profiles skip discovery flow', async function() { + eSimManagerRemote.addEuiccForTest(2); + + const profileLoadingPage = eSimPage.$$('#profileLoadingPage'); const profileDiscoveryPage = eSimPage.$$('#profileDiscoveryPage'); + const activationCodePage = eSimPage.$$('#activationCodePage'); + const finalPage = eSimPage.$$('#finalPage'); + + assertTrue(!!profileLoadingPage); + assertTrue(!!profileDiscoveryPage); + assertTrue(!!activationCodePage); + assertTrue(!!finalPage); + + // Loading page should be showing. + assertTrue( + eSimPage.selectedESimPageName_ === + cellular_setup.ESimPageName.PROFILE_LOADING && + eSimPage.selectedESimPageName_ === profileLoadingPage.id); + + await flushAsync(); + + // Should go to profile discovery page. + assertTrue( + eSimPage.selectedESimPageName_ === + cellular_setup.ESimPageName.PROFILE_DISCOVERY && + eSimPage.selectedESimPageName_ === profileDiscoveryPage.id); + + // Simulate pressing 'Skip'. + assertTrue( + eSimPage.buttonState.skipDiscovery === + cellularSetup.ButtonState.SHOWN_AND_ENABLED); + eSimPage.navigateForward(); + Polymer.dom.flush(); + + // Should now be at the activation code page. + assertTrue( + eSimPage.selectedESimPageName_ === + cellular_setup.ESimPageName.ACTIVATION_CODE && + eSimPage.selectedESimPageName_ === activationCodePage.id); + + // Insert an activation code. + activationCodePage.$$('#activationCode').value = 'ACTIVATION_CODE'; + + // Simulate pressing 'Next'. + assertTrue( + eSimPage.buttonState.next === + cellularSetup.ButtonState.SHOWN_AND_ENABLED); + eSimPage.navigateForward(); + Polymer.dom.flush(); + + // Should now be at the final page. + assertTrue( + eSimPage.selectedESimPageName_ === cellular_setup.ESimPageName.FINAL && + eSimPage.selectedESimPageName_ === finalPage.id); + }); + + test('Multiple eSIM profiles select flow', async function() { + eSimManagerRemote.addEuiccForTest(2); + + const profileLoadingPage = eSimPage.$$('#profileLoadingPage'); + const profileDiscoveryPage = eSimPage.$$('#profileDiscoveryPage'); + const activationCodePage = eSimPage.$$('#activationCodePage'); + const finalPage = eSimPage.$$('#finalPage'); + + assertTrue(!!profileLoadingPage); + assertTrue(!!profileDiscoveryPage); + assertTrue(!!activationCodePage); + assertTrue(!!finalPage); + + // Loading page should be showing. + assertTrue( + eSimPage.selectedESimPageName_ === + cellular_setup.ESimPageName.PROFILE_LOADING && + eSimPage.selectedESimPageName_ === profileLoadingPage.id); + + await flushAsync(); + + // Should go to profile discovery page. + assertTrue( + eSimPage.selectedESimPageName_ === + cellular_setup.ESimPageName.PROFILE_DISCOVERY && + eSimPage.selectedESimPageName_ === profileDiscoveryPage.id); + + // Select the first profile on the list. const profileList = profileDiscoveryPage.$$('#profileList'); profileList.selectItem(profileList.items[0]); Polymer.dom.flush(); + // The 'Done' button should now be enabled. assertTrue( eSimPage.buttonState.done === cellularSetup.ButtonState.SHOWN_AND_ENABLED); + assertTrue( + eSimPage.buttonState.skipDiscovery === + cellularSetup.ButtonState.HIDDEN); }); });
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js index 51bb309..c10fe5d 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js +++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_esim_manager_remote.js
@@ -4,43 +4,98 @@ cr.define('cellular_setup', function() { - /** @implements {chromeos.cellularSetup.mojom.ESimManagerInterface} */ - /* #export */ class FakeESimManagerRemote { + /** @implements {chromeos.cellularSetup.mojom.ESimProfile} */ + class FakeProfile { + constructor(id) { + this.properties_ = { + activationCode: 'activation-code-' + id, + eid: '1', + iccid: id, + name: 'profile' + id, + nickname: 'profile' + id, + serviceProvider: 'provider' + id, + state: chromeos.cellularSetup.mojom.ProfileState.kPending, + }; + } + /** * @override - * @return {!Promise<{euiccs: !Array<!Euicc>,}>} + * @return {!Promise<{properties: + * chromeos.cellularSetup.mojom.ESimProfileProperties},}>} */ - getAvailableEuiccs() { + getProperties() { return new Promise((res) => { res({ - euiccs: [{ - eid: '1', - isActive: true, - }] + properties: this.properties_, + }); + }); + } + } + + /** @implements {chromeos.cellularSetup.mojom.Euicc} */ + class FakeEuicc { + constructor(numProfiles) { + this.profiles_ = []; + for (let i = 0; i < numProfiles; i++) { + this.addProfileForTest_(); + } + } + + /** + * @override + * @return {!Promise<{result: + * chromeos.cellularSetup.mojom.ESimOperationResult},}>} + */ + requestPendingProfiles() { + return new Promise((res) => { + res({ + result: chromeos.cellularSetup.mojom.ESimOperationResult.kSuccess }); }); } /** * @override - * @param { !string } eid * @return {!Promise<{profiles: Array<!ESimProfile>,}>} */ - getProfiles(eid) { + getProfileList() { return new Promise((res) => { res({ - profiles: [{ - activationCode: 'activation-code-1', - eid: '1', - iccid: '1', - name: 'profile1', - nickname: 'profile1', - serviceProvider: 'provider1', - state: chromeos.cellularSetup.mojom.ProfileState.kPending, - }] + profiles: this.profiles_, }); }); } + + /** @private */ + addProfileForTest_() { + const id = this.profiles_.length + 1; + this.profiles_.push(new FakeProfile(id)); + } + } + + /** @implements {chromeos.cellularSetup.mojom.ESimManagerInterface} */ + /* #export */ class FakeESimManagerRemote { + constructor() { + this.euiccs_ = []; + } + + /** + * @override + * @return {!Promise<{euiccs: !Array<!Euicc>,}>} + */ + getAvailableEuiccs() { + return new Promise((res) => { + res({euiccs: this.euiccs_}); + }); + } + + /** + * @param {number} numProfiles The number of profiles the EUICC has. + */ + addEuiccForTest(numProfiles) { + const euicc = new FakeEuicc(numProfiles); + this.euiccs_.push(euicc); + } } // #cr_define_end
diff --git a/chrome/test/data/webui/nearby_share/shared/nearby_contact_visibility_test.js b/chrome/test/data/webui/nearby_share/shared/nearby_contact_visibility_test.js index 7e63a64..b8da5b6c 100644 --- a/chrome/test/data/webui/nearby_share/shared/nearby_contact_visibility_test.js +++ b/chrome/test/data/webui/nearby_share/shared/nearby_contact_visibility_test.js
@@ -132,8 +132,9 @@ assertFalse(isDownloadContactsFailedVisible()); assertFalse(isDownloadContactsPendingVisible()); assertTrue(areContactCheckBoxesVisible()); - const list = visibilityElement.$$('#contactList'); - assertEquals(fakeContactManager.contactRecords.length, list.items.length); + const items = + visibilityElement.$$('#contactList').querySelectorAll('.contact-item'); + assertEquals(fakeContactManager.contactRecords.length, items.length); }); test('Radio group disabled until successful download', async function() {
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 843a6874..92296db 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -35,6 +35,10 @@ "bluetooth_page_tests.js", "cellular_networks_list_test.js", "cellular_setup_dialog_test.js", + "cups_printer_entry_tests.js", + "cups_printer_landing_page_tests.js", + "cups_printer_page_tests.js", + "cups_printer_test_utils.js", "date_time_page_tests.js", "fake_bluetooth.js", "fake_bluetooth_private.js", @@ -64,7 +68,9 @@ "network_summary_test.js", "network_summary_item_test.js", "on_startup_page_tests.js", + "os_about_page_tests.js", "os_edit_dictionary_page_test.js", + "os_files_page_test.js", "os_languages_page_tests.js", "os_languages_page_v2_tests.js", "os_reset_page_test.js", @@ -72,33 +78,28 @@ "os_people_page_test.js", "os_privacy_page_test.js", "os_search_page_test.js", - "smb_shares_page_tests.js", - "os_files_page_test.js", "parental_controls_page_test.js", "people_page_account_manager_test.js", "people_page_change_picture_test.js", "people_page_kerberos_accounts_test.js", "personalization_page_test.js", "smart_inputs_page_test.js", + "smb_shares_page_tests.js", + "test_about_page_browser_proxy_chromeos.js", + "test_cups_printers_browser_proxy.js", "test_device_name_browser_proxy.js", + "test_multidevice_browser_proxy.js", "test_os_languages_browser_proxy.js", "test_os_languages_metrics_proxy.js", "test_os_lifetime_browser_proxy.js", - "test_multidevice_browser_proxy.js", "test_os_reset_browser_proxy.js", - "test_wallpaper_browser_proxy.js", "test_os_sync_browser_proxy.js", + "test_wallpaper_browser_proxy.js", "tether_connection_dialog_test.js", "timezone_selector_test.js", "timezone_subpage_test.js", - "test_cups_printers_browser_proxy.js", + "tts_subpage_test.js", "user_page_tests.js", - "cups_printer_page_tests.js", - "cups_printer_test_utils.js", - "cups_printer_landing_page_tests.js", - "cups_printer_entry_tests.js", - "os_about_page_tests.js", - "test_about_page_browser_proxy_chromeos.js", ] namespace_rewrites = os_settings_namespace_rewrites + os_test_namespace_rewrites + [
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 2bd91b1..b1b7ae2 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -2208,4 +2208,27 @@ mocha.run(); }); +// Test fixture for the TTS Subpage. +// eslint-disable-next-line no-var +var OSSettingsTtsSubpageTest = class extends OSSettingsBrowserTest { + /** @override */ + get browsePreload() { + return super.browsePreload + + 'chromeos/os_a11y_page/tts_subpage.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', + BROWSER_SETTINGS_PATH + '../test_util.js', + 'tts_subpage_test.js', + ]); + } +}; + +TEST_F('OSSettingsTtsSubpageTest', 'AllJsTests', () => { + mocha.run(); +}); + GEN('#endif // defined(NDEBUG)');
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index 09d5deb..34e35fb 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -96,11 +96,16 @@ TEST_F('OSSettingsNearbyShareSubPageV3Test', 'All', () => mocha.run()); -[['AmbientModePage', 'ambient_mode_page_test.m.js'], +[['AboutPage', 'os_about_page_tests.m.js'], + ['AmbientModePage', 'ambient_mode_page_test.m.js'], ['BluetoothPage', 'bluetooth_page_tests.m.js'], ['CellularNetworksList', 'cellular_networks_list_test.m.js'], ['CellularSetupDialog', 'cellular_setup_dialog_test.m.js'], + ['CupsPrinterEntry', 'cups_printer_entry_tests.m.js'], + ['CupsPrinterLandingPage', 'cups_printer_landing_page_tests.m.js'], + ['CupsPrinterPage', 'cups_printer_page_tests.m.js'], ['DateTimePage', 'date_time_page_tests.m.js'], + ['FilesPage', 'os_files_page_test.m.js'], ['GoogleAssistantPage', 'google_assistant_page_test.m.js'], ['InputMethodOptionPage', 'input_method_options_page_test.m.js'], ['InputPage', 'input_page_test.m.js'], @@ -135,17 +140,13 @@ ['PersonalizationPage', 'personalization_page_test.m.js'], ['PrintingPage', 'os_printing_page_tests.m.js'], ['PrivacyPage', 'os_privacy_page_test.m.js'], - ['SmbPage', 'smb_shares_page_tests.m.js'], - ['FilesPage', 'os_files_page_test.m.js'], ['ResetPage', 'os_reset_page_test.m.js'], ['SmartInputsPage', 'smart_inputs_page_test.m.js'], + ['SmbPage', 'smb_shares_page_tests.m.js'], ['TetherConnectionDialog', 'tether_connection_dialog_test.m.js'], ['TimezoneSelector', 'timezone_selector_test.m.js'], ['TimezoneSubpage', 'timezone_subpage_test.m.js'], - ['CupsPrinterPage', 'cups_printer_page_tests.m.js'], - ['CupsPrinterLandingPage', 'cups_printer_landing_page_tests.m.js'], - ['CupsPrinterEntry', 'cups_printer_entry_tests.m.js'], - ['AboutPage', 'os_about_page_tests.m.js'], + ['TtsSubpage', 'tts_subpage_test.m.js'], ].forEach(test => registerTest(...test)); function registerTest(testName, module, caseName) {
diff --git a/chrome/test/data/webui/settings/chromeos/tts_subpage_test.js b/chrome/test/data/webui/settings/chromeos/tts_subpage_test.js new file mode 100644 index 0000000..0ff4b34 --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/tts_subpage_test.js
@@ -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. + +// clang-format off +// #import 'chrome://os-settings/chromeos/os_settings.js'; + +// #import {assertTrue, assertEquals} from '../../chai_assert.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// clang-format on + +suite('TtsSubpage', function() { + /** @type {!TtsSubpageElement|undefined} */ + let ttsSubpage; + + setup(function() { + ttsSubpage = document.createElement('settings-tts-subpage'); + document.body.appendChild(ttsSubpage); + Polymer.dom.flush(); + }); + + test('Preview Voice Select Options', function() { + ttsSubpage.prefs = { + settings: { + 'language': { + 'preferred_languages': { + value: '', + }, + }, + 'tts': { + 'lang_to_voice_name': { + value: '', + }, + }, + }, + }; + + ttsSubpage.set('allVoices', [ + {id: "A", displayLanguage: "Klingon", name: "Star Trek"}, + {id: "B", displayLanguage: "Goa'uld", name: "Star Gate"}, + {id: "C", displayLanguage: "Dothraki", name: "Game of Thrones"}, + ]); + Polymer.dom.flush(); + + const previewVoice = ttsSubpage.$.previewVoice; + assertTrue(!!previewVoice); + assertEquals(3, previewVoice.length); + + // Check one of the language option details. + const secondVoice = ttsSubpage.$$('option[value=B]'); + assertTrue(!!secondVoice); + assertEquals("Goa'uld - Star Gate", String(secondVoice.textContent).trim()); + }); +});
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index cebda78..a9bbeef 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -39,7 +39,6 @@ "action_handler.h", "constants.cc", "constants.h", - "control_service.h", "crash_client.cc", "crash_client.h", "crash_reporter.cc", @@ -59,6 +58,7 @@ "unzipper.h", "update_service.cc", "update_service.h", + "update_service_internal.h", "util.cc", "util.h", ] @@ -95,10 +95,6 @@ "app/app_wake.h", "configurator.cc", "configurator.h", - "control_service_impl.cc", - "control_service_impl.h", - "control_service_impl_inactive.cc", - "control_service_impl_inactive.h", "crx_downloader_factory.h", "external_constants.cc", "external_constants.h", @@ -118,6 +114,10 @@ "update_service_impl.h", "update_service_impl_inactive.cc", "update_service_impl_inactive.h", + "update_service_internal_impl.cc", + "update_service_internal_impl.h", + "update_service_internal_impl_inactive.cc", + "update_service_internal_impl_inactive.h", "updater.cc", "updater.h", ] @@ -138,8 +138,8 @@ "launchd_util.cc", "launchd_util.h", "lib_util_mac.mm", - "mac/control_service_proxy.h", - "mac/control_service_proxy.mm", + "mac/update_service_internal_proxy.h", + "mac/update_service_internal_proxy.mm", "mac/update_service_proxy.h", "mac/update_service_proxy.mm", "prefs_mac.mm",
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc index 8167ab6..4938e63 100644 --- a/chrome/updater/app/app_install.cc +++ b/chrome/updater/app/app_install.cc
@@ -19,13 +19,13 @@ #include "base/version.h" #include "build/build_config.h" #include "chrome/updater/constants.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/persisted_data.h" #include "chrome/updater/prefs.h" #include "chrome/updater/registration_data.h" #include "chrome/updater/setup.h" #include "chrome/updater/tag.h" #include "chrome/updater/update_service.h" +#include "chrome/updater/update_service_internal.h" #include "chrome/updater/updater_version.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/updater/app/app_server.cc b/chrome/updater/app/app_server.cc index 9a966e1..6f0d56f 100644 --- a/chrome/updater/app/app_server.cc +++ b/chrome/updater/app/app_server.cc
@@ -12,14 +12,14 @@ #include "base/version.h" #include "chrome/updater/configurator.h" #include "chrome/updater/constants.h" -#include "chrome/updater/control_service.h" -#include "chrome/updater/control_service_impl.h" -#include "chrome/updater/control_service_impl_inactive.h" #include "chrome/updater/persisted_data.h" #include "chrome/updater/prefs.h" #include "chrome/updater/update_service.h" #include "chrome/updater/update_service_impl.h" #include "chrome/updater/update_service_impl_inactive.h" +#include "chrome/updater/update_service_internal.h" +#include "chrome/updater/update_service_internal_impl.h" +#include "chrome/updater/update_service_internal_impl_inactive.h" #include "chrome/updater/updater_version.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/updater/app/app_server_unittest.cc b/chrome/updater/app/app_server_unittest.cc index 44cec2b..87b6ecb 100644 --- a/chrome/updater/app/app_server_unittest.cc +++ b/chrome/updater/app/app_server_unittest.cc
@@ -13,9 +13,9 @@ #include "base/task/single_thread_task_executor.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "chrome/updater/constants.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/prefs.h" #include "chrome/updater/update_service.h" +#include "chrome/updater/update_service_internal.h" #include "chrome/updater/updater_version.h" #include "chrome/updater/util.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/updater/app/app_wake.cc b/chrome/updater/app/app_wake.cc index de8441c..5f9a0f8 100644 --- a/chrome/updater/app/app_wake.cc +++ b/chrome/updater/app/app_wake.cc
@@ -7,7 +7,7 @@ #include "base/bind.h" #include "build/build_config.h" #include "chrome/updater/app/app.h" -#include "chrome/updater/control_service.h" +#include "chrome/updater/update_service_internal.h" namespace updater {
diff --git a/chrome/updater/app/server/mac/server.mm b/chrome/updater/app/server/mac/server.mm index b1bf26283..3e19a83 100644 --- a/chrome/updater/app/server/mac/server.mm +++ b/chrome/updater/app/server/mac/server.mm
@@ -21,11 +21,11 @@ #include "chrome/updater/app/server/mac/service_delegate.h" #include "chrome/updater/configurator.h" #include "chrome/updater/constants.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/mac/setup/setup.h" #import "chrome/updater/mac/xpc_service_names.h" #include "chrome/updater/prefs.h" #include "chrome/updater/update_service.h" +#include "chrome/updater/update_service_internal.h" namespace updater {
diff --git a/chrome/updater/app/server/mac/service_delegate.mm b/chrome/updater/app/server/mac/service_delegate.mm index a910787..50d395c 100644 --- a/chrome/updater/app/server/mac/service_delegate.mm +++ b/chrome/updater/app/server/mac/service_delegate.mm
@@ -21,10 +21,10 @@ #import "chrome/updater/app/server/mac/server.h" #import "chrome/updater/app/server/mac/service_protocol.h" #import "chrome/updater/app/server/mac/update_service_wrappers.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/mac/setup/setup.h" #import "chrome/updater/mac/xpc_service_names.h" #include "chrome/updater/update_service.h" +#include "chrome/updater/update_service_internal.h" #include "chrome/updater/updater_version.h" @interface CRUUpdateCheckServiceXPCImpl : NSObject <CRUUpdateChecking>
diff --git a/chrome/updater/app/server/win/server.cc b/chrome/updater/app/server/win/server.cc index 48b0392..e9f2307f 100644 --- a/chrome/updater/app/server/win/server.cc +++ b/chrome/updater/app/server/win/server.cc
@@ -20,9 +20,9 @@ #include "chrome/updater/app/server/win/com_classes.h" #include "chrome/updater/app/server/win/com_classes_legacy.h" #include "chrome/updater/configurator.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/prefs.h" #include "chrome/updater/update_service.h" +#include "chrome/updater/update_service_internal.h" #include "chrome/updater/win/constants.h" #include "chrome/updater/win/setup/uninstall.h" #include "chrome/updater/win/wrl_module.h"
diff --git a/chrome/updater/app/server/win/server.h b/chrome/updater/app/server/win/server.h index ebc4223..2ca157f 100644 --- a/chrome/updater/app/server/win/server.h +++ b/chrome/updater/app/server/win/server.h
@@ -14,8 +14,8 @@ #include "base/win/scoped_com_initializer.h" #include "chrome/updater/app/app.h" #include "chrome/updater/app/app_server.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/update_service.h" +#include "chrome/updater/update_service_internal.h" namespace updater {
diff --git a/chrome/updater/mac/control_service_proxy.h b/chrome/updater/mac/update_service_internal_proxy.h similarity index 83% rename from chrome/updater/mac/control_service_proxy.h rename to chrome/updater/mac/update_service_internal_proxy.h index e4af0be..64f83de 100644 --- a/chrome/updater/mac/control_service_proxy.h +++ b/chrome/updater/mac/update_service_internal_proxy.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_UPDATER_MAC_CONTROL_SERVICE_PROXY_H_ -#define CHROME_UPDATER_MAC_CONTROL_SERVICE_PROXY_H_ +#ifndef CHROME_UPDATER_MAC_UPDATE_SERVICE_INTERNAL_PROXY_H_ +#define CHROME_UPDATER_MAC_UPDATE_SERVICE_INTERNAL_PROXY_H_ #import <Foundation/Foundation.h> @@ -11,8 +11,8 @@ #include "base/mac/scoped_nsobject.h" #include "base/memory/scoped_refptr.h" #include "base/sequence_checker.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/service_scope.h" +#include "chrome/updater/update_service_internal.h" @class CRUUpdateServiceInternalProxyImpl; @@ -43,4 +43,4 @@ } // namespace updater -#endif // CHROME_UPDATER_MAC_CONTROL_SERVICE_PROXY_H_ +#endif // CHROME_UPDATER_MAC_UPDATE_SERVICE_INTERNAL_PROXY_H_
diff --git a/chrome/updater/mac/control_service_proxy.mm b/chrome/updater/mac/update_service_internal_proxy.mm similarity index 98% rename from chrome/updater/mac/control_service_proxy.mm rename to chrome/updater/mac/update_service_internal_proxy.mm index 7d88008..0e6d56d 100644 --- a/chrome/updater/mac/control_service_proxy.mm +++ b/chrome/updater/mac/update_service_internal_proxy.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/updater/mac/control_service_proxy.h" +#include "chrome/updater/mac/update_service_internal_proxy.h" #import <Foundation/Foundation.h>
diff --git a/chrome/updater/service_factory_mac.mm b/chrome/updater/service_factory_mac.mm index d63c482..9d93207 100644 --- a/chrome/updater/service_factory_mac.mm +++ b/chrome/updater/service_factory_mac.mm
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "base/memory/ref_counted.h" -#include "chrome/updater/mac/control_service_proxy.h" +#include "chrome/updater/mac/update_service_internal_proxy.h" #include "chrome/updater/mac/update_service_proxy.h" #include "chrome/updater/service_scope.h"
diff --git a/chrome/updater/service_factory_win.cc b/chrome/updater/service_factory_win.cc index 96730f5c..5e214f1 100644 --- a/chrome/updater/service_factory_win.cc +++ b/chrome/updater/service_factory_win.cc
@@ -6,7 +6,7 @@ #include "base/memory/ref_counted.h" #include "base/no_destructor.h" #include "chrome/updater/service_scope.h" -#include "chrome/updater/win/control_service_proxy.h" +#include "chrome/updater/win/update_service_internal_proxy.h" #include "chrome/updater/win/update_service_proxy.h" #include "chrome/updater/win/wrl_module.h"
diff --git a/chrome/updater/control_service.h b/chrome/updater/update_service_internal.h similarity index 91% rename from chrome/updater/control_service.h rename to chrome/updater/update_service_internal.h index 0882d02..dbdb6b9 100644 --- a/chrome/updater/control_service.h +++ b/chrome/updater/update_service_internal.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_UPDATER_CONTROL_SERVICE_H_ -#define CHROME_UPDATER_CONTROL_SERVICE_H_ +#ifndef CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_H_ +#define CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_H_ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" @@ -43,4 +43,4 @@ } // namespace updater -#endif // CHROME_UPDATER_CONTROL_SERVICE_H_ +#endif // CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_H_
diff --git a/chrome/updater/control_service_impl.cc b/chrome/updater/update_service_internal_impl.cc similarity index 98% rename from chrome/updater/control_service_impl.cc rename to chrome/updater/update_service_internal_impl.cc index 0ddfaf3..6742d22 100644 --- a/chrome/updater/control_service_impl.cc +++ b/chrome/updater/update_service_internal_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/updater/control_service_impl.h" +#include "chrome/updater/update_service_internal_impl.h" #include <string> #include <vector>
diff --git a/chrome/updater/control_service_impl.h b/chrome/updater/update_service_internal_impl.h similarity index 93% rename from chrome/updater/control_service_impl.h rename to chrome/updater/update_service_internal_impl.h index d9bd605..aaa3f377 100644 --- a/chrome/updater/control_service_impl.h +++ b/chrome/updater/update_service_internal_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_UPDATER_CONTROL_SERVICE_IMPL_H_ -#define CHROME_UPDATER_CONTROL_SERVICE_IMPL_H_ +#ifndef CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_IMPL_H_ +#define CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_IMPL_H_ #include <string> #include <vector> @@ -14,7 +14,7 @@ #include "base/memory/scoped_refptr.h" #include "base/sequence_checker.h" #include "base/version.h" -#include "chrome/updater/control_service.h" +#include "chrome/updater/update_service_internal.h" namespace update_client { enum class Error; @@ -104,4 +104,4 @@ } // namespace updater -#endif // CHROME_UPDATER_CONTROL_SERVICE_IMPL_H_ +#endif // CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_IMPL_H_
diff --git a/chrome/updater/control_service_impl_inactive.cc b/chrome/updater/update_service_internal_impl_inactive.cc similarity index 90% rename from chrome/updater/control_service_impl_inactive.cc rename to chrome/updater/update_service_internal_impl_inactive.cc index 3c1c637..f13508c 100644 --- a/chrome/updater/control_service_impl_inactive.cc +++ b/chrome/updater/update_service_internal_impl_inactive.cc
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/updater/control_service_impl_inactive.h" +#include "chrome/updater/update_service_internal_impl_inactive.h" #include "base/callback.h" #include "base/memory/scoped_refptr.h" #include "base/threading/sequenced_task_runner_handle.h" -#include "chrome/updater/control_service.h" +#include "chrome/updater/update_service_internal.h" namespace updater {
diff --git a/chrome/updater/control_service_impl_inactive.h b/chrome/updater/update_service_internal_impl_inactive.h similarity index 64% rename from chrome/updater/control_service_impl_inactive.h rename to chrome/updater/update_service_internal_impl_inactive.h index 24ab010..caf0204 100644 --- a/chrome/updater/control_service_impl_inactive.h +++ b/chrome/updater/update_service_internal_impl_inactive.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_UPDATER_CONTROL_SERVICE_IMPL_INACTIVE_H_ -#define CHROME_UPDATER_CONTROL_SERVICE_IMPL_INACTIVE_H_ +#ifndef CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_IMPL_INACTIVE_H_ +#define CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_IMPL_INACTIVE_H_ #include "base/memory/scoped_refptr.h" @@ -15,4 +15,4 @@ } // namespace updater -#endif // CHROME_UPDATER_CONTROL_SERVICE_IMPL_INACTIVE_H_ +#endif // CHROME_UPDATER_UPDATE_SERVICE_INTERNAL_IMPL_INACTIVE_H_
diff --git a/chrome/updater/win/BUILD.gn b/chrome/updater/win/BUILD.gn index cee6b56..a48f180 100644 --- a/chrome/updater/win/BUILD.gn +++ b/chrome/updater/win/BUILD.gn
@@ -76,8 +76,6 @@ source_set("lib") { sources = [ "action_handler.cc", - "control_service_proxy.cc", - "control_service_proxy.h", "group_policy_manager.cc", "group_policy_manager.h", "net/net_util.cc", @@ -104,6 +102,8 @@ "setup/uninstall.h", "task_scheduler.cc", "task_scheduler.h", + "update_service_internal_proxy.cc", + "update_service_internal_proxy.h", "update_service_proxy.cc", "update_service_proxy.h", "user_info.cc",
diff --git a/chrome/updater/win/app_install_controller.cc b/chrome/updater/win/app_install_controller.cc index b5e34e8..c809e6c 100644 --- a/chrome/updater/win/app_install_controller.cc +++ b/chrome/updater/win/app_install_controller.cc
@@ -26,8 +26,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/win/atl.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/update_service.h" +#include "chrome/updater/update_service_internal.h" #include "chrome/updater/win/install_progress_observer.h" #include "chrome/updater/win/ui/progress_wnd.h" #include "chrome/updater/win/ui/resources/resources.grh"
diff --git a/chrome/updater/win/control_service_proxy.cc b/chrome/updater/win/update_service_internal_proxy.cc similarity index 98% rename from chrome/updater/win/control_service_proxy.cc rename to chrome/updater/win/update_service_internal_proxy.cc index 98a2983..78ef9723 100644 --- a/chrome/updater/win/control_service_proxy.cc +++ b/chrome/updater/win/update_service_internal_proxy.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/updater/win/control_service_proxy.h" +#include "chrome/updater/win/update_service_internal_proxy.h" #include <windows.h> #include <wrl/client.h>
diff --git a/chrome/updater/win/control_service_proxy.h b/chrome/updater/win/update_service_internal_proxy.h similarity index 84% rename from chrome/updater/win/control_service_proxy.h rename to chrome/updater/win/update_service_internal_proxy.h index 7504c81d..e98bfb5 100644 --- a/chrome/updater/win/control_service_proxy.h +++ b/chrome/updater/win/update_service_internal_proxy.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_UPDATER_WIN_CONTROL_SERVICE_PROXY_H_ -#define CHROME_UPDATER_WIN_CONTROL_SERVICE_PROXY_H_ +#ifndef CHROME_UPDATER_WIN_UPDATE_SERVICE_INTERNAL_PROXY_H_ +#define CHROME_UPDATER_WIN_UPDATE_SERVICE_INTERNAL_PROXY_H_ #include "base/callback_forward.h" #include "base/memory/scoped_refptr.h" #include "base/sequence_checker.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/service_scope.h" +#include "chrome/updater/update_service_internal.h" namespace base { class SingleThreadTaskRunner; @@ -44,4 +44,4 @@ } // namespace updater -#endif // CHROME_UPDATER_WIN_CONTROL_SERVICE_PROXY_H_ +#endif // CHROME_UPDATER_WIN_UPDATE_SERVICE_INTERNAL_PROXY_H_
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc index 5893100..b630ab5 100644 --- a/chromecast/media/audio/cast_audio_output_stream.cc +++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -212,7 +212,6 @@ } int64_t CastAudioOutputStream::MixerServiceWrapper::GetMaxBufferedFrames() { - DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); int fill_size_frames = audio_params_.frames_per_buffer(); base::TimeDelta target_max_buffered_ms = kMediaMaxBufferedFrames; if (GetContentType(device_id_) == AudioContentType::kCommunication) {
diff --git a/chromeos/components/scanning/resources/index.html b/chromeos/components/scanning/resources/index.html index 6010e29..da14e63 100644 --- a/chromeos/components/scanning/resources/index.html +++ b/chromeos/components/scanning/resources/index.html
@@ -7,6 +7,13 @@ <meta charset="utf-8"> <title>$i18n{appTitle}</title> </head> + <style> + body { + height: 100vh; + margin: 0; + overflow: hidden; + } + </style> <body> <scanning-app></scanning-app>
diff --git a/chromeos/components/scanning/resources/scan_preview.html b/chromeos/components/scanning/resources/scan_preview.html index fc8ef43..4abfc84 100644 --- a/chromeos/components/scanning/resources/scan_preview.html +++ b/chromeos/components/scanning/resources/scan_preview.html
@@ -12,6 +12,12 @@ width: 60%; } + #helpOrProgress { + display: flex; + /* Calculate a height that results in a Letter aspect ratio (1:1.2941). */ + height: calc(1.2941 * var(--left-panel-width)); + } + #progressText { @apply --scanning-progress-text-font; color: var(--scanning-progress-text-color); @@ -24,19 +30,25 @@ } .preview { - border: 1px solid var(--google-grey-200); - border-radius: 4px; - display: flex; - /* TODO(michaelcheco): Replace with correct height for - * preview container. */ - height: 420px; + max-height: calc(100vh - var(--panel-container-margin-top)); overflow-y: scroll; } - /* TODO(jschettler): Check with UX about adding a border around each image. */ - .scanned-image { + .preview::-webkit-scrollbar { + -webkit-appearance: none; + width: 4px; + } + + .preview::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.5); border-radius: 4px; - width: 100%; + } + + .preview-item { + border: 1px solid var(--google-grey-200); + border-radius: 4px; + /* Subtract 2px for the border. */ + width: calc(100% - 2px); } /* Add top margin to all but the first scanned image. */ @@ -54,16 +66,19 @@ } </style> <div class="preview"> - <div id="helperText" hidden$="[[shouldHideHelperText_(appState)]]"> - <span inner-h-t-m-l="[[getHelperTextHtml_()]]"></span> - </div> - <div id="scanProgress" hidden$="[[shouldHideProgress_(appState)]]"> - <span id="progressText">[[getProgressTextString_(pageNumber)]]</span> - <paper-progress value="[[progressPercent]]"></paper-progress> + <div id="helpOrProgress" class="preview-item" + hidden$="[[shouldShowScannedImages_(appState)]]"> + <div id="helperText" hidden$="[[shouldHideHelperText_(appState)]]"> + <span inner-h-t-m-l="[[getHelperTextHtml_()]]"></span> + </div> + <div id="scanProgress" hidden$="[[shouldHideProgress_(appState)]]"> + <span id="progressText">[[getProgressTextString_(pageNumber)]]</span> + <paper-progress value="[[progressPercent]]"></paper-progress> + </div> </div> <div id="scannedImages" hidden$="[[!shouldShowScannedImages_(appState)]]"> <template is="dom-repeat" items="[[objectUrls]]" as="url"> - <img class="scanned-image" src="[[url]]"> + <img class="preview-item scanned-image" src="[[url]]"> </template> </div> </div>
diff --git a/chromeos/components/scanning/resources/scanning_app.html b/chromeos/components/scanning/resources/scanning_app.html index a154740..6678365 100644 --- a/chromeos/components/scanning/resources/scanning_app.html +++ b/chromeos/components/scanning/resources/scanning_app.html
@@ -60,11 +60,11 @@ .panel-container { display: flex; - margin-bottom: var(--panel-container-margin-bottom); margin-top: var(--panel-container-margin-top); } .right-panel { + margin-bottom: var(--right-panel-margin-bottom); padding-inline-end: var(--right-panel-padding-end); padding-inline-start: var(--right-panel-padding-start); width: var(--right-panel-width);
diff --git a/chromeos/components/scanning/resources/scanning_shared_css.html b/chromeos/components/scanning/resources/scanning_shared_css.html index 0eb10d0..cf1588c5 100644 --- a/chromeos/components/scanning/resources/scanning_shared_css.html +++ b/chromeos/components/scanning/resources/scanning_shared_css.html
@@ -17,8 +17,8 @@ --left-panel-padding-end: 32px; --left-panel-padding-start: 32px; --left-panel-width: 288px; - --panel-container-margin-bottom: 20px; --panel-container-margin-top: 20px; + --right-panel-margin-bottom: 20px; --right-panel-padding-end: 32px; --right-panel-padding-start: 0px; --right-panel-width: 384px; @@ -31,8 +31,8 @@ --left-panel-padding-end: 48px; --left-panel-padding-start: 48px; --left-panel-width: 384px; - --panel-container-margin-bottom: 32px; --panel-container-margin-top: 20px; + --right-panel-margin-bottom: 32px; --right-panel-padding-end: 48px; --right-panel-padding-start: 48px; --right-panel-width: 384px; @@ -45,8 +45,8 @@ --left-panel-padding-end: 60px; --left-panel-padding-start: 164px; --left-panel-width: 416px; - --panel-container-margin-bottom: 64px; --panel-container-margin-top: 64px; + --right-panel-margin-bottom: 64px; --right-panel-padding-end: 164px; --right-panel-padding-start: 60px; --right-panel-width: 416px;
diff --git a/chromeos/crosapi/cpp/crosapi_constants.cc b/chromeos/crosapi/cpp/crosapi_constants.cc index e7504b0..01973a0 100644 --- a/chromeos/crosapi/cpp/crosapi_constants.cc +++ b/chromeos/crosapi/cpp/crosapi_constants.cc
@@ -15,13 +15,6 @@ // a directory in the encrypted user data partition. const char kHomeChronosUserPath[] = "/home/chronos/user"; -// The "MyFiles" directory for the ash-side primary user. -const char kMyFilesPath[] = "/home/chronos/user/MyFiles"; - -// The "Downloads" directory for the ash-side primary user. Note that the user -// can choose to download files to a different directory, see DownloadPrefs. -const char kDefaultDownloadsPath[] = "/home/chronos/user/MyFiles/Downloads"; - // The default user-data-directory for Lacros. // NOTE: This is security sensitive. The directory must be inside the encrypted // user data partition.
diff --git a/chromeos/crosapi/cpp/crosapi_constants.h b/chromeos/crosapi/cpp/crosapi_constants.h index 19009786..7b6f120 100644 --- a/chromeos/crosapi/cpp/crosapi_constants.h +++ b/chromeos/crosapi/cpp/crosapi_constants.h
@@ -13,10 +13,6 @@ COMPONENT_EXPORT(CROSAPI) extern const char kHomeChronosUserPath[]; -COMPONENT_EXPORT(CROSAPI) extern const char kMyFilesPath[]; - -COMPONENT_EXPORT(CROSAPI) extern const char kDefaultDownloadsPath[]; - COMPONENT_EXPORT(CROSAPI) extern const char kLacrosUserDataPath[]; COMPONENT_EXPORT(CROSAPI) extern const char kChromeOSReleaseTrack[];
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom index 71ea528..8b5c0667 100644 --- a/chromeos/crosapi/mojom/crosapi.mojom +++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -12,6 +12,7 @@ import "chromeos/crosapi/mojom/screen_manager.mojom"; import "chromeos/crosapi/mojom/select_file.mojom"; import "mojo/public/mojom/base/big_string.mojom"; +import "mojo/public/mojom/base/file_path.mojom"; import "mojo/public/mojom/base/token.mojom"; import "mojo/public/mojom/base/values.mojom"; import "services/device/public/mojom/hid.mojom"; @@ -129,6 +130,22 @@ kDemo, }; +// Default directories on the system. +[Stable] +struct DefaultPaths { + // The default (non-configurable) directory for documents. For example, + // /home/chronos/u-<hash>/MyFiles. We send the full path for future + // compatibility, to avoid assumptions about where on disk the directory is + // located. + mojo_base.mojom.FilePath documents@0; + + // The default (non-configurable) directory for downloads. For example, + // /home/chronos/u-<hash>/MyFiles/Downloads. We send the full path for future + // compatibility, to avoid assumptions about where on disk the directory is + // located. + mojo_base.mojom.FilePath downloads@1; +}; + // LacrosInitParams is a set of parameters for initialization of lacros-chrome, // which is passed from ash-chrome to lacros-chrome. Since ash-chrome and // lacros-chrome may have different versions, lacros-chrome must handle this @@ -181,6 +198,11 @@ // Added in M88. [MinVersion=5] map<mojo_base.mojom.Token, uint32>? interface_versions@5; + + // Default directories on the system. + // Added in M89. + [MinVersion=6] + DefaultPaths? default_paths@6; }; // LacrosChromeService defines the APIs that live in lacros-chrome and
diff --git a/chromeos/dbus/hermes/fake_hermes_profile_client.cc b/chromeos/dbus/hermes/fake_hermes_profile_client.cc index 8a19cb0..ed6dd33 100644 --- a/chromeos/dbus/hermes/fake_hermes_profile_client.cc +++ b/chromeos/dbus/hermes/fake_hermes_profile_client.cc
@@ -154,12 +154,6 @@ // Update the cellular device properties so that they match the carrier // profile that was just enabled. - device_test->SetDeviceProperty( - kCellularDevicePath, shill::kCarrierProperty, - base::Value(properties->service_provider().value()), true); - device_test->SetDeviceProperty( - kCellularDevicePath, shill::kCarrierProperty, - base::Value(properties->service_provider().value()), true); base::DictionaryValue home_provider; home_provider.SetKey(shill::kNameProperty, base::Value(properties->service_provider().value()));
diff --git a/chromeos/lacros/lacros_chrome_service_delegate.h b/chromeos/lacros/lacros_chrome_service_delegate.h index 7dec91f6..1d47549 100644 --- a/chromeos/lacros/lacros_chrome_service_delegate.h +++ b/chromeos/lacros/lacros_chrome_service_delegate.h
@@ -12,6 +12,12 @@ class GURL; +namespace crosapi { +namespace mojom { +class LacrosInitParams; +} // namespace mojom +} // namespace crosapi + namespace chromeos { // Interface to inject Chrome dependent behavior into LacrosChromeServiceImpl @@ -20,6 +26,10 @@ public: virtual ~LacrosChromeServiceDelegate() = default; + // Called during startup when |init_params| become available. + virtual void OnInitialized( + const crosapi::mojom::LacrosInitParams& init_params) = 0; + // Opens a new browser window. virtual void NewWindow() = 0;
diff --git a/chromeos/lacros/lacros_chrome_service_impl.cc b/chromeos/lacros/lacros_chrome_service_impl.cc index 0ef7157..a9f3797 100644 --- a/chromeos/lacros/lacros_chrome_service_impl.cc +++ b/chromeos/lacros/lacros_chrome_service_impl.cc
@@ -295,6 +295,8 @@ BindLacrosChromeServiceReceiver, weak_sequenced_state_, std::move(receiver))); sequenced_state_->WaitForInit(); + DCHECK(init_params_); + delegate_->OnInitialized(*init_params_); did_bind_receiver_ = true; // Bind the remote for MessageCenter on the current thread, and then pass the
diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc index 6a233197..eea2723 100644 --- a/chromeos/network/onc/onc_signature.cc +++ b/chromeos/network/onc/onc_signature.cc
@@ -287,7 +287,6 @@ {::onc::kRecommended, &kRecommendedSignature}, {::onc::cellular::kAPN, &kCellularApnSignature}, {::onc::cellular::kAPNList, &kCellularApnListSignature}, - {::onc::cellular::kCarrier, &kStringSignature}, {::onc::cellular::kAutoConnect, &kBoolSignature}, {NULL}};
diff --git a/chromeos/printing/uri.h b/chromeos/printing/uri.h index 325708a5..5e0abaf 100644 --- a/chromeos/printing/uri.h +++ b/chromeos/printing/uri.h
@@ -284,7 +284,7 @@ // If the Port is specified (GetPort() != -1) and |always_print_port| is set // to true, a Port number is always included in the returned URI (even when // it equals to a Scheme's default port number). - std::string GetNormalized(bool always_print_port = false) const; + std::string GetNormalized(bool always_print_port = true) const; // Returns true <=> whole URL has no UTF-8 characters. bool IsASCII() const;
diff --git a/chromeos/printing/uri_unittest.cc b/chromeos/printing/uri_unittest.cc index 01faf52..d29057f 100644 --- a/chromeos/printing/uri_unittest.cc +++ b/chromeos/printing/uri_unittest.cc
@@ -55,7 +55,7 @@ uri.SetUserinfo(components.userinfo); ASSERT_EQ(uri.GetLastParsingError().status, Uri::ParserStatus::kNoErrors); // Check URI. - EXPECT_EQ(uri.GetNormalized(), normalized_uri); + EXPECT_EQ(uri.GetNormalized(false), normalized_uri); } // Verifies that |input_uri| set as parameter in Uri constructor is parsed @@ -79,7 +79,7 @@ const std::string& normalized_uri) { Uri uri(input_uri); ASSERT_EQ(uri.GetLastParsingError().status, Uri::ParserStatus::kNoErrors); - EXPECT_EQ(uri.GetNormalized(), normalized_uri); + EXPECT_EQ(uri.GetNormalized(false), normalized_uri); } TEST(UriTest, DefaultConstructor) {
diff --git a/chromeos/printing/uri_unittest_consistency.cc b/chromeos/printing/uri_unittest_consistency.cc index e25b75b..1705833 100644 --- a/chromeos/printing/uri_unittest_consistency.cc +++ b/chromeos/printing/uri_unittest_consistency.cc
@@ -121,32 +121,36 @@ // Build normalized URI from encoded components and make sure that it is // equal to the value returned by GetNormalized(). TEST_P(UriConsistencyTest, UriBuilding) { - std::string expected_uri = uri_.GetScheme() + ":"; + std::string scheme = uri_.GetScheme() + ":"; // Build a part of URI called Authority (Userinfo@Host:Port). std::string authority_encoded; if (!uri_.GetUserinfoEncoded().empty()) authority_encoded = uri_.GetUserinfoEncoded() + "@"; authority_encoded += uri_.GetHostEncoded(); - if (uri_.GetPort() != -1 && - uri_.GetPort() != Uri::GetDefaultPort(uri_.GetScheme())) { - authority_encoded += ":" + base::NumberToString(uri_.GetPort()); + std::string authority_with_port_encoded = authority_encoded; + if (uri_.GetPort() != -1) { + if (uri_.GetPort() != Uri::GetDefaultPort(uri_.GetScheme())) + authority_encoded += ":" + base::NumberToString(uri_.GetPort()); + authority_with_port_encoded += ":" + base::NumberToString(uri_.GetPort()); } - // If Authority is not empty, add it to |expected_uri|. + // If Authority is not empty, prefix it with "//". if (!authority_encoded.empty()) - expected_uri += "//" + authority_encoded; + authority_encoded = "//" + authority_encoded; + if (!authority_with_port_encoded.empty()) + authority_with_port_encoded = "//" + authority_with_port_encoded; - // Add Path and Query. - expected_uri += uri_.GetPathEncodedAsString(); - const std::string expected_query = uri_.GetQueryEncodedAsString(); - if (!expected_query.empty()) - expected_uri += "?" + expected_query; - - // Add Fragment to |expected_uri|. + // Build Path, Query and Fragment. + std::string path_query_fragment_encoded = uri_.GetPathEncodedAsString(); + if (!uri_.GetQueryEncodedAsString().empty()) + path_query_fragment_encoded += "?" + uri_.GetQueryEncodedAsString(); if (!uri_.GetFragmentEncoded().empty()) - expected_uri += "#" + uri_.GetFragmentEncoded(); + path_query_fragment_encoded += "#" + uri_.GetFragmentEncoded(); - EXPECT_EQ(uri_.GetNormalized(), expected_uri); + EXPECT_EQ(uri_.GetNormalized(false), + scheme + authority_encoded + path_query_fragment_encoded); + EXPECT_EQ(uri_.GetNormalized(true), + scheme + authority_with_port_encoded + path_query_fragment_encoded); } // Checks if the normalization algorithm is consistent. @@ -154,7 +158,8 @@ // Normalization of normalized uri must not change it. Uri uri2(uri_.GetNormalized()); EXPECT_EQ(uri2.GetLastParsingError().status, Uri::ParserStatus::kNoErrors); - EXPECT_EQ(uri_.GetNormalized(), uri2.GetNormalized()); + EXPECT_EQ(uri_.GetNormalized(true), uri2.GetNormalized(true)); + EXPECT_EQ(uri_.GetNormalized(false), uri2.GetNormalized(false)); // Normalization of normalized Path must not change it. uri2.SetPathEncoded(uri_.GetPathEncodedAsString());
diff --git a/chromeos/services/secure_channel/wire_message.cc b/chromeos/services/secure_channel/wire_message.cc index b9e232c..a0a31af92 100644 --- a/chromeos/services/secure_channel/wire_message.cc +++ b/chromeos/services/secure_channel/wire_message.cc
@@ -10,36 +10,36 @@ #include <limits> #include "base/base64url.h" +#include "base/big_endian.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/notreached.h" #include "base/values.h" #include "chromeos/components/multidevice/logging/logging.h" -// The wire messages have a simple format: -// [ message version ] [ body length ] [ JSON body ] -// 1 byte 2 bytes body length -// When sending encrypted messages, the JSON body contains two fields: an -// optional |permit_id| field and a required |payload| field. -// -// For non-encrypted messages, the message itself is the JSON body, and it -// doesn't have a |payload| field. - namespace chromeos { namespace secure_channel { namespace { -// The length of the message header, in bytes. -const size_t kHeaderLength = 3; +// The number of bytes used to represent the protocol version in the message +// header. +const size_t kNumBytesInHeaderProtocolVersion = 1u; -// The protocol version of the message format. -const int kMessageFormatVersionThree = 3; +// The number of bytes used to represent the message body size. +const size_t kV3NumBytesInHeaderSize = 2u; // 16-bit int +const size_t kV4NumBytesInHeaderSize = 4u; // 32-bit int -const char kPayloadKey[] = "payload"; +// Supported Protocol versions. +const uint8_t kV3HeaderVersion = 0x03; +const uint8_t kV4HeaderVersion = 0x04; + +// JSON keys for feature and payload. const char kFeatureKey[] = "feature"; +const char kPayloadKey[] = "payload"; // The default feature value. This is the default for backward compatibility // reasons; previously, the protocol did not transmit the feature in the @@ -48,77 +48,41 @@ // EasyUnlock by default. const char kDefaultFeature[] = "easy_unlock"; -// Parses the |serialized_message|'s header. Returns |true| iff the message has -// a valid header, is complete, and is well-formed according to the header. Sets -// |is_incomplete_message| to true iff the message does not have enough data to -// parse the header, or if the message length encoded in the message header -// exceeds the size of the |serialized_message|. -bool ParseHeader(const std::string& serialized_message, - bool* is_incomplete_message) { - *is_incomplete_message = false; - if (serialized_message.size() < kHeaderLength) { - *is_incomplete_message = true; - return false; - } +// Features which were launched before protocol v4 was introduced. If we try to +// serialize a WireMessage whose feature is one of these, we should use the v3 +// protocol. +const char* const kV3Features[] = { + // Authentication protocol (used for all features). + "auth" - static_assert(kHeaderLength > 2, "kHeaderLength too small"); - size_t version = serialized_message[0]; - if (version != kMessageFormatVersionThree) { - PA_LOG(WARNING) << "Error: Invalid message version. Got " << version - << ", expected " << kMessageFormatVersionThree; - return false; - } + // Smart Lock. + "easy_unlock", - uint16_t expected_body_length = - (static_cast<uint8_t>(serialized_message[1]) << 8) | - (static_cast<uint8_t>(serialized_message[2]) << 0); - size_t expected_message_length = kHeaderLength + expected_body_length; - if (serialized_message.size() < expected_message_length) { - *is_incomplete_message = true; - return false; - } - if (serialized_message.size() != expected_message_length) { - PA_LOG(WARNING) << "Error: Invalid message length. Got " - << serialized_message.size() << ", expected " - << expected_message_length; - return false; - } + // Instant Tethering. + "magic_tether", +}; - return true; -} - -} // namespace - -WireMessage::~WireMessage() {} - -// static -std::unique_ptr<WireMessage> WireMessage::Deserialize( - const std::string& serialized_message, - bool* is_incomplete_message) { - if (!ParseHeader(serialized_message, is_incomplete_message)) - return nullptr; - - std::unique_ptr<base::Value> body_value = base::JSONReader::ReadDeprecated( - serialized_message.substr(kHeaderLength)); +std::unique_ptr<WireMessage> DeserializeJsonMessageBody( + const std::string& serialized_message_body) { + std::unique_ptr<base::Value> body_value = + base::JSONReader::ReadDeprecated(serialized_message_body); if (!body_value || !body_value->is_dict()) { - PA_LOG(WARNING) << "Error: Unable to parse message as JSON."; + PA_LOG(WARNING) << "Unable to parse message as JSON."; return nullptr; } base::DictionaryValue* body; - bool success = body_value->GetAsDictionary(&body); - DCHECK(success); + if (!body_value->GetAsDictionary(&body)) + NOTREACHED(); std::string payload_base64; if (!body->GetString(kPayloadKey, &payload_base64)) { - // The body is a valid JSON, but it doesn't contain a |payload| field. It - // must be a non-encrypted message. - return base::WrapUnique( - new WireMessage(serialized_message.substr(kHeaderLength))); + // Legacy case: Message without a payload. + return base::WrapUnique(new WireMessage(serialized_message_body)); } if (payload_base64.empty()) { - PA_LOG(WARNING) << "Error: Missing payload."; + PA_LOG(WARNING) << "Message contains empty payload."; return nullptr; } @@ -126,18 +90,103 @@ if (!base::Base64UrlDecode(payload_base64, base::Base64UrlDecodePolicy::REQUIRE_PADDING, &payload)) { - PA_LOG(WARNING) << "Error: Invalid base64 encoding for payload."; + PA_LOG(WARNING) << "Payload contains invalid base64 encoding."; return nullptr; } std::string feature; if (!body->GetString(kFeatureKey, &feature) || feature.empty()) { - feature = std::string(kDefaultFeature); + feature = kDefaultFeature; } return base::WrapUnique(new WireMessage(payload, feature)); } +std::unique_ptr<WireMessage> DeserializeV3OrV4Message( + const std::string& serialized_message, + bool* is_incomplete_message, + bool is_v3) { + const size_t kHeaderSize = + kNumBytesInHeaderProtocolVersion + + (is_v3 ? kV3NumBytesInHeaderSize : kV4NumBytesInHeaderSize); + + if (serialized_message.size() < kHeaderSize) { + PA_LOG(ERROR) << "Message was shorter than expected. " + << "Size: " << serialized_message.size() << ", " + << "Version: " << (is_v3 ? 3 : 4); + *is_incomplete_message = true; + return nullptr; + } + + // Reads the expected body size, starting after the protocol message portion + // of the header. Because this value is received over the network, we must + // convert from big endian to host byte order. + base::BigEndianReader reader( + serialized_message.data() + kNumBytesInHeaderProtocolVersion, + serialized_message.size() - kNumBytesInHeaderProtocolVersion); + + size_t expected_message_length; + if (is_v3) { + uint16_t body_length; + if (!reader.ReadU16(&body_length)) { + PA_LOG(ERROR) << "Failed to read v3 message length."; + *is_incomplete_message = true; + return nullptr; + } + expected_message_length = kHeaderSize + body_length; + } else { + uint32_t body_length; + if (!reader.ReadU32(&body_length)) { + PA_LOG(ERROR) << "Failed to read v4 message length."; + *is_incomplete_message = true; + return nullptr; + } + expected_message_length = kHeaderSize + body_length; + } + + size_t message_length = serialized_message.size(); + if (message_length != expected_message_length) { + PA_LOG(ERROR) << "Message length does not match expectation. " + << "Size: " << serialized_message.size() << ", " + << "Expected size: " << expected_message_length << ", " + << "Version: " << (is_v3 ? 3 : 4); + *is_incomplete_message = message_length < expected_message_length; + return nullptr; + } + + *is_incomplete_message = false; + return DeserializeJsonMessageBody(serialized_message.substr(kHeaderSize)); +} + +} // namespace + +WireMessage::~WireMessage() = default; + +// static +std::unique_ptr<WireMessage> WireMessage::Deserialize( + const std::string& serialized_message, + bool* is_incomplete_message) { + if (serialized_message.empty()) { + PA_LOG(ERROR) << "Attempted to deserialize empty message."; + *is_incomplete_message = true; + return nullptr; + } + + // The first byte of the message is the protocol version as an unsigned 8-bit + // integer. + uint8_t protocol_version = serialized_message[0]; + + if (protocol_version == kV3HeaderVersion || + protocol_version == kV4HeaderVersion) { + return DeserializeV3OrV4Message(serialized_message, is_incomplete_message, + protocol_version == kV3HeaderVersion); + } + + PA_LOG(ERROR) << "Received message with unknown version " << protocol_version; + *is_incomplete_message = false; + return nullptr; +} + std::string WireMessage::Serialize() const { std::string json_body; if (body_.empty()) { @@ -146,7 +195,7 @@ return std::string(); } - // Create JSON body containing permit id and payload. + // Create JSON body containing feature and payload. base::DictionaryValue body; std::string base64_payload; @@ -164,23 +213,30 @@ json_body = body_; } - // Create header containing version and payload size. + bool use_v3_encoding = body_.empty() || feature_.empty() || + base::Contains(kV3Features, feature_); + size_t body_size = json_body.size(); - if (body_size > std::numeric_limits<uint16_t>::max()) { + if (use_v3_encoding && body_size > std::numeric_limits<uint16_t>::max()) { PA_LOG(ERROR) << "Can not create WireMessage because body size exceeds " << "16-bit unsigned integer: " << body_size; return std::string(); } - uint8_t header[] = { - static_cast<uint8_t>(kMessageFormatVersionThree), - static_cast<uint8_t>((body_size >> 8) & 0xFF), - static_cast<uint8_t>(body_size & 0xFF), - }; - static_assert(sizeof(header) == kHeaderLength, "Malformed header."); + const size_t kHeaderSize = + kNumBytesInHeaderProtocolVersion + + (use_v3_encoding ? kV3NumBytesInHeaderSize : kV4NumBytesInHeaderSize); - std::string header_string(kHeaderLength, 0); - std::memcpy(&header_string[0], header, kHeaderLength); + std::string header_string(kHeaderSize, 0); + base::BigEndianWriter writer(&header_string[0], kHeaderSize); + if (use_v3_encoding) { + writer.WriteU8(kV3HeaderVersion); + writer.WriteU16(static_cast<uint16_t>(body_size)); + } else { + writer.WriteU8(kV4HeaderVersion); + writer.WriteU32(static_cast<uint32_t>(body_size)); + } + return header_string + json_body; }
diff --git a/chromeos/services/secure_channel/wire_message.h b/chromeos/services/secure_channel/wire_message.h index a6be885..d0b3bc3 100644 --- a/chromeos/services/secure_channel/wire_message.h +++ b/chromeos/services/secure_channel/wire_message.h
@@ -14,6 +14,33 @@ namespace secure_channel { +// Message sent over the wire via SecureChannel. Each message sent using the +// SecureChannel protocol has a feature name (a unique identifier for the client +// sending/receiving a message) and a payload. +// +// A wire message in SecureChannel is serialized to a byte array (in the format +// of a std::string). The first byte is always the protocol version expressed as +// an unsigned 8-bit int. This class supports protocol versions 3 and 4. +// +// v3: One byte version (0x03), followed by 2 bytes of the message size as an +// unsigned 16-bit int, followed by a stringified JSON object containing a +// "feature" key whose value is the feature and a "payload" key whose value +// is the payload. +// +// [ message version ] [ body length ] [ JSON body ] +// 1 byte 2 bytes body length +// +// v4: One byte version (0x04), followed by 4 bytes of the message size as an +// unsigned 32-bit int, followed by a stringified JSON object containing a +// "feature" key whose value is the feature and a "payload" key whose value +// is the payload. +// +// [ message version ] [ body length ] [ JSON body ] +// 1 byte 4 bytes body length +// +// v3 is deprecated and all new features use v4, but we special-case features +// which were released before v4 and send them via v3 for backward +// compatibility. class WireMessage { public: // Creates a WireMessage containing |payload| for feature |feature| and
diff --git a/chromeos/services/secure_channel/wire_message_unittest.cc b/chromeos/services/secure_channel/wire_message_unittest.cc index b83de7b..34ede73 100644 --- a/chromeos/services/secure_channel/wire_message_unittest.cc +++ b/chromeos/services/secure_channel/wire_message_unittest.cc
@@ -30,7 +30,7 @@ EXPECT_FALSE(message); } -TEST(SecureChannelWireMessageTest, Deserialize_IncompleteHeader) { +TEST(SecureChannelWireMessageTest, Deserialize_IncompleteHeader_V3) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize("\3", &is_incomplete); @@ -38,6 +38,14 @@ EXPECT_FALSE(message); } +TEST(SecureChannelWireMessageTest, Deserialize_IncompleteHeader_V4) { + bool is_incomplete; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize("\4", &is_incomplete); + EXPECT_TRUE(is_incomplete); + EXPECT_FALSE(message); +} + TEST(SecureChannelWireMessageTest, Deserialize_UnexpectedMessageFormatVersion) { bool is_incomplete; // Version 2 is below the minimum supported version. @@ -47,7 +55,7 @@ EXPECT_FALSE(message); } -TEST(SecureChannelWireMessageTest, Deserialize_BodyOfSizeZero) { +TEST(SecureChannelWireMessageTest, Deserialize_BodyOfSizeZero_V3) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(std::string("\3\0\0", 3), &is_incomplete); @@ -55,7 +63,15 @@ EXPECT_FALSE(message); } -TEST(SecureChannelWireMessageTest, Deserialize_IncompleteBody) { +TEST(SecureChannelWireMessageTest, Deserialize_BodyOfSizeZero_V4) { + bool is_incomplete; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(std::string("\4\0\0\0\0", 5), &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(SecureChannelWireMessageTest, Deserialize_IncompleteBody_V3) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize(std::string("\3\0\5", 3), &is_incomplete); @@ -63,8 +79,16 @@ EXPECT_FALSE(message); } +TEST(SecureChannelWireMessageTest, Deserialize_IncompleteBody_V4) { + bool is_incomplete; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(std::string("\4\0\0\0\5", 5), &is_incomplete); + EXPECT_TRUE(is_incomplete); + EXPECT_FALSE(message); +} + TEST(SecureChannelWireMessageTest, - Deserialize_BodyLongerThanSpecifiedInHeader) { + Deserialize_BodyLongerThanSpecifiedInHeader_V3) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize( std::string("\3\0\5", 3) + "123456", &is_incomplete); @@ -72,7 +96,16 @@ EXPECT_FALSE(message); } -TEST(SecureChannelWireMessageTest, Deserialize_BodyIsNotValidJSON) { +TEST(SecureChannelWireMessageTest, + Deserialize_BodyLongerThanSpecifiedInHeader_V4) { + bool is_incomplete; + std::unique_ptr<WireMessage> message = WireMessage::Deserialize( + std::string("\4\0\0\0\5", 5) + "123456", &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(SecureChannelWireMessageTest, Deserialize_BodyIsNotValidJSON_V3) { bool is_incomplete; std::unique_ptr<WireMessage> message = WireMessage::Deserialize( std::string("\3\0\5", 3) + "12345", &is_incomplete); @@ -80,7 +113,15 @@ EXPECT_FALSE(message); } -TEST(SecureChannelWireMessageTest, Deserialize_BodyIsNotADictionary) { +TEST(SecureChannelWireMessageTest, Deserialize_BodyIsNotValidJSON_V4) { + bool is_incomplete; + std::unique_ptr<WireMessage> message = WireMessage::Deserialize( + std::string("\4\0\0\0\5", 5) + "12345", &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(SecureChannelWireMessageTest, Deserialize_BodyIsNotADictionary_V3) { bool is_incomplete; std::string header("\3\0\x15", 3); std::string bytes = header + "[{\"payload\": \"YQ==\"}]"; @@ -90,7 +131,17 @@ EXPECT_FALSE(message); } -TEST(SecureChannelWireMessageTest, Deserialize_NonEncryptedMessage) { +TEST(SecureChannelWireMessageTest, Deserialize_BodyIsNotADictionary_V4) { + bool is_incomplete; + std::string header("\4\0\0\0\x15", 5); + std::string bytes = header + "[{\"payload\": \"YQ==\"}]"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(SecureChannelWireMessageTest, Deserialize_NonEncryptedMessage_V3) { bool is_incomplete; std::string header("\3\0\x02", 3); std::string bytes = header + "{}"; @@ -101,7 +152,18 @@ EXPECT_EQ("{}", message->body()); } -TEST(SecureChannelWireMessageTest, Deserialize_BodyHasEmptyPayload) { +TEST(SecureChannelWireMessageTest, Deserialize_NonEncryptedMessage_V4) { + bool is_incomplete; + std::string header("\4\0\0\0\x02", 5); + std::string bytes = header + "{}"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + ASSERT_TRUE(message); + EXPECT_EQ("{}", message->body()); +} + +TEST(SecureChannelWireMessageTest, Deserialize_BodyHasEmptyPayload_V3) { bool is_incomplete; std::string header("\3\0\x29", 3); std::string bytes = @@ -112,7 +174,18 @@ EXPECT_FALSE(message); } -TEST(SecureChannelWireMessageTest, Deserialize_PayloadIsNotBase64Encoded) { +TEST(SecureChannelWireMessageTest, Deserialize_BodyHasEmptyPayload_V4) { + bool is_incomplete; + std::string header("\4\0\0\0\x29", 5); + std::string bytes = + header + "{\"payload\": \"\", \"feature\": \"testFeature\"}"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(SecureChannelWireMessageTest, Deserialize_PayloadIsNotBase64Encoded_V3) { bool is_incomplete; std::string header("\3\0\x30", 3); std::string bytes = @@ -123,7 +196,18 @@ EXPECT_FALSE(message); } -TEST(SecureChannelWireMessageTest, Deserialize_ValidMessage) { +TEST(SecureChannelWireMessageTest, Deserialize_PayloadIsNotBase64Encoded_V4) { + bool is_incomplete; + std::string header("\4\0\0\0\x30", 5); + std::string bytes = + header + "{\"payload\": \"garbage\", \"feature\": \"testFeature\"}"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + EXPECT_FALSE(message); +} + +TEST(SecureChannelWireMessageTest, Deserialize_ValidMessage_V3) { bool is_incomplete; std::string header("\3\0\x2d", 3); std::string bytes = @@ -136,8 +220,21 @@ EXPECT_EQ("testFeature", message->feature()); } +TEST(SecureChannelWireMessageTest, Deserialize_ValidMessage_V4) { + bool is_incomplete; + std::string header("\4\0\0\0\x2d", 5); + std::string bytes = + header + "{\"payload\": \"YQ==\", \"feature\": \"testFeature\"}"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + ASSERT_TRUE(message); + EXPECT_EQ("a", message->payload()); + EXPECT_EQ("testFeature", message->feature()); +} + TEST(SecureChannelWireMessageTest, - Deserialize_ValidMessageWithBase64UrlEncoding) { + Deserialize_ValidMessageWithBase64UrlEncoding_V3) { bool is_incomplete; std::string header("\3\0\x2d", 3); std::string bytes = @@ -151,7 +248,21 @@ } TEST(SecureChannelWireMessageTest, - Deserialize_ValidMessageWithExtraUnknownFields) { + Deserialize_ValidMessageWithBase64UrlEncoding_V4) { + bool is_incomplete; + std::string header("\4\0\0\0\x2d", 5); + std::string bytes = + header + "{\"payload\": \"_-Y=\", \"feature\": \"testFeature\"}"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + ASSERT_TRUE(message); + EXPECT_EQ("\xFF\xE6", message->payload()); + EXPECT_EQ("testFeature", message->feature()); +} + +TEST(SecureChannelWireMessageTest, + Deserialize_ValidMessageWithExtraUnknownFields_V3) { bool is_incomplete; std::string header("\3\0\x4c", 3); std::string bytes = header + @@ -168,6 +279,24 @@ EXPECT_EQ("testFeature", message->feature()); } +TEST(SecureChannelWireMessageTest, + Deserialize_ValidMessageWithExtraUnknownFields_V4) { + bool is_incomplete; + std::string header("\4\0\0\0\x4c", 5); + std::string bytes = header + + "{" + " \"payload\": \"YQ==\"," + " \"feature\": \"testFeature\"," + " \"unexpected\": \"surprise!\"" + "}"; + std::unique_ptr<WireMessage> message = + WireMessage::Deserialize(bytes, &is_incomplete); + EXPECT_FALSE(is_incomplete); + ASSERT_TRUE(message); + EXPECT_EQ("a", message->payload()); + EXPECT_EQ("testFeature", message->feature()); +} + TEST(SecureChannelWireMessageTest, Deserialize_SizeEquals0x01FF) { // Create a message with a body of 0x01FF bytes to test the size contained in // the header is parsed correctly.
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 c8cc0c5..2ba6d68 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
@@ -181,8 +181,12 @@ public static final String TAB_SWITCHER_BUTTON_CLICKED = "tab_switcher_button_clicked"; /** Read later related events. */ + public static final String APP_MENU_BOOKMARK_STAR_ICON_PRESSED = + "app_menu_bookmark_star_icon_pressed"; 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_BOTTOM_SHEET_FOLDER_SEEN = + "read_later_bottom_sheet_folder_seen"; public static final String READ_LATER_BOOKMARK_FOLDER_OPENED = "read_later_bookmark_folder_opened";
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 278f528..72b5741 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
@@ -51,7 +51,6 @@ Resources resources, Runnable messageDismissed) { mModel = model; mMaxTranslationSupplier = maxTranslationSupplier; - mModel.set(TRANSLATION_Y, -mMaxTranslationSupplier.get()); mHideThresholdPx = resources.getDimensionPixelSize(R.dimen.message_hide_threshold); mMessageDismissed = messageDismissed; } @@ -61,6 +60,9 @@ * @param messageShown The {@link Runnable} that will run once the message banner is shown. */ void show(Runnable messageShown) { + if (mAnimatorSet == null) { + mModel.set(TRANSLATION_Y, -mMaxTranslationSupplier.get()); + } cancelAnyAnimations(); mAnimatorSet = createAnimatorSet(true); mAnimatorSet.addListener(new CancelAwareAnimatorListener() { @@ -119,11 +121,12 @@ // No need to animate if the message banner is in resting position. if (mModel.get(TRANSLATION_Y) == 0.f) return; - mAnimatorSet = createAnimatorSet(mModel.get(TRANSLATION_Y) > -mHideThresholdPx); + final boolean isShow = mModel.get(TRANSLATION_Y) > -mHideThresholdPx; + mAnimatorSet = createAnimatorSet(isShow); mAnimatorSet.addListener(new CancelAwareAnimatorListener() { @Override public void onEnd(Animator animator) { - mMessageDismissed.run(); + if (!isShow) mMessageDismissed.run(); mAnimatorSet = null; } });
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageContainer.java b/components/messages/android/java/src/org/chromium/components/messages/MessageContainer.java index a8a083a..4058d4d 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageContainer.java +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageContainer.java
@@ -48,4 +48,27 @@ ViewUtils.setAncestorsShouldClipChildren(this, true); removeAllViews(); } + + /** + * Runs a {@link Runnable} after the initial layout. If the view is already laid out, the + * {@link Runnable} will be called immediately. + * @param runnable The {@link Runnable}. + */ + void runAfterInitialLayout(Runnable runnable) { + if (getHeight() > 0) { + runnable.run(); + return; + } + + addOnLayoutChangeListener(new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + if (v.getHeight() == 0) return; + + runnable.run(); + v.removeOnLayoutChangeListener(this); + } + }); + } }
diff --git a/components/messages/android/java/src/org/chromium/components/messages/SingleActionMessage.java b/components/messages/android/java/src/org/chromium/components/messages/SingleActionMessage.java index cb49f66..417f9d1 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/SingleActionMessage.java +++ b/components/messages/android/java/src/org/chromium/components/messages/SingleActionMessage.java
@@ -57,11 +57,16 @@ mContainer.getResources(), mDismissHandler.bind(mModel)); } mContainer.addMessage(mView); - final Runnable onShown = () -> { + + final Runnable showRunnable = () -> mMessageBanner.show(() -> { mMessageBanner.setOnTouchRunnable(mAutoDismissTimer::resetTimer); mAutoDismissTimer.startTimer(() -> { mDismissHandler.onResult(mModel); }); - }; - mMessageBanner.show(onShown); + }); + + // Wait until the message and the container are measured before showing the message. This + // is required in case the animation set-up requires the height of the container, e.g. + // showing messages without the top controls visible. + mContainer.runAfterInitialLayout(showRunnable); } /**
diff --git a/components/onc/docs/onc_spec.md b/components/onc/docs/onc_spec.md index 8317abe..3dd4e84 100644 --- a/components/onc/docs/onc_spec.md +++ b/components/onc/docs/onc_spec.md
@@ -1372,10 +1372,6 @@ * (optional) - **boolean** * Whether cellular data connections are allowed when the device is roaming. -* **Carrier** - * (optional, read-only) - **string** - * The name of the carrier for which the device is configured. - * **ESN** * (optional, read-only) - **string** * The Electronic Serial Number of the cellular modem.
diff --git a/components/onc/onc_constants.cc b/components/onc/onc_constants.cc index bc96ee9..3cc746a 100644 --- a/components/onc/onc_constants.cc +++ b/components/onc/onc_constants.cc
@@ -106,7 +106,6 @@ const char kAllowRoaming[] = "AllowRoaming"; const char kAPN[] = "APN"; const char kAPNList[] = "APNList"; -const char kCarrier[] = "Carrier"; const char kESN[] = "ESN"; const char kFamily[] = "Family"; const char kFirmwareRevision[] = "FirmwareRevision";
diff --git a/components/optimization_guide/BUILD.gn b/components/optimization_guide/BUILD.gn index ad7a2d9..9cbe500 100644 --- a/components/optimization_guide/BUILD.gn +++ b/components/optimization_guide/BUILD.gn
@@ -52,6 +52,7 @@ "optimization_guide_util.h", "optimization_metadata.cc", "optimization_metadata.h", + "optimization_target_model_observer.h", "prediction_model.cc", "prediction_model.h", "store_update_data.cc",
diff --git a/components/optimization_guide/optimization_guide_decider.h b/components/optimization_guide/optimization_guide_decider.h index 4da73d3..1072e61 100644 --- a/components/optimization_guide/optimization_guide_decider.h +++ b/components/optimization_guide/optimization_guide_decider.h
@@ -11,6 +11,7 @@ #include "base/containers/flat_map.h" #include "base/optional.h" #include "components/optimization_guide/optimization_metadata.h" +#include "components/optimization_guide/optimization_target_model_observer.h" #include "components/optimization_guide/proto/hints.pb.h" #include "components/optimization_guide/proto/models.pb.h" @@ -68,6 +69,27 @@ client_model_feature_values, OptimizationGuideTargetDecisionCallback callback) = 0; + // Adds an observer for updates to the model for |optimization_target|. + // + // It is assumed that any model retrieved this way will be passed to the + // Machine Learning Service for inference. + // + // Still being implemented - DO NOT USE YET. + virtual void AddObserverForOptimizationTargetModel( + proto::OptimizationTarget optimization_target, + OptimizationTargetModelObserver* observer) = 0; + + // Removes an observer for updates to the model for |optimization_target|. + // + // If |observer| is registered for multiple targets, |observer| must be + // removed for all targets that it is added for in order for it to be fully + // removed from receiving any calls. + // + // Still being implemented - DO NOT USE YET. + virtual void RemoveObserverForOptimizationTargetModel( + proto::OptimizationTarget optimization_target, + OptimizationTargetModelObserver* observer) = 0; + // Registers the optimization types that intend to be queried during the // session. It is expected for this to be called after the browser has been // initialized.
diff --git a/components/optimization_guide/optimization_target_model_observer.h b/components/optimization_guide/optimization_target_model_observer.h new file mode 100644 index 0000000..255407e --- /dev/null +++ b/components/optimization_guide/optimization_target_model_observer.h
@@ -0,0 +1,30 @@ +// 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 COMPONENTS_OPTIMIZATION_GUIDE_OPTIMIZATION_TARGET_MODEL_OBSERVER_H_ +#define COMPONENTS_OPTIMIZATION_GUIDE_OPTIMIZATION_TARGET_MODEL_OBSERVER_H_ + +#include "base/files/file_path.h" +#include "base/observer_list_types.h" +#include "components/optimization_guide/proto/models.pb.h" + +namespace optimization_guide { + +// Observes |optimization_guide::OptimizationGuideDecider| for updates to models +// for a particular optimization target. +class OptimizationTargetModelObserver : public base::CheckedObserver { + public: + // Invoked when a model for |optimization_target| has been updated. It is + // guaranteed that this method will only be invoked for targets that |this| + // is added as an observer for. + // + // When this observer is first added, it will call this function with the + // file path it already has on device, if applicable. + virtual void OnModelFileUpdated(proto::OptimizationTarget optimization_target, + const base::FilePath& file_path) = 0; +}; + +} // namespace optimization_guide + +#endif // COMPONENTS_OPTIMIZATION_GUIDE_OPTIMIZATION_TARGET_MODEL_OBSERVER_H_
diff --git a/components/optimization_guide/test_optimization_guide_decider.cc b/components/optimization_guide/test_optimization_guide_decider.cc index f2c0617..0520bdc 100644 --- a/components/optimization_guide/test_optimization_guide_decider.cc +++ b/components/optimization_guide/test_optimization_guide_decider.cc
@@ -34,6 +34,14 @@ /*optimization_metadata=*/{}); } +void TestOptimizationGuideDecider::AddObserverForOptimizationTargetModel( + optimization_guide::proto::OptimizationTarget optimization_target, + optimization_guide::OptimizationTargetModelObserver* observer) {} + +void TestOptimizationGuideDecider::RemoveObserverForOptimizationTargetModel( + optimization_guide::proto::OptimizationTarget optimization_target, + optimization_guide::OptimizationTargetModelObserver* observer) {} + OptimizationGuideDecision TestOptimizationGuideDecider::CanApplyOptimization( const GURL& url, proto::OptimizationType optimization_type,
diff --git a/components/optimization_guide/test_optimization_guide_decider.h b/components/optimization_guide/test_optimization_guide_decider.h index de8755c..7e56d38 100644 --- a/components/optimization_guide/test_optimization_guide_decider.h +++ b/components/optimization_guide/test_optimization_guide_decider.h
@@ -29,6 +29,12 @@ const base::flat_map<proto::ClientModelFeature, float>& client_model_feature_values, OptimizationGuideTargetDecisionCallback callback) override; + void AddObserverForOptimizationTargetModel( + proto::OptimizationTarget optimization_target, + OptimizationTargetModelObserver* observer) override; + void RemoveObserverForOptimizationTargetModel( + proto::OptimizationTarget optimization_target, + OptimizationTargetModelObserver* observer) override; void RegisterOptimizationTypes( const std::vector<proto::OptimizationType>& optimization_types) override; void CanApplyOptimizationAsync(
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h index a5324df..33a689c 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.h +++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -122,10 +122,6 @@ // on the characteristics of this accessibility node. - (content::BrowserAccessibility*)actionTarget; -// Return the active descendant for this accessibility object or null if there -// is no active descendant defined or in the case of an error. -- (content::BrowserAccessibility*)activeDescendant; - // Internally-used property. @property(nonatomic, readonly) NSPoint origin;
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index d9d756a..311715e 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -1747,21 +1747,16 @@ if (![self instanceActive]) return nil; - // - // If the active descendant points to an element in a container with - // selectable children, add the "owns" relationship to point to that - // container. That's the only way activeDescendant is actually - // supported with VoiceOver. - // - - BrowserAccessibility* activeDescendant = [self activeDescendant]; + BrowserAccessibility* activeDescendant = + _owner->manager()->GetActiveDescendant(_owner); if (!activeDescendant) return nil; BrowserAccessibility* container = activeDescendant->PlatformGetParent(); while (container && - !ui::IsContainerWithSelectableChildren(container->GetRole())) + !ui::IsContainerWithSelectableChildren(container->GetRole())) { container = container->PlatformGetParent(); + } if (!container) return nil; @@ -2245,43 +2240,39 @@ - (NSArray*)selectedChildren { if (![self instanceActive]) return nil; + NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; - BrowserAccessibilityManager* manager = _owner->manager(); - BrowserAccessibility* focusedChild = manager->GetFocus(); - if (focusedChild == _owner) - focusedChild = manager->GetActiveDescendant(focusedChild); - - if (focusedChild && - (focusedChild == _owner || !focusedChild->IsDescendantOf(_owner))) - focusedChild = nullptr; - - // If it's not multiselectable, try to skip iterating over the - // children. - if (!GetState(_owner, ax::mojom::State::kMultiselectable)) { - // First try the focused child. - if (focusedChild) { + BrowserAccessibility* focusedChild = _owner->manager()->GetFocus(); + // "IsDescendantOf" also returns true when the two objects are equivalent. + if (focusedChild && focusedChild != _owner && + focusedChild->IsDescendantOf(_owner)) { + // If this container is not multi-selectable, try to skip iterating over the + // children because there could only be at most one selected child. The + // selected child should also be equivalent to the focused child, because + // selection is tethered to the focus. + if (!GetState(_owner, ax::mojom::State::kMultiselectable)) { [ret addObject:ToBrowserAccessibilityCocoa(focusedChild)]; return ret; } + + // If this container is multi-selectable and the focused child is selected, + // add the focused child in the list of selected children first, because + // this is how VoiceOver determines where to draw the focus ring around the + // active item. + if (focusedChild->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) + [ret addObject:ToBrowserAccessibilityCocoa(focusedChild)]; } - // Put the focused one first, if it's focused, as this helps VO draw the - // focus box around the active item. - if (focusedChild && - focusedChild->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) - [ret addObject:ToBrowserAccessibilityCocoa(focusedChild)]; - - // If it's multiselectable or if the previous attempts failed, - // return any children with the "selected" state, which may - // come from aria-selected. + // If this container is multi-selectable, we need to return any additional + // children (other than the focused child) with the "selected" state. If this + // container is not multi-selectable, but none of its children have the focus, + // we need to return all its children with the "selected" state. for (auto it = _owner->PlatformChildrenBegin(); it != _owner->PlatformChildrenEnd(); ++it) { BrowserAccessibility* child = it.get(); - if (child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) { - if (child == focusedChild) - continue; // Already added as first item. - else - [ret addObject:ToBrowserAccessibilityCocoa(child)]; + if (child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected) && + child != focusedChild) { + [ret addObject:ToBrowserAccessibilityCocoa(child)]; } } @@ -3903,23 +3894,18 @@ if (!ui::IsContainerWithSelectableChildren(_owner->node()->data().role)) return _owner; - if (BrowserAccessibility* activeDescendant = [self activeDescendant]) + // Active descendant takes priority over focus, because the webpage author has + // explicitly designated a different behavior for users of assistive software. + BrowserAccessibility* activeDescendant = + _owner->manager()->GetActiveDescendant(_owner); + if (activeDescendant != _owner) return activeDescendant; - BrowserAccessibility* focused = _owner->manager()->GetFocus(); - if (focused && focused->IsDescendantOf(_owner)) - return focused; + BrowserAccessibility* focus = _owner->manager()->GetFocus(); + if (focus && focus->IsDescendantOf(_owner)) + return focus; return _owner; } -// Return the active descendant for this accessibility object or null if there -// is no active descendant defined or in the case of an error. -- (BrowserAccessibility*)activeDescendant { - int activeDescendantId; - if (!_owner->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, - &activeDescendantId)) - return nullptr; - return _owner->manager()->GetFromID(activeDescendantId); -} @end
diff --git a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm index 5cd9170..03b84fa 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
@@ -593,7 +593,7 @@ <div tabindex="2" role="treeitem">2</div> </div>)HTML"); - EXPECT_TRUE(NavigateToURL(shell(), url)); + ASSERT_TRUE(NavigateToURL(shell(), url)); waiter.WaitForNotification(); BrowserAccessibility* tree = FindNode(ax::mojom::Role::kTree); @@ -601,8 +601,8 @@ [ToBrowserAccessibilityCocoa(tree) retain]); NSArray* tree_children = [cocoa_tree children]; - EXPECT_NSEQ(@"AXRow", [tree_children[0] role]); - EXPECT_NSEQ(@"AXRow", [tree_children[1] role]); + ASSERT_NSEQ(@"AXRow", [tree_children[0] role]); + ASSERT_NSEQ(@"AXRow", [tree_children[1] role]); content::RenderProcessHost* render_process_host = shell()->web_contents()->GetMainFrame()->GetProcess(); @@ -614,12 +614,12 @@ TriggerContextMenuAndGetMenuLocation(cocoa_tree, menu_filter.get()); menu_filter->Reset(); - gfx::Point item_1_point = + gfx::Point item_2_point = TriggerContextMenuAndGetMenuLocation(tree_children[1], menu_filter.get()); - ASSERT_NE(tree_point, item_1_point); + EXPECT_NE(tree_point, item_2_point); // Now focus the second child and trigger a context menu on the tree. - EXPECT_TRUE( + ASSERT_TRUE( content::ExecuteScript(shell()->web_contents(), "document.body.children[0].children[1].focus();")); WaitForAccessibilityFocusChange(); @@ -629,7 +629,7 @@ menu_filter->Reset(); gfx::Point new_point = TriggerContextMenuAndGetMenuLocation(cocoa_tree, menu_filter.get()); - ASSERT_EQ(new_point, item_1_point); + EXPECT_EQ(new_point, item_2_point); } IN_PROC_BROWSER_TEST_F(BrowserAccessibilityCocoaBrowserTest, @@ -734,8 +734,8 @@ EXPECT_EQ([second_child owner], [second_child actionTarget]); EXPECT_EQ(test.second, [second_child owner] == [parent actionTarget]); - // aria-activedescendant should take priority of focus for determining - // if an object is the action target. + // aria-activedescendant should take priority over focus for determining if + // an object is the action target. FocusAccessibilityElementAndWaitForFocusChange(first_child); EXPECT_EQ(test.second, [second_child owner] == [parent actionTarget]); }
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 3e8f736..05cec91 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -638,25 +638,25 @@ } BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendant( - BrowserAccessibility* focus) const { - if (!focus) + BrowserAccessibility* node) const { + if (!node) return nullptr; - int32_t active_descendant_id; + ui::AXNode::AXID active_descendant_id; BrowserAccessibility* active_descendant = nullptr; - if (focus->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, - &active_descendant_id)) { - active_descendant = focus->manager()->GetFromID(active_descendant_id); + if (node->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, + &active_descendant_id)) { + active_descendant = node->manager()->GetFromID(active_descendant_id); } - // When getting the active descendant, we avoid calling IsInvisibleOrIgnored - // on the node because IsInvisibleOrIgnored takes the focused object into - // account by retrieving it. We already have the focused object, thus there is - // no need to re-retrieve it. Furthermore, doing so can lead to an infinite - // loop. Therefore just check the AXNodeData. - - if (focus->GetRole() == ax::mojom::Role::kPopUpButton) { - BrowserAccessibility* child = focus->InternalGetFirstChild(); + // When getting the active descendant, we avoid calling + // BrowserAccessibility::IsInvisibleOrIgnored on the node because + // IsInvisibleOrIgnored takes the focused object into account by retrieving + // it. We already have the focused object, thus there is no need to + // re-retrieve it. Furthermore, doing so can lead to an infinite loop. + // Therefore just check the AXNodeData. + if (node->GetRole() == ax::mojom::Role::kPopUpButton) { + BrowserAccessibility* child = node->InternalGetFirstChild(); if (child && child->GetRole() == ax::mojom::Role::kMenuListPopup && !child->GetData().IsInvisibleOrIgnored()) { // The active descendant is found on the menu list popup, i.e. on the @@ -677,7 +677,7 @@ if (active_descendant && !active_descendant->GetData().IsInvisibleOrIgnored()) return active_descendant; - return focus; + return node; } bool BrowserAccessibilityManager::NativeViewHasFocus() { @@ -714,7 +714,7 @@ BrowserAccessibility* BrowserAccessibilityManager::GetFocusFromThisOrDescendantFrame() const { - int32_t focus_id = GetTreeData().focus_id; + ui::AXNode::AXID focus_id = GetTreeData().focus_id; BrowserAccessibility* obj = GetFromID(focus_id); // If nothing is focused, then the top document has the focus. if (!obj)
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index 2c1e194..d497a95 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -362,9 +362,10 @@ // descendants. BrowserAccessibility* GetFocusFromThisOrDescendantFrame() const; - // Given a focused node |focus|, returns a descendant of that node if it - // has an active descendant, otherwise returns |focus|. - BrowserAccessibility* GetActiveDescendant(BrowserAccessibility* focus) const; + // Given a node, returns a descendant of that node if the node has an active + // descendant, otherwise returns the node itself. The node does not need to be + // focused. + BrowserAccessibility* GetActiveDescendant(BrowserAccessibility* node) const; // Returns true if native focus is anywhere in this WebContents or not. bool NativeViewHasFocus();
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc index e0a751e3..c5e2399 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -15,6 +15,12 @@ namespace content { +namespace { +// The maximum number of TYPE_WINDOW_CONTENT_CHANGED events to fire in one +// atomic update before we give up and fire it on the root node instead. +constexpr int kMaxContentChangedEventsToFire = 5; +} // namespace + // static BrowserAccessibilityManager* BrowserAccessibilityManager::Create( const ui::AXTreeUpdate& initial_tree, @@ -195,9 +201,27 @@ // Always send AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED to notify // the Android system that the accessibility hierarchy rooted at this - // node has changed. - if (event_type != ui::AXEventGenerator::Event::SUBTREE_CREATED) - wcax->HandleContentChanged(android_node->unique_id()); + // node has changed. However, if there are a large number of changes + // it's too expensive to fire all of them, so we just fire one + // on the root instead. + if (event_type != ui::AXEventGenerator::Event::SUBTREE_CREATED) { + content_changed_events_++; + if (content_changed_events_ < kMaxContentChangedEventsToFire) { + // If it's less than the max event count, fire the event on the specific + // node that changed. + wcax->HandleContentChanged(android_node->unique_id()); + } else if (content_changed_events_ == kMaxContentChangedEventsToFire) { + // If it's equal to the max event count, fire the event on the + // root instead. + BrowserAccessibilityManager* root_manager = GetRootManager(); + if (root_manager) { + auto* root_node = + static_cast<BrowserAccessibilityAndroid*>(root_manager->GetRoot()); + if (root_node) + wcax->HandleContentChanged(root_node->unique_id()); + } + } + } switch (event_type) { case ui::AXEventGenerator::Event::ALERT: { @@ -499,6 +523,9 @@ ui::AXTree* tree, bool root_changed, const std::vector<ui::AXTreeObserver::Change>& changes) { + // Reset this every time we get an atomic update. + content_changed_events_ = 0; + BrowserAccessibilityManager::OnAtomicUpdateFinished(tree, root_changed, changes);
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h index 2a17563..f6e18fa 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.h +++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -134,6 +134,10 @@ // See docs for set_prune_tree_for_screen_reader, above. bool prune_tree_for_screen_reader_; + // A count of the number of TYPE_WINDOW_CONTENT_CHANGED events we've + // fired during a single atomic update. + int content_changed_events_ = 0; + DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerAndroid); };
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index 79369535..4f5c9dd 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -72,10 +72,6 @@ BrowserAccessibility* BrowserAccessibilityManagerMac::GetFocus() const { BrowserAccessibility* focus = BrowserAccessibilityManager::GetFocus(); - if (!focus) - return nullptr; - - // Otherwise, follow the active descendant. return GetActiveDescendant(focus); }
diff --git a/content/browser/font_access/font_access_manager_impl.cc b/content/browser/font_access/font_access_manager_impl.cc index b914894..107002e 100644 --- a/content/browser/font_access/font_access_manager_impl.cc +++ b/content/browser/font_access/font_access_manager_impl.cc
@@ -13,7 +13,9 @@ #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/font_access_delegate.h" #include "content/public/browser/render_process_host.h" +#include "content/public/common/content_client.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/font_access/font_enumeration_table.pb.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h" @@ -106,6 +108,49 @@ #endif } +void FontAccessManagerImpl::ChooseLocalFonts( + ChooseLocalFontsCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_CURRENTLY_ON(BrowserThread::UI); +#if !defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL) + std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented, + {}); +#else + const BindingContext& context = receivers_.current_context(); + + RenderFrameHostImpl* rfh = RenderFrameHostImpl::FromID(context.frame_id); + if (rfh == nullptr) { + std::move(callback).Run( + blink::mojom::FontEnumerationStatus::kUnexpectedError, {}); + return; + } + + // Page Visibility is required for the API to function at all. + if (rfh->visibility() == blink::mojom::FrameVisibility::kNotRendered) { + std::move(callback).Run(blink::mojom::FontEnumerationStatus::kNotVisible, + {}); + return; + } + + // Transient User Activation required before showing the chooser. + // This action will consume it. + if (!rfh->HasTransientUserActivation()) { + std::move(callback).Run( + blink::mojom::FontEnumerationStatus::kNeedsUserActivation, {}); + return; + } + rfh->frame_tree_node()->UpdateUserActivationState( + blink::mojom::UserActivationUpdateType::kConsumeTransientActivation, + blink::mojom::UserActivationNotificationType::kNone); + + FontAccessDelegate* delegate = + GetContentClient()->browser()->GetFontAccessDelegate(); + choosers_[context.frame_id] = delegate->RunChooser( + rfh, base::BindOnce(&FontAccessManagerImpl::DidChooseLocalFonts, + base::Unretained(this), std::move(callback))); +#endif +} + void FontAccessManagerImpl::FindAllFonts(FindAllFontsCallback callback) { #if !defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL) std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented, @@ -188,4 +233,18 @@ std::move(callback).Run(status, std::move(data)); } +void FontAccessManagerImpl::DidChooseLocalFonts( + ChooseLocalFontsCallback callback, + blink::mojom::FontEnumerationStatus status, + std::vector<blink::mojom::FontMetadataPtr> fonts) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // The chooser has fulfilled its purpose. It's safe to dispose of it. + const BindingContext& context = receivers_.current_context(); + int erased = choosers_.erase(context.frame_id); + DCHECK(erased == 1); + + std::move(callback).Run(std::move(status), std::move(fonts)); +} + } // namespace content
diff --git a/content/browser/font_access/font_access_manager_impl.h b/content/browser/font_access/font_access_manager_impl.h index 6d39e3d..104f947 100644 --- a/content/browser/font_access/font_access_manager_impl.h +++ b/content/browser/font_access/font_access_manager_impl.h
@@ -7,6 +7,7 @@ #include "base/sequence_checker.h" #include "content/common/content_export.h" +#include "content/public/browser/font_access_chooser.h" #include "content/public/browser/font_access_context.h" #include "content/public/browser/global_routing_id.h" #include "mojo/public/cpp/bindings/receiver_set.h" @@ -15,6 +16,28 @@ namespace content { +// The ownership hierarchy for this class is: +// +// StoragePartitionImpl (1) <- (1) FontAccessManagerImpl +// +// FontAccessManagerImpl (1) <- (*) BindingContext +// FontAccessManagerImpl (1) <- (*) FontAccessChooser +// +// BindingContext (1) <- (1) GlobalFrameRoutingId +// GlobalFrameRoutingId (1) <-- (1) FontAccessChooser +// +// Legend: +// +// <- : owns +// <-- : corresponds to +// (N) : N is a number or *, which denotes zero or more +// +// In English: +// * There's one FontAccessManagerImpl per StoragePartitionImpl +// * Frames are bound to FontAccessManangerImpl via a BindingContext +// * The FontAccessManagerImpl owns the lifetimes of FontAccessChoosers +// * There is one FontAccessChooser for each Frame via its GlobalFrameRoutingId, +// obtained from a corresponding BindingContext class CONTENT_EXPORT FontAccessManagerImpl : public blink::mojom::FontAccessManager, public FontAccessContext { @@ -40,6 +63,7 @@ // blink.mojom.FontAccessManager: void EnumerateLocalFonts(EnumerateLocalFontsCallback callback) override; + void ChooseLocalFonts(ChooseLocalFontsCallback callback) override; // content::FontAccessContext: void FindAllFonts(FindAllFontsCallback callback) override; @@ -54,6 +78,9 @@ void DidFindAllFonts(FindAllFontsCallback callback, blink::mojom::FontEnumerationStatus, base::ReadOnlySharedMemoryRegion); + void DidChooseLocalFonts(ChooseLocalFontsCallback callback, + blink::mojom::FontEnumerationStatus status, + std::vector<blink::mojom::FontMetadataPtr> fonts); // Registered clients. mojo::ReceiverSet<blink::mojom::FontAccessManager, BindingContext> receivers_; @@ -63,6 +90,9 @@ bool skip_privacy_checks_for_testing_ = false; + // Here to keep the choosers alive for the user to interact with. + std::map<GlobalFrameRoutingId, std::unique_ptr<FontAccessChooser>> choosers_; + SEQUENCE_CHECKER(sequence_checker_); };
diff --git a/content/browser/speech/tts_controller_impl.cc b/content/browser/speech/tts_controller_impl.cc index 9c190bd..8715e8e 100644 --- a/content/browser/speech/tts_controller_impl.cc +++ b/content/browser/speech/tts_controller_impl.cc
@@ -129,11 +129,15 @@ return; } - // If the TTS platform is still loading, queue or flush the utterance. The - // utterances can be sent to platform specific implementation or to the - // engine implementation. Every utterances are postponed until the platform - // specific implementation is loaded to avoid racy behaviors. - if (TtsPlatformLoading()) { + // If the TTS platform or tts engine delegate is still loading or + // initializing, queue or flush the utterance. The utterances can be sent to + // platform specific implementation or to the engine implementation. Every + // utterances are postponed until the platform specific implementation and + // built in tts engine are loaded to avoid races where the utterance gets + // dropped unexpectedly. + if (TtsPlatformLoading() || + (engine_delegate_ && !engine_delegate_->IsBuiltInTtsEngineInitialized( + utterance->GetBrowserContext()))) { if (utterance->GetShouldClearQueue()) ClearUtteranceQueue(true);
diff --git a/content/browser/speech/tts_controller_unittest.cc b/content/browser/speech/tts_controller_unittest.cc index 725d2c0d..31dd5bc 100644 --- a/content/browser/speech/tts_controller_unittest.cc +++ b/content/browser/speech/tts_controller_unittest.cc
@@ -8,6 +8,7 @@ #include "base/memory/ptr_util.h" #include "base/values.h" +#include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "content/browser/speech/tts_utterance_impl.h" #include "content/public/browser/tts_platform.h" @@ -107,6 +108,45 @@ base::OnceCallback<void(bool)> did_start_speaking_callback_; }; +class MockTtsEngineDelegate : public TtsEngineDelegate { + public: + int utterance_id() { return utterance_id_; } + + void set_is_built_in_tts_engine_initialized(bool value) { + is_built_in_tts_engine_initialized_ = value; + } + + void set_voices(const std::vector<VoiceData>& voices) { voices_ = voices; } + + // TtsEngineDelegate: + void Speak(TtsUtterance* utterance, const VoiceData& voice) override { + utterance_id_ = utterance->GetId(); + } + + bool LoadBuiltInTtsEngine(BrowserContext* browser_context) override { + return true; + } + + bool IsBuiltInTtsEngineInitialized(BrowserContext* browser_context) override { + return is_built_in_tts_engine_initialized_; + } + + void GetVoices(BrowserContext* browser_context, + std::vector<VoiceData>* out_voices) override { + *out_voices = voices_; + } + + // Unused (TtsEngineDelegate:) + void Stop(TtsUtterance* utterance) override {} + void Pause(TtsUtterance* utterance) override {} + void Resume(TtsUtterance* utterance) override {} + + private: + bool is_built_in_tts_engine_initialized_ = true; + int utterance_id_ = -1; + std::vector<VoiceData> voices_; +}; + #if BUILDFLAG(IS_CHROMEOS_ASH) class MockTtsControllerDelegate : public TtsControllerDelegate { public: @@ -173,6 +213,11 @@ platform_impl_ = std::make_unique<MockTtsPlatformImpl>(controller_.get()); browser_context_ = std::make_unique<TestBrowserContext>(); controller()->SetTtsPlatform(platform_impl_.get()); +#if !defined(OS_ANDROID) + // TtsEngineDelegate isn't set for Android in ChromeContentBrowserClient + // since it has no extensions. + controller()->SetTtsEngineDelegate(&engine_delegate_); +#endif // !defined(OS_ANDROID) #if BUILDFLAG(IS_CHROMEOS_ASH) controller()->SetTtsControllerDelegateForTesting(&delegate_); #endif @@ -187,6 +232,7 @@ MockTtsPlatformImpl* platform_impl() { return platform_impl_.get(); } TestTtsControllerImpl* controller() { return controller_.get(); } TestBrowserContext* browser_context() { return browser_context_.get(); } + MockTtsEngineDelegate* engine_delegate() { return &engine_delegate_; } #if BUILDFLAG(IS_CHROMEOS_ASH) MockTtsControllerDelegate* delegate() { return &delegate_; } @@ -225,6 +271,7 @@ std::unique_ptr<TestTtsControllerImpl> controller_; std::unique_ptr<MockTtsPlatformImpl> platform_impl_; std::unique_ptr<TestBrowserContext> browser_context_; + MockTtsEngineDelegate engine_delegate_; #if BUILDFLAG(IS_CHROMEOS_ASH) MockTtsControllerDelegate delegate_; #endif @@ -791,7 +838,7 @@ EXPECT_EQ(0, platform_impl()->stop_speaking_called()); } -TEST_F(TtsControllerTest, SpeakWhenLoading) { +TEST_F(TtsControllerTest, SpeakWhenLoadingPlatformImpl) { platform_impl()->SetPlatformImplInitialized(false); std::unique_ptr<WebContents> web_contents = CreateWebContents(); @@ -821,4 +868,47 @@ EXPECT_FALSE(controller()->IsSpeaking()); } +#if !defined(OS_ANDROID) +TEST_F(TtsControllerTest, SpeakWhenLoadingBuiltInEngine) { + engine_delegate()->set_is_built_in_tts_engine_initialized(false); + + std::vector<VoiceData> voices; + VoiceData voice_data; + voice_data.engine_id = "x"; + voice_data.events.insert(TTS_EVENT_START); + voice_data.events.insert(TTS_EVENT_END); + voices.push_back(voice_data); + engine_delegate()->set_voices(voices); + + std::unique_ptr<WebContents> web_contents = CreateWebContents(); + std::unique_ptr<TtsUtteranceImpl> utterance = + CreateUtteranceImpl(web_contents.get()); + utterance->SetShouldClearQueue(false); + + // Speak an utterance while the built in engine is initializing, the utterance + // should be queued. + controller()->SpeakOrEnqueue(std::move(utterance)); + EXPECT_FALSE(IsUtteranceListEmpty()); + EXPECT_FALSE(TtsControllerCurrentUtterance()); + + // Simulate the completion of the initialisation. + engine_delegate()->set_is_built_in_tts_engine_initialized(true); + controller()->VoicesChanged(); + + int utterance_id = engine_delegate()->utterance_id(); + controller()->OnTtsEvent(utterance_id, content::TTS_EVENT_START, 0, 0, + std::string()); + EXPECT_TRUE(IsUtteranceListEmpty()); + EXPECT_TRUE(TtsControllerCurrentUtterance()); + EXPECT_TRUE(controller()->IsSpeaking()); + + // Complete the playing utterance. + controller()->OnTtsEvent(utterance_id, content::TTS_EVENT_END, 0, 0, + std::string()); + EXPECT_TRUE(IsUtteranceListEmpty()); + EXPECT_FALSE(TtsControllerCurrentUtterance()); + EXPECT_FALSE(controller()->IsSpeaking()); +} +#endif // !defined(OS_ANDROID) + } // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 3587e6a6..718f4c2 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -177,6 +177,7 @@ #include "ui/aura/window.h" #endif #include "ui/base/layout.h" +#include "ui/base/pointer/pointer_device.h" #include "ui/base/ui_base_features.h" #include "ui/base/ui_base_switches.h" #include "ui/display/screen.h" @@ -2574,8 +2575,8 @@ ui::GetAvailablePointerAndHoverTypes(); prefs->primary_pointer_type = static_cast<blink::mojom::PointerType>( ui::GetPrimaryPointerType(prefs->available_pointer_types)); - prefs->primary_hover_type = - ui::GetPrimaryHoverType(prefs->available_hover_types); + prefs->primary_hover_type = static_cast<blink::mojom::HoverType>( + ui::GetPrimaryHoverType(prefs->available_hover_types)); prefs->pointer_events_max_touch_points = ui::MaxTouchPoints();
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index 4c747ea..c6868a6 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -6330,6 +6330,7 @@ auto discovery = std::make_unique<device::cablev2::Discovery>( network_context_.get(), qr_generator_key_, /*pairings=*/std::vector<std::unique_ptr<device::cablev2::Pairing>>(), + /*extension_contents=*/std::vector<device::CableDiscoveryData>(), GetPairingCallback()); auto* const discovery_ptr = discovery.get(); @@ -6354,6 +6355,7 @@ auto discovery = std::make_unique<device::cablev2::Discovery>( network_context_.get(), qr_generator_key_, /*pairings=*/std::vector<std::unique_ptr<device::cablev2::Pairing>>(), + /*extension_contents=*/std::vector<device::CableDiscoveryData>(), GetPairingCallback()); auto* discovery_ptr = discovery.get(); @@ -6375,6 +6377,7 @@ // Now do a pairing-based exchange. discovery = std::make_unique<device::cablev2::Discovery>( network_context_.get(), qr_generator_key_, std::move(pairings_), + /*extension_contents=*/std::vector<device::CableDiscoveryData>(), GetPairingCallback()); discovery_ptr = discovery.get(); @@ -6429,6 +6432,7 @@ auto network_context = device::cablev2::NewMockTunnelServer(base::nullopt); auto discovery = std::make_unique<device::cablev2::Discovery>( network_context.get(), qr_generator_key_, std::move(pairings), + /*extension_contents=*/std::vector<device::CableDiscoveryData>(), GetPairingCallback()); AuthenticatorEnvironmentImpl::GetInstance()
diff --git a/content/browser/webauth/authenticator_mojom_traits.cc b/content/browser/webauth/authenticator_mojom_traits.cc index e4d78b8..01c78d6 100644 --- a/content/browser/webauth/authenticator_mojom_traits.cc +++ b/content/browser/webauth/authenticator_mojom_traits.cc
@@ -310,16 +310,41 @@ device::CableDiscoveryData>:: Read(blink::mojom::CableAuthenticationDataView data, device::CableDiscoveryData* out) { - if (data.version() != 1) { - return false; + switch (data.version()) { + case 1: { + base::Optional<std::array<uint8_t, 16>> client_eid, authenticator_eid; + base::Optional<std::array<uint8_t, 32>> session_pre_key; + if (!data.ReadClientEid(&client_eid) || !client_eid || + !data.ReadAuthenticatorEid(&authenticator_eid) || + !authenticator_eid || !data.ReadSessionPreKey(&session_pre_key) || + !session_pre_key) { + return false; + } + + out->version = device::CableDiscoveryData::Version::V1; + out->v1.emplace(); + out->v1->client_eid = *client_eid; + out->v1->authenticator_eid = *authenticator_eid; + out->v1->session_pre_key = *session_pre_key; + break; + } + + case 2: { + base::Optional<std::vector<uint8_t>> server_link_data; + if (!data.ReadServerLinkData(&server_link_data) || !server_link_data) { + return false; + } + + out->version = device::CableDiscoveryData::Version::V2; + out->v2.emplace(std::move(*server_link_data)); + + break; + } + + default: + return false; } - out->version = device::CableDiscoveryData::Version::V1; - out->v1.emplace(); - if (!data.ReadClientEid(&out->v1->client_eid) || - !data.ReadAuthenticatorEid(&out->v1->authenticator_eid) || - !data.ReadSessionPreKey(&out->v1->session_pre_key)) { - return false; - } + return true; }
diff --git a/content/browser/webauth/authenticator_mojom_traits.h b/content/browser/webauth/authenticator_mojom_traits.h index f22a501..bbd07be 100644 --- a/content/browser/webauth/authenticator_mojom_traits.h +++ b/content/browser/webauth/authenticator_mojom_traits.h
@@ -203,26 +203,47 @@ StructTraits<blink::mojom::CableAuthenticationDataView, device::CableDiscoveryData> { static uint8_t version(const device::CableDiscoveryData& in) { - CHECK_EQ(device::CableDiscoveryData::Version::V1, in.version); - return 1; + switch (in.version) { + case device::CableDiscoveryData::Version::V1: + return 1; + case device::CableDiscoveryData::Version::V2: + return 2; + case device::CableDiscoveryData::Version::INVALID: + CHECK(false); + return 0; + } } - static const device::CableEidArray& client_eid( + static base::Optional<device::CableEidArray> client_eid( const device::CableDiscoveryData& in) { - CHECK_EQ(device::CableDiscoveryData::Version::V1, in.version); - return in.v1->client_eid; + if (in.version == device::CableDiscoveryData::Version::V1) { + return in.v1->client_eid; + } + return base::nullopt; } - static const device::CableEidArray& authenticator_eid( + static const base::Optional<device::CableEidArray> authenticator_eid( const device::CableDiscoveryData& in) { - CHECK_EQ(device::CableDiscoveryData::Version::V1, in.version); - return in.v1->authenticator_eid; + if (in.version == device::CableDiscoveryData::Version::V1) { + return in.v1->authenticator_eid; + } + return base::nullopt; } - static const device::CableSessionPreKeyArray& session_pre_key( + static const base::Optional<device::CableSessionPreKeyArray> session_pre_key( const device::CableDiscoveryData& in) { - CHECK_EQ(device::CableDiscoveryData::Version::V1, in.version); - return in.v1->session_pre_key; + if (in.version == device::CableDiscoveryData::Version::V1) { + return in.v1->session_pre_key; + } + return base::nullopt; + } + + static const base::Optional<std::vector<uint8_t>> server_link_data( + const device::CableDiscoveryData& in) { + if (in.version == device::CableDiscoveryData::Version::V2) { + return *in.v2; + } + return base::nullopt; } static bool Read(blink::mojom::CableAuthenticationDataView data,
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index 8132c83..87bd663 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -153,7 +153,9 @@ "file_select_listener.h", "file_url_loader.h", "focused_node_details.h", + "font_access_chooser.h", "font_access_context.h", + "font_access_delegate.h", "font_list_async.h", "frame_accept_header.cc", "frame_accept_header.h",
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 418501e..281a1aa0 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -891,6 +891,10 @@ return nullptr; } +FontAccessDelegate* ContentBrowserClient::GetFontAccessDelegate() { + return nullptr; +} + bool ContentBrowserClient::ShowPaymentHandlerWindow( content::BrowserContext* browser_context, const GURL& url,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index a4dee7b..d4b02c6 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -196,6 +196,7 @@ class ControllerPresentationServiceDelegate; class DevToolsManagerDelegate; class FeatureObserverClient; +class FontAccessDelegate; class HidDelegate; class LoginDelegate; class MediaObserver; @@ -1578,6 +1579,10 @@ // Allows the embedder to provide an implementation of the Web Bluetooth API. virtual BluetoothDelegate* GetBluetoothDelegate(); + // Allows the embedder to provide an implementation of the Local Font Access + // API. + virtual FontAccessDelegate* GetFontAccessDelegate(); + // Attempt to open the Payment Handler window inside its corresponding // PaymentRequest UI surface. Returns true if the ContentBrowserClient // implementation supports this operation (desktop Chrome) or false otherwise.
diff --git a/content/public/browser/font_access_chooser.h b/content/public/browser/font_access_chooser.h new file mode 100644 index 0000000..8e77f3e --- /dev/null +++ b/content/public/browser/font_access_chooser.h
@@ -0,0 +1,29 @@ +// 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 CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CHOOSER_H_ +#define CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CHOOSER_H_ + +#include "base/callback_forward.h" +#include "content/common/content_export.h" +#include "content/public/browser/render_frame_host.h" +#include "third_party/blink/public/mojom/font_access/font_access.mojom.h" + +namespace content { + +class CONTENT_EXPORT FontAccessChooser { + public: + using Callback = + base::OnceCallback<void(blink::mojom::FontEnumerationStatus, + std::vector<blink::mojom::FontMetadataPtr>)>; + FontAccessChooser() = default; + virtual ~FontAccessChooser() = default; + + FontAccessChooser(const FontAccessChooser&) = delete; + FontAccessChooser operator=(const FontAccessChooser&) = delete; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_FONT_ACCESS_CHOOSER_H_
diff --git a/content/public/browser/font_access_delegate.h b/content/public/browser/font_access_delegate.h new file mode 100644 index 0000000..37d9e66 --- /dev/null +++ b/content/public/browser/font_access_delegate.h
@@ -0,0 +1,26 @@ +// 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 CONTENT_PUBLIC_BROWSER_FONT_ACCESS_DELEGATE_H_ +#define CONTENT_PUBLIC_BROWSER_FONT_ACCESS_DELEGATE_H_ + +#include "content/common/content_export.h" +#include "content/public/browser/font_access_chooser.h" + +namespace content { + +class RenderFrameHost; + +class CONTENT_EXPORT FontAccessDelegate { + public: + virtual ~FontAccessDelegate() = default; + + virtual std::unique_ptr<FontAccessChooser> RunChooser( + RenderFrameHost* frame, + FontAccessChooser::Callback callback) = 0; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_FONT_ACCESS_DELEGATE_H_
diff --git a/content/public/browser/tts_controller.h b/content/public/browser/tts_controller.h index 04934c6..4acb517 100644 --- a/content/public/browser/tts_controller.h +++ b/content/public/browser/tts_controller.h
@@ -67,6 +67,10 @@ // Load the built-in TTS engine. virtual bool LoadBuiltInTtsEngine(BrowserContext* browser_context) = 0; + + // Returns whether the built in engine is initialized. + virtual bool IsBuiltInTtsEngineInitialized( + BrowserContext* browser_context) = 0; }; // Class that wants to be notified when the set of
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 112814b..6eb6475 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -432,7 +432,7 @@ // Note that the origin policy-based variant of origin isolation is controlled // by kOriginPolicy, instead. const base::Feature kOriginIsolationHeader{"OriginIsolationHeader", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; // Origin Policy. See https://crbug.com/751996 const base::Feature kOriginPolicy{"OriginPolicy",
diff --git a/content/test/fuzzer/OWNERS b/content/test/fuzzer/OWNERS index 054ad6e..bd29a9e 100644 --- a/content/test/fuzzer/OWNERS +++ b/content/test/fuzzer/OWNERS
@@ -1,3 +1,2 @@ -mmoroz@chromium.org ochang@chromium.org metzman@chromium.org
diff --git a/device/fido/cable/cable_discovery_data.cc b/device/fido/cable/cable_discovery_data.cc index 71dffdc4..b5da2a06 100644 --- a/device/fido/cable/cable_discovery_data.cc +++ b/device/fido/cable/cable_discovery_data.cc
@@ -54,6 +54,9 @@ v1->authenticator_eid == other.v1->authenticator_eid && v1->session_pre_key == other.v1->session_pre_key; + case CableDiscoveryData::Version::V2: + return v2.value() == other.v2.value(); + case CableDiscoveryData::Version::INVALID: CHECK(false); return false;
diff --git a/device/fido/cable/cable_discovery_data.h b/device/fido/cable/cable_discovery_data.h index e494672..fcee5db 100644 --- a/device/fido/cable/cable_discovery_data.h +++ b/device/fido/cable/cable_discovery_data.h
@@ -51,6 +51,7 @@ enum class Version { INVALID, V1, + V2, }; CableDiscoveryData(Version version, @@ -79,6 +80,10 @@ CableSessionPreKeyArray session_pre_key; }; base::Optional<V1Data> v1; + + // For caBLEv2, the payload is the server-link data provided in the extension + // as the "sessionPreKey". + base::Optional<std::vector<uint8_t>> v2; }; namespace cablev2 {
diff --git a/device/fido/cable/fido_cable_discovery.cc b/device/fido/cable/fido_cable_discovery.cc index 219f89f..1f05454c 100644 --- a/device/fido/cable/fido_cable_discovery.cc +++ b/device/fido/cable/fido_cable_discovery.cc
@@ -201,6 +201,7 @@ device, nonce, discovery_data.v1->session_pre_key); } + case CableDiscoveryData::Version::V2: case CableDiscoveryData::Version::INVALID: CHECK(false); return nullptr;
diff --git a/device/fido/cable/v2_discovery.cc b/device/fido/cable/v2_discovery.cc index 7fb8d6a..a7cf4b9 100644 --- a/device/fido/cable/v2_discovery.cc +++ b/device/fido/cable/v2_discovery.cc
@@ -19,21 +19,14 @@ Discovery::Discovery(network::mojom::NetworkContext* network_context, base::span<const uint8_t, kQRKeySize> qr_generator_key, std::vector<std::unique_ptr<Pairing>> pairings, + const std::vector<CableDiscoveryData>& extension_contents, base::Optional<base::RepeatingCallback<void(PairingEvent)>> pairing_callback) : FidoDeviceDiscovery( FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy), network_context_(network_context), - local_identity_seed_(fido_parsing_utils::Materialize( - base::span<const uint8_t, kQRSeedSize>(qr_generator_key.data(), - kQRSeedSize))), - qr_secret_(fido_parsing_utils::Materialize( - base::span<const uint8_t, kQRSecretSize>( - qr_generator_key.data() + kQRSeedSize, - kQRSecretSize))), - eid_key_(Derive<EXTENT(eid_key_)>(qr_secret_, - base::span<const uint8_t>(), - DerivedValueType::kEIDKey)), + qr_keys_(KeysFromQRGeneratorKey(qr_generator_key)), + extension_keys_(KeysFromExtension(extension_contents)), pairings_(std::move(pairings)), pairing_callback_(std::move(pairing_callback)) { static_assert(EXTENT(qr_generator_key) == kQRSecretSize + kQRSeedSize, ""); @@ -93,16 +86,30 @@ } // Check whether the EID matches a QR code. - base::Optional<CableEidArray> plaintext = eid::Decrypt(advert, eid_key_); + base::Optional<CableEidArray> plaintext = + eid::Decrypt(advert, qr_keys_.eid_key); if (plaintext) { FIDO_LOG(DEBUG) << " (" << base::HexEncode(advert) << " matches QR code)"; AddDevice(std::make_unique<cablev2::FidoTunnelDevice>( network_context_, base::BindOnce(&Discovery::AddPairing, weak_factory_.GetWeakPtr()), - qr_secret_, local_identity_seed_, *plaintext)); + qr_keys_.qr_secret, qr_keys_.local_identity_seed, *plaintext)); return; } + // Check whether the EID matches the extension. + if (extension_keys_) { + plaintext = eid::Decrypt(advert, extension_keys_->eid_key); + if (plaintext) { + FIDO_LOG(DEBUG) << " (" << base::HexEncode(advert) + << " matches extension)"; + AddDevice(std::make_unique<cablev2::FidoTunnelDevice>( + network_context_, base::DoNothing(), extension_keys_->qr_secret, + extension_keys_->local_identity_seed, *plaintext)); + return; + } + } + FIDO_LOG(DEBUG) << " (" << base::HexEncode(advert) << ": no v2 match)"; } @@ -123,5 +130,39 @@ pairing_callback_->Run(std::move(peer_public_key_x962)); } +// static +Discovery::UnpairedKeys Discovery::KeysFromQRGeneratorKey( + base::span<const uint8_t, kQRKeySize> qr_generator_key) { + UnpairedKeys ret; + static_assert(EXTENT(qr_generator_key) == kQRSeedSize + kQRSecretSize, ""); + ret.local_identity_seed = fido_parsing_utils::Materialize( + qr_generator_key.subspan<0, kQRSeedSize>()); + ret.qr_secret = fido_parsing_utils::Materialize( + qr_generator_key.subspan<kQRSeedSize, kQRSecretSize>()); + ret.eid_key = Derive<EXTENT(ret.eid_key)>( + ret.qr_secret, base::span<const uint8_t>(), DerivedValueType::kEIDKey); + return ret; +} + +// static +base::Optional<Discovery::UnpairedKeys> Discovery::KeysFromExtension( + const std::vector<CableDiscoveryData>& extension_contents) { + for (auto const& data : extension_contents) { + if (data.version != CableDiscoveryData::Version::V2) { + continue; + } + + if (data.v2->size() != kQRKeySize) { + FIDO_LOG(ERROR) << "caBLEv2 extension has incorrect length (" + << data.v2->size() << ")"; + continue; + } + + return KeysFromQRGeneratorKey(base::make_span<kQRKeySize>(*data.v2)); + } + + return base::nullopt; +} + } // namespace cablev2 } // namespace device
diff --git a/device/fido/cable/v2_discovery.h b/device/fido/cable/v2_discovery.h index e2c4851..c0042c9 100644 --- a/device/fido/cable/v2_discovery.h +++ b/device/fido/cable/v2_discovery.h
@@ -36,6 +36,7 @@ Discovery(network::mojom::NetworkContext* network_context, base::span<const uint8_t, kQRKeySize> qr_generator_key, std::vector<std::unique_ptr<Pairing>> pairings, + const std::vector<CableDiscoveryData>& extension_contents, // pairing_callback will be called when a QR-initiated connection // receives pairing information from the peer, or when an existing // pairing is found to be invalid. @@ -52,14 +53,25 @@ void OnBLEAdvertSeen(const std::array<uint8_t, kAdvertSize>& advert) override; private: + // UnpairedKeys are keys that are conveyed by QR code or that come from the + // server, i.e. keys that enable interactions with unpaired phones. + struct UnpairedKeys { + std::array<uint8_t, kQRSeedSize> local_identity_seed; + std::array<uint8_t, kQRSecretSize> qr_secret; + std::array<uint8_t, kEIDKeySize> eid_key; + }; + void AddPairing(std::unique_ptr<Pairing> pairing); void PairingIsInvalid( std::array<uint8_t, kP256X962Length> peer_public_key_x962); + static UnpairedKeys KeysFromQRGeneratorKey( + base::span<const uint8_t, kQRKeySize> qr_generator_key); + static base::Optional<UnpairedKeys> KeysFromExtension( + const std::vector<CableDiscoveryData>& extension_contents); network::mojom::NetworkContext* const network_context_; - const std::array<uint8_t, kQRSeedSize> local_identity_seed_; - const std::array<uint8_t, kQRSecretSize> qr_secret_; - const std::array<uint8_t, kEIDKeySize> eid_key_; + const UnpairedKeys qr_keys_; + const base::Optional<UnpairedKeys> extension_keys_; std::vector<std::unique_ptr<Pairing>> pairings_; const base::Optional<base::RepeatingCallback<void(PairingEvent)>> pairing_callback_;
diff --git a/device/fido/features.cc b/device/fido/features.cc index 91a1e99..cb933df 100644 --- a/device/fido/features.cc +++ b/device/fido/features.cc
@@ -25,6 +25,10 @@ extern const base::Feature kWebAuthPhoneSupport{ "WebAuthenticationPhoneSupport", base::FEATURE_DISABLED_BY_DEFAULT}; +extern const base::Feature kWebAuthCableExtensionAnywhere{ + "WebAuthenticationCableExtensionAnywhere", + base::FEATURE_DISABLED_BY_DEFAULT}; + extern const base::Feature kWebAuthGetAssertionFeaturePolicy{ "WebAuthenticationGetAssertionFeaturePolicy", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/device/fido/features.h b/device/fido/features.h index a3c8844..9e7d1d6 100644 --- a/device/fido/features.h +++ b/device/fido/features.h
@@ -32,6 +32,10 @@ COMPONENT_EXPORT(DEVICE_FIDO) extern const base::Feature kWebAuthPhoneSupport; +// Support the caBLE extension in assertion requests from any origin. +COMPONENT_EXPORT(DEVICE_FIDO) +extern const base::Feature kWebAuthCableExtensionAnywhere; + // Enable WebAuthn GetAssertion calls in cross-origin iframes if allowed by // Feature Policy. COMPONENT_EXPORT(DEVICE_FIDO)
diff --git a/device/fido/fido_discovery_factory.cc b/device/fido/fido_discovery_factory.cc index e839a103..24170ed 100644 --- a/device/fido/fido_discovery_factory.cc +++ b/device/fido/fido_discovery_factory.cc
@@ -52,6 +52,7 @@ if (qr_generator_key_.has_value()) { v2_discovery = std::make_unique<cablev2::Discovery>( network_context_, *qr_generator_key_, std::move(v2_pairings_), + cable_data_.value_or(std::vector<CableDiscoveryData>()), std::move(cable_pairing_callback_)); } std::unique_ptr<FidoDiscoveryBase> v1_discovery =
diff --git a/device/vr/openxr/openxr_interaction_profiles.h b/device/vr/openxr/openxr_interaction_profiles.h index 6222870..33aa2e4a 100644 --- a/device/vr/openxr/openxr_interaction_profiles.h +++ b/device/vr/openxr/openxr_interaction_profiles.h
@@ -28,7 +28,7 @@ kHTCVive = 4, kSamsungOdyssey = 5, kHPReverbG2 = 6, - kHandSelect = 7, + kHandSelectGrasp = 7, kCount = 8, }; @@ -119,8 +119,8 @@ constexpr const char* kHPReverbG2InputProfiles[] = { "hp-mixed-reality", "oculus-touch", "generic-trigger-squeeze"}; -constexpr const char* kGenericHandSelectInputProfile[] = { - "generic-hand-select"}; +constexpr const char* kGenericHandSelectGraspInputProfile[] = { + "generic-hand-select-grasp", "generic-hand-select"}; constexpr OpenXrButtonPathMap kMicrosoftMotionControllerButtonPathMaps[] = { {OpenXrButtonType::kTrigger, @@ -279,10 +279,13 @@ 1}, }; -constexpr OpenXrButtonPathMap kGenericHandSelectButtonPathMaps[] = { +constexpr OpenXrButtonPathMap kGenericHandSelectGraspButtonPathMaps[] = { {OpenXrButtonType::kTrigger, {{OpenXrButtonActionType::kValue, "/input/select/value"}}, 1}, + {OpenXrButtonType::kTrigger, + {{OpenXrButtonActionType::kValue, "/input/squeeze/value"}}, + 1}, }; constexpr OpenXrAxisPathMap kMicrosoftMotionControllerAxisPathMaps[] = { @@ -408,16 +411,16 @@ constexpr OpenXrControllerInteractionProfile kHandInteractionMSFTInteractionProfile = { - OpenXrInteractionProfileType::kHandSelect, + OpenXrInteractionProfileType::kHandSelectGrasp, "/interaction_profiles/microsoft/hand_interaction", kMSFTHandInteractionExtensionName, GamepadMapping::kNone, - kGenericHandSelectInputProfile, - base::size(kGenericHandSelectInputProfile), - kGenericHandSelectButtonPathMaps, - base::size(kGenericHandSelectButtonPathMaps), - kGenericHandSelectButtonPathMaps, - base::size(kGenericHandSelectButtonPathMaps), + kGenericHandSelectGraspInputProfile, + base::size(kGenericHandSelectGraspInputProfile), + kGenericHandSelectGraspButtonPathMaps, + base::size(kGenericHandSelectGraspButtonPathMaps), + kGenericHandSelectGraspButtonPathMaps, + base::size(kGenericHandSelectGraspButtonPathMaps), nullptr, 0};
diff --git a/docs/how_to_add_your_feature_flag.md b/docs/how_to_add_your_feature_flag.md index 4ca8af89..07c7ef8d 100644 --- a/docs/how_to_add_your_feature_flag.md +++ b/docs/how_to_add_your_feature_flag.md
@@ -22,7 +22,7 @@ [[2](https://chromium-review.googlesource.com/c/554510/8/content/public/common/content_features.h)] 2. how to use it [[1](https://chromium-review.googlesource.com/c/554510/8/content/common/service_worker/service_worker_utils.cc#153)] -3. how to wire your new base::Feature to a blink runtime feature[[1](https://chromium.googlesource.com/chromium/src/+/HEAD/content/child/InitializeBlinkFeatures.md)] +3. how to wire your new base::Feature to a blink runtime feature[[1](https://chromium.googlesource.com/chromium/src/+/master/docs/initialize_blink_features.md)] 4. how to use it in blink [[1](https://chromium-review.googlesource.com/c/554510/8/third_party/blnk/renderere/core/workers/worker_thread.cc)]
diff --git a/docs/security/OWNERS b/docs/security/OWNERS index a862375..57ae617 100644 --- a/docs/security/OWNERS +++ b/docs/security/OWNERS
@@ -3,7 +3,6 @@ dcheng@chromium.org estark@chromium.org felt@chromium.org -mmoroz@chromium.org nasko@chromium.org meacer@chromium.org mkwst@chromium.org @@ -11,4 +10,4 @@ parisa@chromium.org rsesek@chromium.org tsepez@chromium.org -vakh@chromium.org \ No newline at end of file +vakh@chromium.org
diff --git a/docs/speed/perf_lab_platforms.md b/docs/speed/perf_lab_platforms.md index 72c441f..e251c69 100644 --- a/docs/speed/perf_lab_platforms.md +++ b/docs/speed/perf_lab_platforms.md
@@ -24,7 +24,6 @@ * [mac-10_12_laptop_low_end-perf](https://ci.chromium.org/p/chrome/builders/ci/mac-10_12_laptop_low_end-perf): MacBook Air, Core i5 1.8 GHz, 8GB RAM, 128GB SSD, HD Graphics. * [mac-10_13_laptop_high_end-perf](https://ci.chromium.org/p/chrome/builders/ci/mac-10_13_laptop_high_end-perf): MacBook Pro, Core i7 2.8 GHz, 16GB RAM, 256GB SSD, Radeon 55. * [mac-arm_dtk_arm-perf](https://ci.chromium.org/p/chrome/builders/ci/mac-arm_dtk_arm-perf): Mac ARM DTK (ARM Chrome). - * [mac-arm_dtk_x86-perf](https://ci.chromium.org/p/chrome/builders/ci/mac-arm_dtk_x86-perf): Mac ARM DTK (X86 Chrome). ## Win
diff --git a/extensions/browser/renderer_startup_helper.cc b/extensions/browser/renderer_startup_helper.cc index d43f688..28b058f 100644 --- a/extensions/browser/renderer_startup_helper.cc +++ b/extensions/browser/renderer_startup_helper.cc
@@ -122,9 +122,8 @@ // renderers may have content scripts. bool is_lock_screen_context = client->IsLockScreenContext(process->GetBrowserContext()); - process->Send(new ExtensionMsg_SetSessionInfo(GetCurrentChannel(), - GetCurrentFeatureSessionType(), - is_lock_screen_context)); + renderer->SetSessionInfo(GetCurrentChannel(), GetCurrentFeatureSessionType(), + is_lock_screen_context); // Platform apps need to know the system font. // TODO(dbeam): this is not the system font in all cases.
diff --git a/extensions/browser/renderer_startup_helper_unittest.cc b/extensions/browser/renderer_startup_helper_unittest.cc index 6ee2f58..574e672 100644 --- a/extensions/browser/renderer_startup_helper_unittest.cc +++ b/extensions/browser/renderer_startup_helper_unittest.cc
@@ -51,6 +51,10 @@ unloaded_extensions_.push_back(extension_id); } + void SetSessionInfo(version_info::Channel channel, + mojom::FeatureSessionType session, + bool is_lock_screen_context) override {} + std::vector<std::string> activated_extensions_; std::vector<std::string> unloaded_extensions_; mojo::AssociatedReceiverSet<mojom::Renderer> receivers_;
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index 78fc44a..0c5e7e9 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -40,6 +40,7 @@ sources = [ "mojom/app_window.mojom", + "mojom/channel.mojom", "mojom/feature_session_type.mojom", "mojom/guest_view.mojom", "mojom/keep_alive.mojom", @@ -58,6 +59,18 @@ "//url/mojom:url_mojom_gurl", ] + cpp_typemaps = [ + { + types = [ + { + mojom = "extensions.mojom.Channel" + cpp = "version_info::Channel" + }, + ] + traits_headers = [ "//extensions/common/mojom/channel_mojom_traits.h" ] + traits_public_deps = [ "//components/version_info:channel" ] + }, + ] overridden_deps = [ "//content/public/common:interfaces" ] component_deps = [ "//content/public/common" ]
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index 12050b6..d1c5f4c 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -703,13 +703,6 @@ extensions::PortId /* port_id */, std::string /* error_message */) -// Informs the renderer what channel (dev, beta, stable, etc) and user session -// type is running. -IPC_MESSAGE_CONTROL3(ExtensionMsg_SetSessionInfo, - version_info::Channel /* channel */, - extensions::mojom::FeatureSessionType /* session_type */, - bool /* is_lock_screen_context */) - // Notify the renderer that its window has closed. IPC_MESSAGE_ROUTED1(ExtensionMsg_AppWindowClosed, bool /* send_onclosed */)
diff --git a/extensions/common/mojom/OWNERS b/extensions/common/mojom/OWNERS index 08850f4..1feb514 100644 --- a/extensions/common/mojom/OWNERS +++ b/extensions/common/mojom/OWNERS
@@ -1,2 +1,4 @@ per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_mojom_traits*.*=set noparent +per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/extensions/common/mojom/channel.mojom b/extensions/common/mojom/channel.mojom new file mode 100644 index 0000000..e8868d5e --- /dev/null +++ b/extensions/common/mojom/channel.mojom
@@ -0,0 +1,14 @@ +// 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. + +module extensions.mojom; + +// The possible channels for an installation. Refer to version_info::Channel. +enum Channel { + kUnknown = 0, + kCanary = 1, + kDev = 2, + kBeta = 3, + kStable = 4, +};
diff --git a/extensions/common/mojom/channel_mojom_traits.h b/extensions/common/mojom/channel_mojom_traits.h new file mode 100644 index 0000000..97a286d --- /dev/null +++ b/extensions/common/mojom/channel_mojom_traits.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 EXTENSIONS_COMMON_MOJOM_CHANNEL_MOJOM_TRAITS_H_ +#define EXTENSIONS_COMMON_MOJOM_CHANNEL_MOJOM_TRAITS_H_ + +#include "components/version_info/channel.h" +#include "extensions/common/mojom/channel.mojom-shared.h" +#include "mojo/public/cpp/bindings/enum_traits.h" + +namespace mojo { + +template <> +struct EnumTraits<extensions::mojom::Channel, version_info::Channel> { + static extensions::mojom::Channel ToMojom(version_info::Channel input) { + switch (input) { + case version_info::Channel::UNKNOWN: + return extensions::mojom::Channel::kUnknown; + case version_info::Channel::CANARY: + return extensions::mojom::Channel::kCanary; + case version_info::Channel::DEV: + return extensions::mojom::Channel::kDev; + case version_info::Channel::BETA: + return extensions::mojom::Channel::kBeta; + case version_info::Channel::STABLE: + return extensions::mojom::Channel::kStable; + } + NOTREACHED(); + return extensions::mojom::Channel::kUnknown; + } + + static bool FromMojom(extensions::mojom::Channel input, + version_info::Channel* out) { + switch (input) { + case extensions::mojom::Channel::kUnknown: + *out = version_info::Channel::UNKNOWN; + return true; + case extensions::mojom::Channel::kCanary: + *out = version_info::Channel::CANARY; + return true; + case extensions::mojom::Channel::kDev: + *out = version_info::Channel::DEV; + return true; + case extensions::mojom::Channel::kBeta: + *out = version_info::Channel::BETA; + return true; + case extensions::mojom::Channel::kStable: + *out = version_info::Channel::STABLE; + return true; + } + NOTREACHED(); + *out = version_info::Channel::UNKNOWN; + return false; + } +}; + +} // namespace mojo + +#endif // EXTENSIONS_COMMON_MOJOM_CHANNEL_MOJOM_TRAITS_H_
diff --git a/extensions/common/mojom/renderer.mojom b/extensions/common/mojom/renderer.mojom index fe22c10..f5696db 100644 --- a/extensions/common/mojom/renderer.mojom +++ b/extensions/common/mojom/renderer.mojom
@@ -4,6 +4,9 @@ module extensions.mojom; +import "extensions/common/mojom/channel.mojom"; +import "extensions/common/mojom/feature_session_type.mojom"; + // This should be used for implementing browser-to-renderer control messages // which need to retain FIFO with respect to other mojo interfaces like // content.mojom.Renderer. @@ -20,4 +23,11 @@ // Notifies the renderer that an extension was unloaded in the browser. UnloadExtension(string extension_id); + + // Informs the renderer what channel (dev, beta, stable, etc) and user session + // type is running. |is_lock_screen_context| represents whether the browser + // context is associated with Chrome OS lock screen. + SetSessionInfo(Channel channel, + FeatureSessionType session, + bool is_lock_screen_context); };
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index be05088..2e3a519 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -872,7 +872,6 @@ IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchEvent, OnDispatchEvent) - IPC_MESSAGE_HANDLER(ExtensionMsg_SetSessionInfo, OnSetSessionInfo) IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingAllowlist, OnSetScriptingAllowlist) IPC_MESSAGE_HANDLER(ExtensionMsg_SetSystemFont, OnSetSystemFont) @@ -1158,9 +1157,9 @@ } } -void Dispatcher::OnSetSessionInfo(version_info::Channel channel, - mojom::FeatureSessionType session_type, - bool is_lock_screen_context) { +void Dispatcher::SetSessionInfo(version_info::Channel channel, + mojom::FeatureSessionType session_type, + bool is_lock_screen_context) { SetCurrentChannel(channel); SetCurrentFeatureSessionType(session_type); script_context_set_->set_is_lock_screen_context(is_lock_screen_context);
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h index 0d5093c..341ce13 100644 --- a/extensions/renderer/dispatcher.h +++ b/extensions/renderer/dispatcher.h
@@ -217,6 +217,9 @@ void ActivateExtension(const std::string& extension_id) override; void SetActivityLoggingEnabled(bool enabled) override; void UnloadExtension(const std::string& extension_id) override; + void SetSessionInfo(version_info::Channel channel, + mojom::FeatureSessionType session_type, + bool lock_screen_context) override; void OnRendererAssociatedRequest( mojo::PendingAssociatedReceiver<mojom::Renderer> receiver); @@ -240,9 +243,6 @@ const base::ListValue& args); void OnDispatchEvent(const ExtensionMsg_DispatchEvent_Params& params, const base::ListValue& event_args); - void OnSetSessionInfo(version_info::Channel channel, - mojom::FeatureSessionType session_type, - bool lock_screen_context); void OnSetScriptingAllowlist( const ExtensionsClient::ScriptingAllowlist& extension_ids); void OnSetSystemFont(const std::string& font_family,
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 510ab07..0b8ba06 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -1632,7 +1632,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -1679,7 +1679,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -2008,7 +2008,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -2055,7 +2055,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -9772,7 +9772,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -9819,7 +9819,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -9866,7 +9866,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -9913,7 +9913,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -9960,7 +9960,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10007,7 +10007,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10054,7 +10054,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10101,7 +10101,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10148,7 +10148,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10195,7 +10195,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10241,7 +10241,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10288,7 +10288,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium_clang_coverage_tot\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10335,7 +10335,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10382,7 +10382,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10429,7 +10429,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10476,7 +10476,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10523,7 +10523,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\",\"xcode_build_version\":\"12a7209\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10570,7 +10570,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\",\"xcode_build_version\":\"12a7209\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10617,7 +10617,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\",\"xcode_build_version\":\"12a7209\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10664,7 +10664,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium_clang_coverage_tot\",\"xcode_build_version\":\"12a7209\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10711,7 +10711,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10758,7 +10758,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10805,7 +10805,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10852,7 +10852,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10899,7 +10899,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10946,7 +10946,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -10993,7 +10993,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -11040,7 +11040,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium_clang_coverage_tot\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -11086,7 +11086,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\",\"xcode_build_version\":\"12a7209\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 caches { name: "xcode_ios_12a7209" path: "xcode_ios_12a7209.app" @@ -11136,7 +11136,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\",\"xcode_build_version\":\"12a7209\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 caches { name: "xcode_ios_12a7209" path: "xcode_ios_12a7209.app" @@ -11281,7 +11281,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments { @@ -18669,7 +18669,7 @@ cmd: "recipes" } properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.clang\",\"perf_dashboard_machine_group\":\"ChromiumClang\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 43200 + execution_timeout_secs: 50400 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments {
diff --git a/infra/config/lib/ci.star b/infra/config/lib/ci.star index bc75d2a..822c1a9 100644 --- a/infra/config/lib/ci.star +++ b/infra/config/lib/ci.star
@@ -521,7 +521,7 @@ # Because these run ToT Clang, goma is not used. # Naturally the runtime will be ~4-8h on average, depending on config. # CFI builds will take even longer - around 11h. - execution_timeout = 12 * time.hour, + execution_timeout = 14 * time.hour, properties = properties, **kwargs )
diff --git a/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm b/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm index a04bef5..d5b2c64 100644 --- a/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm +++ b/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm
@@ -278,10 +278,8 @@ if (session_service_) { NSString* state_path = base::SysUTF8ToNSString( browser_state_->GetStatePath().AsUTF8Unsafe()); - [session_service_ - deleteLastSessionFileInDirectory:state_path - completion: - CreatePendingTaskCompletionClosure()]; + [session_service_ deleteAllSessionFilesInBrowserStateDirectory:state_path + completion:CreatePendingTaskCompletionClosure()]; } // Remove the screenshots taken by the system when backgrounding the
diff --git