diff --git a/DEPS b/DEPS index 958a953..18fa36d 100644 --- a/DEPS +++ b/DEPS
@@ -245,15 +245,15 @@ # 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': '30fdea3d8fd5ed39de28acae75586d7c4f08ad11', + 'skia_revision': '0e845dc8b05cb2d40d1c880184e33dd76081283a', # 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': '5da4293254a42479d73853b54bc9a54b1f17fd84', + 'v8_revision': '4807b5a15583ca12874e810a2dfcff1415441657', # 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': '96fd9b72d07c54398af2fec01bcd697ad334e6b2', + 'angle_revision': 'd4c8209b3ec9e81339dbb0ba4b62476d61bcbc6b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -261,7 +261,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'd8851a7fd3c12685297ff4690e3dae842be85777', + 'pdfium_revision': '81683d4924b14869564198f832a20f46926cbad1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -276,7 +276,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling googletest # and whatever else without interference from each other. - 'googletest_revision': '1d9f7c5fb2f56b4321b9eec0731b874eb6eef466', + 'googletest_revision': 'aea0874c4252d47d1da096ad763b9c04b42c8514', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling lighttpd # and whatever else without interference from each other. @@ -320,7 +320,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': '6bcbe0f26d957c72a4a1aab42b4ed3c8079915c8', + 'devtools_frontend_revision': 'be87120d5ca8b28896f4cf2a19da255437ea6fd6', # 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. @@ -360,7 +360,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'a62f8e402c081cd38307863d813cf7712a492a3b', + 'dawn_revision': 'cdc9bb4f313be35ef99490c2c2ad7d6e5472c948', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -805,7 +805,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'B9rhutyqLDhWWNhiyH6A1gC63mYwYyQfnP4O5533VnwC', + 'version': 'yFvftcNOlZZJaFm5vRn6OVKPs5whEChqCg3ESP47ycIC', }, ], 'condition': 'checkout_android', @@ -1044,7 +1044,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c3e25c828dd3aac5f03cab26bf12cc788d111532', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '9fa0cb7230db34d3df4434523e5352b35bde7136', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1648,7 +1648,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'fca7b339442bd70c5dc49bb33ee7f9466b560a97', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'cb87ec9557b69c2c4e036673c39bb013f28329b9', + Var('webrtc_git') + '/src.git' + '@' + 'f490d6f818fb7ade9f2c24b83bd51054943cc4a6', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1718,7 +1718,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b91bc92c92c7c822fe546935d41239d6143f1ea6', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@6b7d7f99ba3e662467b03fa7ed22b98d024b0ef0', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 3eb2598..3705c3e 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1076,7 +1076,6 @@ 'OS_MAC', 'OS_NACL', 'OS_NACL_NONSFI', - 'OS_NACL_SFI', 'OS_NETBSD', 'OS_OPENBSD', 'OS_POSIX',
diff --git a/WATCHLISTS b/WATCHLISTS index 54daad8..0d0d802 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -2508,7 +2508,8 @@ 'eme': ['eme-reviews@chromium.org'], 'enterprise_reporting_private': ['domfc+watch@chromium.org', 'anthonyvd+watch@chormium.org'], - 'exo': ['crostini-ui+exo@chromium.org'], + 'exo': ['crostini-ui+exo@chromium.org', + 'yhanada+watchexo@chromium.org'], 'explore_sites': ['chili+watch@chromium.org', 'dewittj+watch@chromium.org', 'dimich+watch@chromium.org',
diff --git a/ash/components/arc/arc_features.cc b/ash/components/arc/arc_features.cc index 2859021..a5c39f31 100644 --- a/ash/components/arc/arc_features.cc +++ b/ash/components/arc/arc_features.cc
@@ -63,6 +63,11 @@ const base::Feature kFilePickerExperimentFeature{ "ArcFilePickerExperiment", base::FEATURE_ENABLED_BY_DEFAULT}; +// Controls experimental key GMS Core and related services protection against to +// be killed by low memory killer. +const base::Feature kGmsCoreLowMemoryKillerProtection{ + "ArcGmsCoreLowMemoryKillerProtection", base::FEATURE_DISABLED_BY_DEFAULT}; + // Controls whether the guest zram is enabled. This is only for ARCVM. const base::Feature kGuestZram{"ArcGuestZram", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/components/arc/arc_features.h b/ash/components/arc/arc_features.h index f44976c..bae6ee4 100644 --- a/ash/components/arc/arc_features.h +++ b/ash/components/arc/arc_features.h
@@ -22,6 +22,7 @@ extern const base::Feature kEnableUnmanagedToManagedTransitionFeature; extern const base::Feature kEnableUsap; extern const base::Feature kFilePickerExperimentFeature; +extern const base::Feature kGmsCoreLowMemoryKillerProtection; extern const base::Feature kGuestZram; extern const base::FeatureParam<int> kGuestZramSize; extern const base::Feature kLogdConfig;
diff --git a/ash/components/arc/mojom/BUILD.gn b/ash/components/arc/mojom/BUILD.gn index 14cf13f..6339249 100644 --- a/ash/components/arc/mojom/BUILD.gn +++ b/ash/components/arc/mojom/BUILD.gn
@@ -325,12 +325,8 @@ cpp = "media::VideoPixelFormat" }, { - mojom = "arc.mojom.DecodeStatus" - cpp = "media::DecodeStatus" - }, - { - mojom = "arc.mojom.Status" - cpp = "media::Status" + mojom = "arc.mojom.DecoderStatus" + cpp = "media::DecoderStatus" }, ] traits_headers = [ "video_accelerator_mojom_traits.h" ]
diff --git a/ash/components/arc/mojom/video_accelerator_mojom_traits.cc b/ash/components/arc/mojom/video_accelerator_mojom_traits.cc index 6a0865f..9222684 100644 --- a/ash/components/arc/mojom/video_accelerator_mojom_traits.cc +++ b/ash/components/arc/mojom/video_accelerator_mojom_traits.cc
@@ -228,85 +228,45 @@ } // static -arc::mojom::DecodeStatus -EnumTraits<arc::mojom::DecodeStatus, media::DecodeStatus>::ToMojom( - media::DecodeStatus input) { - switch (input) { - case media::DecodeStatus::kOk: - return arc::mojom::DecodeStatus::OK; - case media::DecodeStatus::kAborted: - return arc::mojom::DecodeStatus::ABORTED; - case media::DecodeStatus::kDecoderFailedDecode: - return arc::mojom::DecodeStatus::DECODE_FAILED; - default: - NOTREACHED() << "unknown decode status: " << static_cast<int>(input); - return arc::mojom::DecodeStatus::DECODE_FAILED; - } -} - -// static -bool EnumTraits<arc::mojom::DecodeStatus, media::DecodeStatus>::FromMojom( - arc::mojom::DecodeStatus input, - media::DecodeStatus* output) { - switch (input) { - case arc::mojom::DecodeStatus::OK: - *output = media::DecodeStatus::kOk; - return true; - case arc::mojom::DecodeStatus::ABORTED: - *output = media::DecodeStatus::kAborted; - return true; - case arc::mojom::DecodeStatus::DECODE_FAILED: - *output = media::DecodeStatus::kDecoderFailedDecode; - return true; - } - NOTREACHED() << "unknown decode status: " << static_cast<int>(input); - return false; -} - -// static -arc::mojom::Status EnumTraits<arc::mojom::Status, media::Status>::ToMojom( - media::Status input) { +arc::mojom::DecoderStatus +EnumTraits<arc::mojom::DecoderStatus, media::DecoderStatus>::ToMojom( + media::DecoderStatus input) { switch (input.code()) { - case media::StatusCode::kOk: - return arc::mojom::Status::OK; - case media::StatusCode::kAborted: - return arc::mojom::Status::ABORTED; - case media::StatusCode::kInvalidArgument: - return arc::mojom::Status::INVALID_ARGUMENT; - case media::StatusCode::kDecoderFailedDecode: - return arc::mojom::Status::DECODER_DECODE_FAILED; - case media::StatusCode::kDecoderInitializationFailed: - return arc::mojom::Status::DECODER_INITIALIZATION_FAILED; - case media::StatusCode::kDecoderCreationFailed: - return arc::mojom::Status::DECODER_CREATION_FAILED; + case media::DecoderStatus::Codes::kOk: + return arc::mojom::DecoderStatus::OK; + case media::DecoderStatus::Codes::kAborted: + return arc::mojom::DecoderStatus::ABORTED; + case media::DecoderStatus::Codes::kFailed: + return arc::mojom::DecoderStatus::FAILED; + case media::DecoderStatus::Codes::kFailedToCreateDecoder: + return arc::mojom::DecoderStatus::CREATION_FAILED; + case media::DecoderStatus::Codes::kInvalidArgument: + return arc::mojom::DecoderStatus::INVALID_ARGUMENT; default: NOTREACHED() << "unknown status: " << static_cast<int>(input.code()); - return arc::mojom::Status::INVALID_ARGUMENT; + return arc::mojom::DecoderStatus::INVALID_ARGUMENT; } } // static -bool EnumTraits<arc::mojom::Status, media::Status>::FromMojom( - arc::mojom::Status input, - media::Status* output) { +bool EnumTraits<arc::mojom::DecoderStatus, media::DecoderStatus>::FromMojom( + arc::mojom::DecoderStatus input, + media::DecoderStatus* output) { switch (input) { - case arc::mojom::Status::OK: - *output = media::StatusCode::kOk; + case arc::mojom::DecoderStatus::OK: + *output = media::DecoderStatus::Codes::kOk; return true; - case arc::mojom::Status::ABORTED: - *output = media::StatusCode::kAborted; + case arc::mojom::DecoderStatus::ABORTED: + *output = media::DecoderStatus::Codes::kAborted; return true; - case arc::mojom::Status::INVALID_ARGUMENT: - *output = media::StatusCode::kInvalidArgument; + case arc::mojom::DecoderStatus::FAILED: + *output = media::DecoderStatus::Codes::kFailed; return true; - case arc::mojom::Status::DECODER_DECODE_FAILED: - *output = media::StatusCode::kDecoderFailedDecode; + case arc::mojom::DecoderStatus::CREATION_FAILED: + *output = media::DecoderStatus::Codes::kFailedToCreateDecoder; return true; - case arc::mojom::Status::DECODER_INITIALIZATION_FAILED: - *output = media::StatusCode::kDecoderInitializationFailed; - return true; - case arc::mojom::Status::DECODER_CREATION_FAILED: - *output = media::StatusCode::kDecoderCreationFailed; + case arc::mojom::DecoderStatus::INVALID_ARGUMENT: + *output = media::DecoderStatus::Codes::kInvalidArgument; return true; } NOTREACHED() << "unknown status: " << static_cast<int>(input);
diff --git a/ash/components/arc/mojom/video_accelerator_mojom_traits.h b/ash/components/arc/mojom/video_accelerator_mojom_traits.h index 334cc49..f047c84b 100644 --- a/ash/components/arc/mojom/video_accelerator_mojom_traits.h +++ b/ash/components/arc/mojom/video_accelerator_mojom_traits.h
@@ -11,7 +11,7 @@ #include "ash/components/arc/mojom/video_decoder.mojom-shared.h" #include "ash/components/arc/video_accelerator/video_frame_plane.h" #include "media/base/color_plane_layout.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/status.h" #include "media/base/video_codecs.h" #include "media/base/video_frame_layout.h" @@ -135,18 +135,11 @@ }; template <> -struct EnumTraits<arc::mojom::DecodeStatus, media::DecodeStatus> { - static arc::mojom::DecodeStatus ToMojom(media::DecodeStatus input); +struct EnumTraits<arc::mojom::DecoderStatus, media::DecoderStatus> { + static arc::mojom::DecoderStatus ToMojom(media::DecoderStatus input); - static bool FromMojom(arc::mojom::DecodeStatus input, - media::DecodeStatus* output); -}; - -template <> -struct EnumTraits<arc::mojom::Status, media::Status> { - static arc::mojom::Status ToMojom(media::Status input); - - static bool FromMojom(arc::mojom::Status input, media::Status* output); + static bool FromMojom(arc::mojom::DecoderStatus input, + media::DecoderStatus* output); }; } // namespace mojo
diff --git a/ash/components/arc/mojom/video_decoder.mojom b/ash/components/arc/mojom/video_decoder.mojom index f10833b..1e9b46ca 100644 --- a/ash/components/arc/mojom/video_decoder.mojom +++ b/ash/components/arc/mojom/video_decoder.mojom
@@ -9,24 +9,17 @@ import "ash/components/arc/mojom/video_frame_pool.mojom"; import "sandbox/policy/mojom/sandbox.mojom"; -// Based on media::Status, only a limited set of relevant status codes are -// currently added here. +// Based on media::DecoderStatus, only a limited set of relevant status codes +// are currently added here. +// TODO(b:189278506): ensure that the ARCVM side of the video decoder uses the +// new entries listed here. [Extensible] -enum Status { +enum DecoderStatus { OK = 0, ABORTED = 1, - INVALID_ARGUMENT = 2, - DECODER_DECODE_FAILED = 3, - DECODER_INITIALIZATION_FAILED = 4, - DECODER_CREATION_FAILED = 5, -}; - -// Based on media::DecodeStatus -[Extensible] -enum DecodeStatus { - OK = 0, - ABORTED = 1, - DECODE_FAILED = 2, + FAILED = 2, + INVALID_ARGUMENT = 3, + CREATION_FAILED = 4, }; // Based on media::DecoderBuffer @@ -72,10 +65,10 @@ Initialize@0(VideoDecoderConfig config, pending_remote<VideoDecoderClient> client, pending_associated_receiver<VideoFramePool> video_frame_pool) - => (Status status); + => (DecoderStatus status); // Decode the specified frame, flushes if an EOS buffer is passed - Decode@1(DecoderBuffer buffer) => (DecodeStatus status); + Decode@1(DecoderBuffer buffer) => (DecoderStatus status); // Reset the decoder. All pending Decode requests will be finished or aborted // before the callback is called. @@ -95,5 +88,5 @@ int64 timestamp); // Notify the client an error happened while decoding the stream. - OnError@1(Status status); + OnError@1(DecoderStatus status); };
diff --git a/ash/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc b/ash/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc index 1e74524..ecc5053 100644 --- a/ash/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc +++ b/ash/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
@@ -421,8 +421,8 @@ } void GpuArcVideoDecodeAccelerator::NotifyInitializationComplete( - media::Status status) { - DVLOGF(4) << "status: " << status.code(); + media::DecoderStatus status) { + DVLOGF(4) << "status: " << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); OnInitializeDone(
diff --git a/ash/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.h b/ash/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.h index abc2de2..8d66e81 100644 --- a/ash/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.h +++ b/ash/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.h
@@ -51,7 +51,7 @@ ~GpuArcVideoDecodeAccelerator() override; // Implementation of media::VideoDecodeAccelerator::Client interface. - void NotifyInitializationComplete(media::Status status) override; + void NotifyInitializationComplete(media::DecoderStatus status) override; void ProvidePictureBuffers(uint32_t requested_num_of_buffers, media::VideoPixelFormat format, uint32_t textures_per_buffer,
diff --git a/ash/components/arc/video_accelerator/gpu_arc_video_decoder.cc b/ash/components/arc/video_accelerator/gpu_arc_video_decoder.cc index bcbb52e..3c08883 100644 --- a/ash/components/arc/video_accelerator/gpu_arc_video_decoder.cc +++ b/ash/components/arc/video_accelerator/gpu_arc_video_decoder.cc
@@ -17,7 +17,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/media_util.h" #include "media/base/video_codecs.h" #include "media/base/video_frame.h" @@ -90,14 +90,13 @@ if (decoder_) { VLOGF(1) << "Re-initialization is not allowed"; - OnInitializeDone( - media::Status(media::StatusCode::kDecoderInitializationFailed)); + OnInitializeDone(media::DecoderStatus::Codes::kFailed); return; } if (num_instances_ >= kMaxConcurrentInstances) { VLOGF(1) << "Maximum concurrent instances reached: " << num_instances_; - OnInitializeDone(media::Status(media::StatusCode::kDecoderCreationFailed)); + OnInitializeDone(media::DecoderStatus::Codes::kFailedToCreateDecoder); return; } @@ -110,7 +109,7 @@ if (!decoder_) { VLOGF(1) << "Failed to create video decoder"; - OnInitializeDone(media::Status(media::StatusCode::kDecoderCreationFailed)); + OnInitializeDone(media::DecoderStatus::Codes::kFailedToCreateDecoder); return; } num_instances_++; @@ -161,7 +160,7 @@ mojom::BufferPtr& buffer_ptr = buffer->get_buffer(); base::ScopedFD fd = buffer_ptr->handle_fd.TakeFD(); if (!fd.is_valid()) { - OnError(FROM_HERE, media::Status(media::StatusCode::kInvalidArgument)); + OnError(media::DecoderStatus::Codes::kInvalidArgument); return; } DVLOGF(4) << "timestamp: " << buffer_ptr->timestamp << ", fd: " << fd.get(); @@ -183,7 +182,7 @@ CreateDecoderBuffer(std::move(fd), buffer_ptr->offset, buffer_ptr->size); if (!decoder_buffer) { VLOGF(1) << "Failed to create decoder buffer from fd"; - OnError(FROM_HERE, media::Status(media::StatusCode::kInvalidArgument)); + OnError(media::DecoderStatus::Codes::kInvalidArgument); return; } @@ -234,28 +233,24 @@ base::Unretained(this), std::move(callback))); } -void GpuArcVideoDecoder::OnInitializeDone(media::Status status) { - DVLOGF(4) << "status: " << status.code(); +void GpuArcVideoDecoder::OnInitializeDone(media::DecoderStatus status) { + DVLOGF(4) << "status: " << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Report initialization status to UMA. - base::UmaHistogramEnumeration("Media.GpuArcVideoDecoder.InitializeResult", - status.code()); - std::move(init_callback_).Run(status); } void GpuArcVideoDecoder::OnDecodeDone(DecodeCallback callback, - media::Status status) { - DVLOGF(4) << "status: " << status.code(); + media::DecoderStatus status) { + DVLOGF(4) << "status: " << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!status.is_ok() && (status.code() != media::StatusCode::kAborted)) { + if (!status.is_ok() && status != media::DecoderStatus::Codes::kAborted) { std::move(callback).Run(status.code()); return; } - std::move(callback).Run(media::DecodeStatus::OK); + std::move(callback).Run(media::DecoderStatus::Codes::kOk); } void GpuArcVideoDecoder::OnFrameReady(scoped_refptr<media::VideoFrame> frame) { @@ -267,7 +262,7 @@ video_frame_pool_->GetVideoFrameId(frame.get()); if (!video_frame_id) { VLOGF(1) << "Failed to get video frame id."; - OnError(FROM_HERE, media::Status(media::StatusCode::kInvalidArgument)); + OnError(media::DecoderStatus::Codes::kInvalidArgument); return; } @@ -295,7 +290,7 @@ if (!reset_callback_) { VLOGF(1) << "Unexpected OnResetDone() callback received from VD"; - OnError(FROM_HERE, media::Status(media::StatusCode::kInvalidArgument)); + OnError(media::DecoderStatus::Codes::kInvalidArgument); return; } @@ -312,8 +307,7 @@ client_video_frames_.clear(); } -void GpuArcVideoDecoder::OnError(base::Location location, - const media::Status& status) { +void GpuArcVideoDecoder::OnError(media::DecoderStatus status) { VLOGF(1) << "error: " << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -327,7 +321,7 @@ error_state_ = true; if (client_) { - client_->OnError(status); + client_->OnError(std::move(status)); } // Abort all pending requests. @@ -364,7 +358,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (error_state_) { - std::move(callback).Run(media::DecodeStatus::DECODE_ERROR); + std::move(callback).Run(media::DecoderStatus::Codes::kFailed); return; } if (!decoder_) { @@ -387,7 +381,7 @@ if (!decoder_) { VLOGF(1) << "VD not initialized"; - OnError(FROM_HERE, media::Status(media::StatusCode::kInvalidArgument)); + OnError(media::DecoderStatus::Codes::kInvalidArgument); return; }
diff --git a/ash/components/arc/video_accelerator/gpu_arc_video_decoder.h b/ash/components/arc/video_accelerator/gpu_arc_video_decoder.h index 07646c8..f586a25d 100644 --- a/ash/components/arc/video_accelerator/gpu_arc_video_decoder.h +++ b/ash/components/arc/video_accelerator/gpu_arc_video_decoder.h
@@ -56,9 +56,9 @@ using Request = base::OnceClosure; // Called by the decoder when initialization is done. - void OnInitializeDone(media::Status status); + void OnInitializeDone(media::DecoderStatus status); // Called by the decoder when the specified buffer has been decoded. - void OnDecodeDone(DecodeCallback callback, media::Status status); + void OnDecodeDone(DecodeCallback callback, media::DecoderStatus status); // Called by the decoder when a decoded frame is ready. void OnFrameReady(scoped_refptr<media::VideoFrame> frame); // Called by the decoder when a reset has been completed. @@ -66,7 +66,7 @@ // Called by the video frame pool when new frames have been requested. void OnRequestVideoFrames(); // Called when an error occurred. - void OnError(base::Location location, const media::Status& status); + void OnError(media::DecoderStatus status); // Handle all requests that are currently in the |requests_| queue. void HandleRequests();
diff --git a/ash/components/arc/video_accelerator/gpu_arc_video_frame_pool.cc b/ash/components/arc/video_accelerator/gpu_arc_video_frame_pool.cc index 77532ad..a177295 100644 --- a/ash/components/arc/video_accelerator/gpu_arc_video_frame_pool.cc +++ b/ash/components/arc/video_accelerator/gpu_arc_video_frame_pool.cc
@@ -12,7 +12,7 @@ #include "base/posix/eintr_wrapper.h" #include "build/build_config.h" #include "gpu/ipc/common/gpu_memory_buffer_support.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/format_utils.h" #include "media/base/video_types.h" #include "media/gpu/buffer_validation.h"
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 813e83fe..eddf2c9 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -549,6 +549,11 @@ const base::Feature kEnableWireGuard{"EnableWireGuard", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enforces Ash extension keep-list. Only the extensions/Chrome apps in the +// keep-list are enabled in Ash. +const base::Feature kEnforceAshExtensionKeeplist{ + "EnforceAshExtensionKeeplist", base::FEATURE_ENABLED_BY_DEFAULT}; + // Enables Device End Of Lifetime warning notifications. const base::Feature kEolWarningNotifications{"EolWarningNotifications", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index e38b43b6d..d3e06b57 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -218,6 +218,8 @@ extern const base::Feature kEnableSamlReauthenticationOnLockscreen; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kEnableWireGuard; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kEnforceAshExtensionKeeplist; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kEolWarningNotifications; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kESimPolicy; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kExoLockNotification;
diff --git a/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.cc b/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.cc index df843a318d..1ecda79 100644 --- a/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.cc +++ b/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.cc
@@ -9,7 +9,6 @@ #include "ash/strings/grit/ash_strings.h" #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/time/time.h" #include "ui/base/l10n/l10n_util.h" #include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/notification.h" @@ -36,8 +35,6 @@ // progress bar. const int kInfiniteLoadingProgressValue = -1; -constexpr base::TimeDelta kNotificationTimeout = base::Seconds(30); - // Creates an empty Fast Pair notification with the given id and uses the // Bluetooth icon and FastPair notifierID. std::unique_ptr<message_center::Notification> CreateNotification( @@ -59,6 +56,7 @@ /*delegate=*/nullptr, /*small_image=*/ash::kNotificationBluetoothIcon, /*warning_level=*/warning_level); + notification->set_never_timeout(true); notification->set_priority( message_center::NotificationPriority::MAX_PRIORITY); @@ -78,12 +76,10 @@ explicit NotificationDelegate( base::RepeatingClosure on_primary_click, base::OnceCallback<void(bool)> on_close, - base::RepeatingClosure on_secondary_click = base::DoNothing(), - base::OneShotTimer* expire_notification_timer = nullptr) { + base::RepeatingClosure on_secondary_click = base::DoNothing()) { on_primary_click_ = on_primary_click; on_secondary_click_ = on_secondary_click; on_close_ = std::move(on_close); - expire_notification_timer_ = expire_notification_timer; } protected: @@ -107,22 +103,13 @@ } // message_center::NotificationDelegate override: - void Close(bool by_user) override { - // If there is an expire notification timer, stop the timer if the user - // dismisses the notification to prevent the timer firing and removing - // notifications that might come up later. - if (expire_notification_timer_) - expire_notification_timer_->Stop(); - - std::move(on_close_).Run(by_user); - } + void Close(bool by_user) override { std::move(on_close_).Run(by_user); } private: enum class Button { kPrimaryButton, kSecondaryButton }; base::RepeatingClosure on_primary_click_; base::RepeatingClosure on_secondary_click_; base::OnceCallback<void(bool)> on_close_; - base::OneShotTimer* expire_notification_timer_; }; FastPairNotificationController::FastPairNotificationController() = default; @@ -176,19 +163,9 @@ discovery_notification->set_delegate( base::MakeRefCounted<NotificationDelegate>( /*on_primary_click=*/on_connect_clicked, - /*on_close=*/std::move(on_close), - /*on_secondary_click=*/base::DoNothing(), - /*expire_notification_timer=*/&expire_notification_timer_)); + /*on_close=*/std::move(on_close))); discovery_notification->set_image(device_image); - // Start timer for how long to show the notification before removing the - // notification. After the timeout period, we will remove the notification - // from the Message Center. - expire_notification_timer_.Start( - FROM_HERE, kNotificationTimeout, - base::BindOnce(&FastPairNotificationController::RemoveNotifications, - weak_ptr_factory_.GetWeakPtr())); - MessageCenter::Get()->AddNotification(std::move(discovery_notification)); } @@ -196,14 +173,6 @@ const std::u16string& device_name, gfx::Image device_image, base::OnceCallback<void(bool)> on_close) { - // If we get to this point in the pairing flow where we are showing the - // Pairing notification, then the user has elected to begin pairing and we - // can stop the timer that was waiting for user interaction on the - // Discovery notification. We do not need the timer for the Pairing - // notification since it will be removed when pairing succeeds or fails by - // the system. - expire_notification_timer_.Stop(); - std::unique_ptr<message_center::Notification> pairing_notification = CreateNotification( kFastPairPairingNotificationId, @@ -249,18 +218,9 @@ base::MakeRefCounted<NotificationDelegate>( /*on_primary_click=*/on_save_clicked, /*on_close=*/std::move(on_close), - /*on_secondary_click=*/on_learn_more_clicked, - /*expire_notification_timer=*/&expire_notification_timer_)); + /*on_secondary_click=*/on_learn_more_clicked)); associate_account_notification->set_image(device_image); - // Start timer for how long to show the notification before removing the - // notification. After the timeout period, we will remove the notification - // from the Message Center. - expire_notification_timer_.Start( - FROM_HERE, kNotificationTimeout, - base::BindOnce(&FastPairNotificationController::RemoveNotifications, - weak_ptr_factory_.GetWeakPtr())); - MessageCenter::Get()->AddNotification( std::move(associate_account_notification)); }
diff --git a/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h b/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h index 315c7796..9022153 100644 --- a/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h +++ b/ash/quick_pair/ui/fast_pair/fast_pair_notification_controller.h
@@ -7,8 +7,6 @@ #include "base/callback.h" #include "base/component_export.h" -#include "base/memory/weak_ptr.h" -#include "base/timer/timer.h" #include "ui/gfx/image/image.h" namespace ash { @@ -44,14 +42,6 @@ base::RepeatingClosure on_learn_more_clicked, base::OnceCallback<void(bool)> on_close); void RemoveNotifications(); - - private: - // This timer is used for Discovery and Associate Account notifications to - // remove them from the Message Center if the user does not elect to begin - // pairing/saving to their account. - base::OneShotTimer expire_notification_timer_; - - base::WeakPtrFactory<FastPairNotificationController> weak_ptr_factory_{this}; }; } // namespace quick_pair
diff --git a/ash/webui/camera_app_ui/resources/js/js.gni b/ash/webui/camera_app_ui/resources/js/js.gni index ab5c167..1bf4085 100644 --- a/ash/webui/camera_app_ui/resources/js/js.gni +++ b/ash/webui/camera_app_ui/resources/js/js.gni
@@ -68,9 +68,9 @@ "untrusted_script_loader.ts", "untrusted_video_processor_helper.ts", "util.ts", - "views/camera_intent.js", + "views/camera_intent.ts", "views/camera.ts", - "views/camera/layout.js", + "views/camera/layout.ts", "views/camera/mode/index.ts", "views/camera/mode/mode_base.ts", "views/camera/mode/photo.ts", @@ -80,18 +80,18 @@ "views/camera/mode/square.ts", "views/camera/mode/video.ts", "views/camera/document_corner_overlay.js", - "views/camera/options.js", + "views/camera/options.ts", "views/camera/preview.js", - "views/camera/scan_options.js", - "views/camera/timertick.js", - "views/camera/video_encoder_options.js", + "views/camera/scan_options.ts", + "views/camera/timertick.ts", + "views/camera/video_encoder_options.ts", "views/crop_document.ts", - "views/dialog.js", + "views/dialog.ts", "views/ptz_panel.js", "views/review.ts", "views/settings.js", "views/view.ts", - "views/warning.js", + "views/warning.ts", "waitable_event.ts", "window_controller.ts", ]
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/layout.js b/ash/webui/camera_app_ui/resources/js/views/camera/layout.js deleted file mode 100644 index 0ead234..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/camera/layout.js +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {cssStyle} from '../../css.js'; -import * as dom from '../../dom.js'; -import * as state from '../../state.js'; -import {Mode} from '../../type.js'; -import {windowController} from '../../window_controller.js'; - -/** - * Creates a controller to handle layouts of Camera view. - */ -export class Layout { - /** - * @public - */ - constructor() { - /** - * @const {!HTMLDivElement} - * @private - */ - this.previewBox_ = dom.get('#preview-box', HTMLDivElement); - - /** - * @const {!HTMLCanvasElement} - * @private - */ - this.faceOverlay_ = dom.get('#preview-face-overlay', HTMLCanvasElement); - - /** - * @const {!CSSStyleDeclaration} - * @private - */ - this.viewportRule_ = cssStyle('#preview-viewport'); - - /** - * @const {!CSSStyleDeclaration} - * @private - */ - this.contentRule_ = cssStyle('.preview-content'); - } - - /** - * @param {number} width - * @param {number} height - * @private - */ - setContentSize_(width, height) { - this.contentRule_.setProperty('width', `${width}px`); - this.contentRule_.setProperty('height', `${height}px`); - this.faceOverlay_.width = width; - this.faceOverlay_.height = height; - } - - /** - * @param {number} width - * @param {number} height - * @private - */ - setViewportSize_(width, height) { - this.viewportRule_.setProperty('width', `${width}px`); - this.viewportRule_.setProperty('height', `${height}px`); - } - - /** - * Sets the offset between video content and viewport. - * @param {number} dx - * @param {number} dy - * @private - */ - setContentOffset_(dx, dy) { - this.contentRule_.setProperty('left', `${dx}px`); - this.contentRule_.setProperty('top', `${dy}px`); - } - - /** - * Updates the layout for video-size or window-size changes. - */ - update() { - const fullWindow = windowController.isFullscreenOrMaximized(); - const tall = window.innerHeight > window.innerWidth; - state.set(state.State.TABLET_LANDSCAPE, fullWindow && !tall); - state.set(state.State.MAX_WND, fullWindow); - state.set(state.State.TALL, tall); - - const {width: boxW, height: boxH} = - this.previewBox_.getBoundingClientRect(); - const video = dom.get('#preview-video', HTMLVideoElement); - - if (state.get(Mode.SQUARE)) { - const viewportSize = Math.min(boxW, boxH); - this.setViewportSize_(viewportSize, viewportSize); - const scale = - viewportSize / Math.min(video.videoHeight, video.videoWidth); - const contentW = scale * video.videoWidth; - const contentH = scale * video.videoHeight; - this.setContentSize_(contentW, contentH); - this.setContentOffset_( - (viewportSize - contentW) / 2, (viewportSize - contentH) / 2); - } else { - const scale = Math.min(boxH / video.videoHeight, boxW / video.videoWidth); - const contentW = scale * video.videoWidth; - const contentH = scale * video.videoHeight; - this.setViewportSize_(contentW, contentH); - this.setContentSize_(contentW, contentH); - this.setContentOffset_(0, 0); - } - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/layout.ts b/ash/webui/camera_app_ui/resources/js/views/camera/layout.ts new file mode 100644 index 0000000..82dc3b60 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/camera/layout.ts
@@ -0,0 +1,73 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {cssStyle} from '../../css.js'; +import * as dom from '../../dom.js'; +import * as state from '../../state.js'; +import {Mode} from '../../type.js'; +import {windowController} from '../../window_controller.js'; + +/** + * Creates a controller to handle layouts of Camera view. + */ +export class Layout { + private readonly previewBox = dom.get('#preview-box', HTMLDivElement); + private readonly faceOverlay = + dom.get('#preview-face-overlay', HTMLCanvasElement); + private readonly viewportRule = cssStyle('#preview-viewport'); + private readonly contentRule = cssStyle('.preview-content'); + + private setContentSize(width: number, height: number) { + this.contentRule.setProperty('width', `${width}px`); + this.contentRule.setProperty('height', `${height}px`); + this.faceOverlay.width = width; + this.faceOverlay.height = height; + } + + private setViewportSize(width: number, height: number) { + this.viewportRule.setProperty('width', `${width}px`); + this.viewportRule.setProperty('height', `${height}px`); + } + + /** + * Sets the offset between video content and viewport. + */ + private setContentOffset(dx: number, dy: number) { + this.contentRule.setProperty('left', `${dx}px`); + this.contentRule.setProperty('top', `${dy}px`); + } + + /** + * Updates the layout for video-size or window-size changes. + */ + update(): void { + const fullWindow = windowController.isFullscreenOrMaximized(); + const tall = window.innerHeight > window.innerWidth; + state.set(state.State.TABLET_LANDSCAPE, fullWindow && !tall); + state.set(state.State.MAX_WND, fullWindow); + state.set(state.State.TALL, tall); + + const {width: boxW, height: boxH} = this.previewBox.getBoundingClientRect(); + const video = dom.get('#preview-video', HTMLVideoElement); + + if (state.get(Mode.SQUARE)) { + const viewportSize = Math.min(boxW, boxH); + this.setViewportSize(viewportSize, viewportSize); + const scale = + viewportSize / Math.min(video.videoHeight, video.videoWidth); + const contentW = scale * video.videoWidth; + const contentH = scale * video.videoHeight; + this.setContentSize(contentW, contentH); + this.setContentOffset( + (viewportSize - contentW) / 2, (viewportSize - contentH) / 2); + } else { + const scale = Math.min(boxH / video.videoHeight, boxW / video.videoWidth); + const contentW = scale * video.videoWidth; + const contentH = scale * video.videoHeight; + this.setViewportSize(contentW, contentH); + this.setContentSize(contentW, contentH); + this.setContentOffset(0, 0); + } + } +}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/options.js b/ash/webui/camera_app_ui/resources/js/views/camera/options.js deleted file mode 100644 index 07eded5..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/camera/options.js +++ /dev/null
@@ -1,233 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import * as animate from '../../animation.js'; -// eslint-disable-next-line no-unused-vars -import {Camera3DeviceInfo} from '../../device/camera3_device_info.js'; -// eslint-disable-next-line no-unused-vars -import {DeviceInfoUpdater} from '../../device/device_info_updater.js'; -import * as dom from '../../dom.js'; -import {I18nString} from '../../i18n_string.js'; -import * as localStorage from '../../models/local_storage.js'; -import * as nav from '../../nav.js'; -import * as state from '../../state.js'; -import {Facing, PerfEvent, ViewName} from '../../type.js'; -import * as util from '../../util.js'; - -/** - * Creates a controller for the options of Camera view. - */ -export class Options { - /** - * @param {!DeviceInfoUpdater} infoUpdater - * @param {function(): !Promise} doSwitchDevice Callback to trigger device - * switching. - */ - constructor(infoUpdater, doSwitchDevice) { - /** - * @type {!DeviceInfoUpdater} - * @private - * @const - */ - this.infoUpdater_ = infoUpdater; - - /** - * @type {function(): !Promise} - * @private - * @const - */ - this.doSwitchDevice_ = doSwitchDevice; - - /** - * @type {!HTMLInputElement} - * @private - * @const - */ - this.toggleMic_ = dom.get('#toggle-mic', HTMLInputElement); - - /** - * @type {!HTMLInputElement} - * @private - * @const - */ - this.toggleMirror_ = dom.get('#toggle-mirror', HTMLInputElement); - - /** - * Device id of the camera device currently used or selected. - * @type {?string} - * @private - */ - this.videoDeviceId_ = null; - - /** - * Whether list of video devices is being refreshed now. - * @type {boolean} - * @private - */ - this.refreshingVideoDeviceIds_ = false; - - /** - * Mirroring set per device. - * @type {!Object} - * @private - */ - this.mirroringToggles_ = {}; - - /** - * Current audio track in use. - * @type {?MediaStreamTrack} - * @private - */ - this.audioTrack_ = null; - - dom.get('#switch-device', HTMLButtonElement) - .addEventListener('click', () => this.switchDevice_()); - dom.get('#open-settings', HTMLButtonElement) - .addEventListener('click', () => nav.open(ViewName.SETTINGS)); - - this.toggleMic_.addEventListener('click', () => this.updateAudioByMic_()); - this.toggleMirror_.addEventListener('click', () => this.saveMirroring_()); - - util.bindElementAriaLabelWithState({ - element: dom.get('#toggle-timer', Element), - state: state.State.TIMER_3SEC, - onLabel: I18nString.TOGGLE_TIMER_3S_BUTTON, - offLabel: I18nString.TOGGLE_TIMER_10S_BUTTON, - }); - - // Restore saved mirroring states per video device. - this.mirroringToggles_ = localStorage.getObject('mirroringToggles'); - // Remove the deprecated values. - localStorage.remove('effectIndex', 'toggleMulti', 'toggleMirror'); - - this.infoUpdater_.addDeviceChangeListener((updater) => { - state.set(state.State.MULTI_CAMERA, updater.getDevicesInfo().length >= 2); - }); - } - - /** - * Device id of the camera device currently used or selected. - * @return {?string} - */ - get currentDeviceId() { - return this.videoDeviceId_; - } - - /** - * Switches to the next available camera device. - * @private - */ - async switchDevice_() { - if (!state.get(state.State.STREAMING) || state.get(state.State.TAKING)) { - return; - } - state.set(PerfEvent.CAMERA_SWITCHING, true); - const devices = await this.infoUpdater_.getDevicesInfo(); - animate.play(dom.get('#switch-device', HTMLElement)); - let index = - devices.findIndex((entry) => entry.deviceId === this.videoDeviceId_); - if (index === -1) { - index = 0; - } - if (devices.length > 0) { - index = (index + 1) % devices.length; - this.videoDeviceId_ = devices[index].deviceId; - } - const isSuccess = await this.doSwitchDevice_(); - state.set(PerfEvent.CAMERA_SWITCHING, false, {hasError: !isSuccess}); - } - - /** - * Updates the options' values for the current constraints and stream. - * @param {!MediaStream} stream Current Stream in use. - * @param {!Facing} facing - */ - updateValues(stream, facing) { - const track = stream.getVideoTracks()[0]; - const trackSettings = track.getSettings && track.getSettings(); - this.videoDeviceId_ = trackSettings && trackSettings.deviceId || null; - this.updateMirroring_(facing); - this.audioTrack_ = stream.getAudioTracks()[0]; - this.updateAudioByMic_(); - } - - /** - * Updates mirroring for a new stream. - * @param {!Facing} facing Facing of the stream. - * @private - */ - updateMirroring_(facing) { - // Update mirroring by detected facing-mode. Enable mirroring by default if - // facing-mode isn't available. - let enabled = facing !== Facing.ENVIRONMENT; - - // Override mirroring only if mirroring was toggled manually. - if (this.videoDeviceId_ in this.mirroringToggles_) { - enabled = this.mirroringToggles_[this.videoDeviceId_]; - } - - util.toggleChecked(this.toggleMirror_, enabled); - } - - /** - * Saves the toggled mirror state for the current video device. - * @private - */ - saveMirroring_() { - this.mirroringToggles_[this.videoDeviceId_] = this.toggleMirror_.checked; - localStorage.set('mirroringToggles', this.mirroringToggles_); - } - - /** - * Enables/disables the current audio track according to the microphone - * option. - * @private - */ - updateAudioByMic_() { - if (this.audioTrack_) { - this.audioTrack_.enabled = this.toggleMic_.checked; - } - } - - /** - * Gets the video device ids sorted by preference. - * @param {!Facing} facing Preferred facing to use - * @return {!Array<string>} - */ - videoDeviceIds(facing) { - /** @type {!Array<(!Camera3DeviceInfo|!MediaDeviceInfo)>} */ - let devices; - /** - * Object mapping from device id to facing. Set to null for fake cameras. - * @type {?Object<string, !Facing>} - */ - let facings = null; - - const camera3Info = this.infoUpdater_.getCamera3DevicesInfo(); - if (camera3Info) { - devices = camera3Info; - facings = {}; - for (const {deviceId, facing} of camera3Info) { - facings[deviceId] = facing; - } - } else { - devices = this.infoUpdater_.getDevicesInfo(); - } - - const preferredFacing = - facing === Facing.NOT_SET ? util.getDefaultFacing() : facing; - // Put the selected video device id first. - const sorted = devices.map((device) => device.deviceId).sort((a, b) => { - if (a === b) { - return 0; - } - if (this.videoDeviceId_ ? a === this.videoDeviceId_ : - (facings && facings[a] === preferredFacing)) { - return -1; - } - return 1; - }); - return sorted; - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/options.ts b/ash/webui/camera_app_ui/resources/js/views/camera/options.ts new file mode 100644 index 0000000..1838bcf --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/camera/options.ts
@@ -0,0 +1,185 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as animate from '../../animation.js'; +import {Camera3DeviceInfo} from '../../device/camera3_device_info.js'; +import {DeviceInfoUpdater} from '../../device/device_info_updater.js'; +import * as dom from '../../dom.js'; +import {I18nString} from '../../i18n_string.js'; +import * as localStorage from '../../models/local_storage.js'; +import * as nav from '../../nav.js'; +import * as state from '../../state.js'; +import {Facing, PerfEvent, ViewName} from '../../type.js'; +import * as util from '../../util.js'; + +/** + * Creates a controller for the options of Camera view. + */ +export class Options { + private readonly toggleMic = dom.get('#toggle-mic', HTMLInputElement); + private readonly toggleMirror = dom.get('#toggle-mirror', HTMLInputElement); + + /** + * Device id of the camera device currently used or selected. + */ + private videoDeviceId: string|null = null; + + /** + * Mirroring set per device. + */ + private mirroringToggles: Record<string, boolean> = {}; + + /** + * Current audio track in use. + */ + private audioTrack: MediaStreamTrack|null = null; + + /** + * @param doSwitchDevice Callback to trigger device switching. + */ + constructor( + private readonly infoUpdater: DeviceInfoUpdater, + private readonly doSwitchDevice: () => Promise<boolean>, + ) { + dom.get('#switch-device', HTMLButtonElement) + .addEventListener('click', () => this.switchDevice()); + dom.get('#open-settings', HTMLButtonElement) + .addEventListener('click', () => nav.open(ViewName.SETTINGS)); + + this.toggleMic.addEventListener('click', () => this.updateAudioByMic()); + this.toggleMirror.addEventListener('click', () => this.saveMirroring()); + + util.bindElementAriaLabelWithState({ + element: dom.get('#toggle-timer', Element), + state: state.State.TIMER_3SEC, + onLabel: I18nString.TOGGLE_TIMER_3S_BUTTON, + offLabel: I18nString.TOGGLE_TIMER_10S_BUTTON, + }); + + // Restore saved mirroring states per video device. + this.mirroringToggles = localStorage.getObject('mirroringToggles'); + // Remove the deprecated values. + localStorage.remove('effectIndex', 'toggleMulti', 'toggleMirror'); + + this.infoUpdater.addDeviceChangeListener((updater) => { + state.set(state.State.MULTI_CAMERA, updater.getDevicesInfo().length >= 2); + }); + } + + /** + * Device id of the camera device currently used or selected. + */ + get currentDeviceId(): string|null { + return this.videoDeviceId; + } + + /** + * Switches to the next available camera device. + */ + private async switchDevice() { + if (!state.get(state.State.STREAMING) || state.get(state.State.TAKING)) { + return; + } + state.set(PerfEvent.CAMERA_SWITCHING, true); + const devices = this.infoUpdater.getDevicesInfo(); + animate.play(dom.get('#switch-device', HTMLElement)); + let index = + devices.findIndex((entry) => entry.deviceId === this.videoDeviceId); + if (index === -1) { + index = 0; + } + if (devices.length > 0) { + index = (index + 1) % devices.length; + this.videoDeviceId = devices[index].deviceId; + } + const isSuccess = await this.doSwitchDevice(); + state.set(PerfEvent.CAMERA_SWITCHING, false, {hasError: !isSuccess}); + } + + /** + * Updates the options' values for the current constraints and stream. + * @param stream Current Stream in use. + */ + updateValues(stream: MediaStream, facing: Facing): void { + const track = stream.getVideoTracks()[0]; + const trackSettings = track.getSettings && track.getSettings(); + this.videoDeviceId = trackSettings && trackSettings.deviceId || null; + this.updateMirroring(facing); + this.audioTrack = stream.getAudioTracks()[0]; + this.updateAudioByMic(); + } + + /** + * Updates mirroring for a new stream. + * @param facing Facing of the stream. + */ + private updateMirroring(facing: Facing) { + // Update mirroring by detected facing-mode. Enable mirroring by default if + // facing-mode isn't available. + let enabled = facing !== Facing.ENVIRONMENT; + + // Override mirroring only if mirroring was toggled manually. + if (this.videoDeviceId in this.mirroringToggles) { + enabled = this.mirroringToggles[this.videoDeviceId]; + } + + util.toggleChecked(this.toggleMirror, enabled); + } + + /** + * Saves the toggled mirror state for the current video device. + */ + private saveMirroring() { + this.mirroringToggles[this.videoDeviceId] = this.toggleMirror.checked; + localStorage.set('mirroringToggles', this.mirroringToggles); + } + + /** + * Enables/disables the current audio track according to the microphone + * option. + */ + private updateAudioByMic() { + if (this.audioTrack) { + this.audioTrack.enabled = this.toggleMic.checked; + } + } + + /** + * Gets the video device ids sorted by preference. + * @param facing Preferred facing to use + */ + videoDeviceIds(facing: Facing): string[] { + let devices: Array<Camera3DeviceInfo|MediaDeviceInfo>; + /** + * Object mapping from device id to facing. Set to null for fake cameras. + */ + let facings: Record<string, Facing>|null = null; + + const camera3Info = this.infoUpdater.getCamera3DevicesInfo(); + if (camera3Info) { + devices = camera3Info; + facings = {}; + for (const {deviceId, facing} of camera3Info) { + facings[deviceId] = facing; + } + } else { + devices = this.infoUpdater.getDevicesInfo(); + } + + const preferredFacing = + facing === Facing.NOT_SET ? util.getDefaultFacing() : facing; + // Put the selected video device id first. + const sorted = devices.map((device) => device.deviceId).sort((a, b) => { + if (a === b) { + return 0; + } + if (this.videoDeviceId ? a === this.videoDeviceId : + (facings && facings[a] === preferredFacing)) { + return -1; + } + return 1; + }); + return sorted; + } +}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/scan_options.js b/ash/webui/camera_app_ui/resources/js/views/camera/scan_options.js deleted file mode 100644 index 8b319ec8..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/camera/scan_options.js +++ /dev/null
@@ -1,223 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assert, assertInstanceof} from '../../assert.js'; -import * as barcodeChip from '../../barcode_chip.js'; -// eslint-disable-next-line no-unused-vars -import {DeviceInfoUpdater} from '../../device/device_info_updater.js'; -import * as dom from '../../dom.js'; -// eslint-disable-next-line no-unused-vars -import {Point} from '../../geometry.js'; -import {sendBarcodeEnabledEvent} from '../../metrics.js'; -import {BarcodeScanner} from '../../models/barcode.js'; -import * as state from '../../state.js'; -import {Mode} from '../../type.js'; - -import {DocumentCornerOverlay} from './document_corner_overlay.js'; - -/** - * @enum {string} - */ -const ScanType = { - BARCODE: 'barcode', - DOCUMENT: 'document', -}; - -const scanTypeValues = new Set(Object.values(ScanType)); - -/** - * @param {!HTMLInputElement} el - * @return {!ScanType} - */ -function getScanTypeFromElement(el) { - const s = el.dataset['scantype']; - assert(scanTypeValues.has(s), `No such scantype: ${s}`); - return /** @type {!ScanType} */ (s); -} - -/** - * @param {!ScanType} type - * @return {!HTMLInputElement} - */ -function getElemetFromScanType(type) { - return dom.get(`input[data-scantype=${type}]`, HTMLInputElement); -} - -const DEFAULT_SCAN_TYPE = ScanType.DOCUMENT; - -/** - * Controller for the scan options of Camera view. - */ -export class ScanOptions { - /** - * @param {!function(!Point): !Promise<void>} updatePointOfInterest function - * to update point of interest on the stream. - * @public - */ - constructor(updatePointOfInterest) { - /** - * Togglable barcode option in photo mode. - * @type {!HTMLInputElement} - * @private - * @const - */ - this.photoBarcodeOption_ = dom.get('#toggle-barcode', HTMLInputElement); - - /** - * @type {!Array<!HTMLInputElement>} - * @private - * @const - */ - this.scanOptions_ = - [...dom.getAll('#scan-modes-group [data-scantype]', HTMLInputElement)]; - - /** - * Whether preview have attached as scan frame source. - * @type {boolean} - * @private - */ - this.previewAttached_ = false; - - /** - * May be null if preview is not ready. - * @type {?BarcodeScanner} - * @private - */ - this.barcodeScanner_ = null; - - /** - * @const {!DocumentCornerOverlay} - * @private - */ - this.documentCornerOverylay_ = - new DocumentCornerOverlay(updatePointOfInterest); - - /** - * Called when scan option changed. - * @type {function(): void} - * @public - */ - this.onChange = () => {}; - - [this.photoBarcodeOption_, ...this.scanOptions_].forEach((opt) => { - opt.addEventListener('click', (evt) => { - if (state.get(state.State.CAMERA_CONFIGURING)) { - evt.preventDefault(); - } - }); - }); - this.photoBarcodeOption_.addEventListener('change', () => { - this.updateOption_( - this.photoBarcodeOption_.checked ? ScanType.BARCODE : null); - }); - this.scanOptions_.forEach((opt) => { - opt.addEventListener('change', (evt) => { - if (opt.checked) { - this.updateOption_(this.getToggledScanOption_()); - } - }); - }); - } - - /** - * @return {!ScanType} Returns scan type of checked radio buttons in scan type - * option groups. - */ - getToggledScanOption_() { - const checkedEl = this.scanOptions_.find(({checked}) => checked); - return checkedEl === undefined ? DEFAULT_SCAN_TYPE : - getScanTypeFromElement(checkedEl); - } - - /** - * Attaches to preview video as source of frames to be scanned. - * @param {!HTMLVideoElement} video - * @return {!Promise} - */ - async attachPreview(video) { - assert(!this.previewAttached_); - this.barcodeScanner_ = new BarcodeScanner(video, (value) => { - barcodeChip.show(value); - }); - const {deviceId} = assertInstanceof(video.srcObject, MediaStream) - .getVideoTracks()[0] - .getSettings(); - this.documentCornerOverylay_.attach(deviceId); - this.previewAttached_ = true; - const scanType = state.get(Mode.SCAN) ? this.getToggledScanOption_() : null; - await this.updateOption_(scanType); - } - - /** - * @return {boolean} - */ - isDocumentModeEanbled() { - return this.documentCornerOverylay_.isEnabled(); - } - - /** - * @param {?ScanType} scanType Scan type to be enabled, null for no type is - * enabled. - * @private - */ - async updateOption_(scanType) { - if (!this.previewAttached_) { - return; - } - assert(this.barcodeScanner_ !== null); - - this.updateOptionsUI_(scanType); - const mode = state.get(state.State.SHOW_SCAN_MODE) ? Mode.SCAN : Mode.PHOTO; - if (state.get(mode) && scanType === ScanType.BARCODE) { - sendBarcodeEnabledEvent(); - this.barcodeScanner_.start(); - state.set(state.State.ENABLE_SCAN_BARCODE, true); - } else { - this.stopBarcodeScanner_(); - } - - if (state.get(Mode.SCAN) && scanType === ScanType.DOCUMENT) { - await this.documentCornerOverylay_.start(); - } else { - await this.documentCornerOverylay_.stop(); - } - - this.onChange(); - } - - /** - * @private - */ - stopBarcodeScanner_() { - this.barcodeScanner_.stop(); - barcodeChip.dismiss(); - state.set(state.State.ENABLE_SCAN_BARCODE, false); - } - - /** - * @param {?ScanType} scanType - * @private - */ - updateOptionsUI_(scanType) { - if (state.get(Mode.SCAN)) { - assert(scanType !== null); - getElemetFromScanType(scanType).checked = true; - } else if (state.get(Mode.PHOTO)) { - this.photoBarcodeOption_.checked = scanType === ScanType.BARCODE; - } - } - - /** - * Stops all scanner and detach from current preview. - * @return {!Promise} - */ - async detachPreview() { - if (this.barcodeScanner_ !== null) { - this.stopBarcodeScanner_(); - this.barcodeScanner_ = null; - } - await this.documentCornerOverylay_.detach(); - this.previewAttached_ = false; - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/scan_options.ts b/ash/webui/camera_app_ui/resources/js/views/camera/scan_options.ts new file mode 100644 index 0000000..8be6eae --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/camera/scan_options.ts
@@ -0,0 +1,180 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assert, assertInstanceof} from '../../assert.js'; +import * as barcodeChip from '../../barcode_chip.js'; +import * as dom from '../../dom.js'; +import {Point} from '../../geometry.js'; +import {sendBarcodeEnabledEvent} from '../../metrics.js'; +import {BarcodeScanner} from '../../models/barcode.js'; +import * as state from '../../state.js'; +import {Mode} from '../../type.js'; +import {assertEnumVariant} from '../../util.js'; + +import {DocumentCornerOverlay} from './document_corner_overlay.js'; + +enum ScanType { + BARCODE = 'barcode', + DOCUMENT = 'document', +} + +function getScanTypeFromElement(el: HTMLInputElement): ScanType { + return assertEnumVariant(ScanType, el.dataset['scantype']); +} + +function getElemetFromScanType(type: ScanType): HTMLInputElement { + return dom.get(`input[data-scantype=${type}]`, HTMLInputElement); +} + +const DEFAULT_SCAN_TYPE = ScanType.DOCUMENT; + +/** + * Controller for the scan options of Camera view. + */ +export class ScanOptions { + /** + * Togglable barcode option in photo mode. + */ + private readonly photoBarcodeOption = + dom.get('#toggle-barcode', HTMLInputElement); + + private readonly scanOptions = + [...dom.getAll('#scan-modes-group [data-scantype]', HTMLInputElement)]; + + /** + * Whether preview have attached as scan frame source. + */ + private previewAttached = false; + + /** + * May be null if preview is not ready. + */ + private barcodeScanner: BarcodeScanner|null = null; + + private readonly documentCornerOverylay: DocumentCornerOverlay; + + /** + * Called when scan option changed. + * TODO(pihsun): Change to use a setter function to set this callback, + * instead of a public property. + */ + onChange = (): void => { + // Do nothing. + }; + + /* + * @param updatePointOfInterest function to update point of interest on the + * stream. + */ + constructor(updatePointOfInterest: (point: Point) => Promise<void>) { + this.documentCornerOverylay = + new DocumentCornerOverlay(updatePointOfInterest); + + [this.photoBarcodeOption, ...this.scanOptions].forEach((opt) => { + opt.addEventListener('click', (evt) => { + if (state.get(state.State.CAMERA_CONFIGURING)) { + evt.preventDefault(); + } + }); + }); + this.photoBarcodeOption.addEventListener('change', () => { + this.updateOption( + this.photoBarcodeOption.checked ? ScanType.BARCODE : null); + }); + this.scanOptions.forEach((opt) => { + opt.addEventListener('change', () => { + if (opt.checked) { + this.updateOption(this.getToggledScanOption()); + } + }); + }); + } + + /** + * @return Returns scan type of checked radio buttons in scan type option + * groups. + */ + private getToggledScanOption(): ScanType { + const checkedEl = this.scanOptions.find(({checked}) => checked); + return checkedEl === undefined ? DEFAULT_SCAN_TYPE : + getScanTypeFromElement(checkedEl); + } + + /** + * Attaches to preview video as source of frames to be scanned. + */ + async attachPreview(video: HTMLVideoElement): Promise<void> { + assert(!this.previewAttached); + this.barcodeScanner = new BarcodeScanner(video, (value) => { + barcodeChip.show(value); + }); + const {deviceId} = assertInstanceof(video.srcObject, MediaStream) + .getVideoTracks()[0] + .getSettings(); + this.documentCornerOverylay.attach(deviceId); + this.previewAttached = true; + const scanType = state.get(Mode.SCAN) ? this.getToggledScanOption() : null; + await this.updateOption(scanType); + } + + isDocumentModeEanbled(): boolean { + return this.documentCornerOverylay.isEnabled(); + } + + /** + * @param scanType Scan type to be enabled, null for no type is + * enabled. + */ + private async updateOption(scanType: ScanType|null) { + if (!this.previewAttached) { + return; + } + assert(this.barcodeScanner !== null); + + this.updateOptionsUI(scanType); + const mode = state.get(state.State.SHOW_SCAN_MODE) ? Mode.SCAN : Mode.PHOTO; + if (state.get(mode) && scanType === ScanType.BARCODE) { + sendBarcodeEnabledEvent(); + this.barcodeScanner.start(); + state.set(state.State.ENABLE_SCAN_BARCODE, true); + } else { + this.stopBarcodeScanner(); + } + + if (state.get(Mode.SCAN) && scanType === ScanType.DOCUMENT) { + await this.documentCornerOverylay.start(); + } else { + await this.documentCornerOverylay.stop(); + } + + this.onChange(); + } + + private stopBarcodeScanner() { + this.barcodeScanner.stop(); + barcodeChip.dismiss(); + state.set(state.State.ENABLE_SCAN_BARCODE, false); + } + + private updateOptionsUI(scanType: ScanType|null) { + if (state.get(Mode.SCAN)) { + assert(scanType !== null); + getElemetFromScanType(scanType).checked = true; + } else if (state.get(Mode.PHOTO)) { + this.photoBarcodeOption.checked = scanType === ScanType.BARCODE; + } + } + + /** + * Stops all scanner and detach from current preview. + */ + async detachPreview(): Promise<void> { + if (this.barcodeScanner !== null) { + this.stopBarcodeScanner(); + this.barcodeScanner = null; + } + await this.documentCornerOverylay.detach(); + this.previewAttached = false; + } +}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/timertick.js b/ash/webui/camera_app_ui/resources/js/views/camera/timertick.ts similarity index 91% rename from ash/webui/camera_app_ui/resources/js/views/camera/timertick.js rename to ash/webui/camera_app_ui/resources/js/views/camera/timertick.ts index 009c127..eeda977 100644 --- a/ash/webui/camera_app_ui/resources/js/views/camera/timertick.js +++ b/ash/webui/camera_app_ui/resources/js/views/camera/timertick.ts
@@ -10,15 +10,14 @@ /** * Handler to cancel the active running timer-ticks. - * @type {?function(): void} */ -let doCancel = null; +let doCancel: (() => void)|null = null; /** * Starts timer ticking if applicable. - * @return {!Promise} Promise for the operation. + * @return Promise for the operation. */ -export function start() { +export function start(): Promise<void> { doCancel = null; if (!state.get(state.State.TIMER)) { return Promise.resolve(); @@ -63,7 +62,7 @@ /** * Cancels active timer ticking if applicable. */ -export function cancel() { +export function cancel(): void { if (doCancel) { doCancel(); doCancel = null;
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/video_encoder_options.js b/ash/webui/camera_app_ui/resources/js/views/camera/video_encoder_options.js deleted file mode 100644 index cdcb678..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/camera/video_encoder_options.js +++ /dev/null
@@ -1,236 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assert, assertInstanceof, assertNumber} from '../../assert.js'; -import * as dom from '../../dom.js'; -import {reportError} from '../../error.js'; -import * as h264 from '../../h264.js'; -import * as state from '../../state.js'; -// eslint-disable-next-line no-unused-vars -import { - ErrorLevel, - ErrorType, - Resolution, -} from '../../type.js'; -import * as util from '../../util.js'; - -/** - * Precondition states to toggle custom video encoder parameters. - * @type {!Array<!state.State>} - */ -const preconditions = [ - state.State.EXPERT, - state.State.CUSTOM_VIDEO_PARAMETERS, -]; - -/** - * Creates a controller for expert mode video encoder options of Camera view. - */ -export class VideoEncoderOptions { - /** - * @param {function(?h264.EncoderParameters): void} onChange Called when video - * encoder option changed. - */ - constructor(onChange) { - /** - * @const {function(?h264.EncoderParameters): void} - * @private - */ - this.onChange_ = onChange; - - /** - * @const {!HTMLSelectElement} - * @private - */ - this.videoProfile_ = dom.get('#video-profile', HTMLSelectElement); - - /** - * @const {!HTMLDivElement} - * @private - */ - this.bitrateSlider_ = dom.get('#bitrate-slider', HTMLDivElement); - - /** - * @const {!HTMLInputElement} - * @private - */ - this.bitrateMultiplierInput_ = - dom.getFrom(this.bitrateSlider_, 'input[type=range]', HTMLInputElement); - - /** - * @const {!HTMLDivElement} - * @private - */ - this.bitrateMultiplerText_ = dom.get('#bitrate-multiplier', HTMLDivElement); - - /** - * @const {!HTMLDivElement} - * @private - */ - this.bitrateText_ = dom.get('#bitrate-number', HTMLDivElement); - - /** - * @type {?Resolution} - * @private - */ - this.resolution_ = null; - - /** - * @type {?number} - * @private - */ - this.fps_ = null; - } - - /** - * @return {boolean} - * @private - */ - get enable_() { - return preconditions.every((s) => state.get(s)) && - this.resolution_ !== null && this.fps_ !== null; - } - - /** - * @return {?h264.Profile} - */ - get selectedProfile_() { - if (this.videoProfile_.value === '') { - return null; - } - return h264.assertProfile(Number(this.videoProfile_.value)); - } - - /** - * @private - */ - disableBitrateSlider_() { - this.bitrateSlider_.hidden = true; - } - - /** - * @private - */ - updateBitrate_() { - if (!this.enable_ || this.selectedProfile_ === null) { - this.onChange_(null); - return; - } - const fps = assertNumber(this.fps_); - const resolution = assertInstanceof(this.resolution_, Resolution); - const profile = this.selectedProfile_; - assert(profile !== null); - const multiplier = this.bitrateMultiplierInput_.valueAsNumber; - this.bitrateMultiplerText_.textContent = 'x' + multiplier; - const bitrate = multiplier * resolution.area; - this.bitrateText_.textContent = `${(bitrate / 1e6).toFixed(1)} Mbps`; - const level = h264.getMinimalLevel(profile, bitrate, fps, resolution); - if (level === null) { - reportError( - ErrorType.NO_AVAILABLE_LEVEL, ErrorLevel.WARNING, - new Error( - `No available level for profile=${ - h264.getProfileName(profile)}, ` + - `resolution=${resolution}, ` + - `fps=${fps}, ` + - `bitrate=${bitrate}`)); - this.onChange_(null); - return; - } - this.onChange_({profile, level, bitrate}); - } - - /** - * @private - */ - updateBitrateRange_() { - if (!this.enable_ || this.selectedProfile_ === null) { - this.disableBitrateSlider_(); - this.onChange_(null); - return; - } - const fps = assertNumber(this.fps_); - const resolution = assertInstanceof(this.resolution_, Resolution); - const profile = this.selectedProfile_; - assert(profile !== null); - - const maxLevel = h264.Levels[h264.Levels.length - 1]; - if (!h264.checkLevelLimits(maxLevel, fps, resolution)) { - reportError( - ErrorType.NO_AVAILABLE_LEVEL, ErrorLevel.WARNING, - new Error( - `No available level for profile=${ - h264.getProfileName(profile)}, ` + - `resolution=${resolution}, ` + - `fps=${fps}`)); - this.disableBitrateSlider_(); - this.onChange_(null); - return; - } - const maxBitrate = h264.getMaxBitrate(profile, maxLevel); - - // The slider is used to select bitrate multiplier with respect to - // resolution pixels. It comply with chrome's logic of selecting default - // bitrate with multiplier 2. Limits multiplier up to 15 for confining - // result video size. - const max = Math.min(Math.floor(maxBitrate / resolution.area), 15); - this.bitrateMultiplierInput_.max = max.toString(); - this.bitrateMultiplierInput_.value = - (this.bitrateMultiplierInput_.valueAsNumber || Math.min(max, 2)) - .toString(); - this.updateBitrate_(); - this.bitrateSlider_.hidden = false; - } - - /** - * @private - */ - initBitrateSlider_() { - for (const evt of ['input', 'change']) { - this.bitrateMultiplierInput_.addEventListener( - evt, () => this.updateBitrate_()); - } - } - - /** - * @private - */ - initVideoProfile_() { - // TODO(b/151047420): Remove options and use the largest supported profile. - for (const profile of h264.profileValues) { - const tpl = util.instantiateTemplate('#video-profile-option-template'); - const option = dom.getFrom(tpl, 'option', HTMLOptionElement); - option.value = profile.toString(); - option.textContent = h264.getProfileName(profile); - this.videoProfile_.appendChild(option); - } - - this.videoProfile_.addEventListener( - 'change', () => this.updateBitrateRange_()); - } - - /** - * @public - */ - initialize() { - this.initVideoProfile_(); - this.initBitrateSlider_(); - - for (const s of preconditions) { - state.addObserver(s, () => this.updateBitrateRange_()); - } - } - - /** - * @param {!Resolution} resolution - * @param {number} fps - */ - updateValues(resolution, fps) { - this.resolution_ = resolution; - this.fps_ = fps; - // TODO(b/151047420): Restore profile/bitrate preference for current camera, - // resolution, fps. - this.updateBitrateRange_(); - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/video_encoder_options.ts b/ash/webui/camera_app_ui/resources/js/views/camera/video_encoder_options.ts new file mode 100644 index 0000000..017a059 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/camera/video_encoder_options.ts
@@ -0,0 +1,168 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assert, assertInstanceof, assertNumber} from '../../assert.js'; +import * as dom from '../../dom.js'; +import {reportError} from '../../error.js'; +import * as h264 from '../../h264.js'; +import * as state from '../../state.js'; +import { + ErrorLevel, + ErrorType, + Resolution, +} from '../../type.js'; +import * as util from '../../util.js'; + +/** + * Precondition states to toggle custom video encoder parameters. + */ +const preconditions = [ + state.State.EXPERT, + state.State.CUSTOM_VIDEO_PARAMETERS, +]; + +/** + * Creates a controller for expert mode video encoder options of Camera view. + */ +export class VideoEncoderOptions { + private readonly videoProfile = dom.get('#video-profile', HTMLSelectElement); + private readonly bitrateSlider = dom.get('#bitrate-slider', HTMLDivElement); + private readonly bitrateMultiplierInput: HTMLInputElement; + private readonly bitrateMultiplerText = + dom.get('#bitrate-multiplier', HTMLDivElement); + private readonly bitrateText = dom.get('#bitrate-number', HTMLDivElement); + private resolution: Resolution|null = null; + private fps: number|null = null; + + /** + * @param onChange Called when video encoder option changed. + */ + constructor( + private readonly onChange: (param: h264.EncoderParameters|null) => void) { + this.bitrateMultiplierInput = + dom.getFrom(this.bitrateSlider, 'input[type=range]', HTMLInputElement); + } + + private get enable(): boolean { + return preconditions.every((s) => state.get(s)) && + this.resolution !== null && this.fps !== null; + } + + private get selectedProfile(): h264.Profile|null { + if (this.videoProfile.value === '') { + return null; + } + return h264.assertProfile(Number(this.videoProfile.value)); + } + + private disableBitrateSlider() { + this.bitrateSlider.hidden = true; + } + + private updateBitrate() { + if (!this.enable || this.selectedProfile === null) { + this.onChange(null); + return; + } + const fps = assertNumber(this.fps); + const resolution = assertInstanceof(this.resolution, Resolution); + const profile = this.selectedProfile; + assert(profile !== null); + const multiplier = this.bitrateMultiplierInput.valueAsNumber; + this.bitrateMultiplerText.textContent = 'x' + multiplier; + const bitrate = multiplier * resolution.area; + this.bitrateText.textContent = `${(bitrate / 1e6).toFixed(1)} Mbps`; + const level = h264.getMinimalLevel(profile, bitrate, fps, resolution); + if (level === null) { + reportError( + ErrorType.NO_AVAILABLE_LEVEL, ErrorLevel.WARNING, + new Error( + `No available level for profile=${ + h264.getProfileName(profile)}, ` + + `resolution=${resolution}, ` + + `fps=${fps}, ` + + `bitrate=${bitrate}`)); + this.onChange(null); + return; + } + this.onChange({profile, level, bitrate}); + } + + private updateBitrateRange() { + if (!this.enable || this.selectedProfile === null) { + this.disableBitrateSlider(); + this.onChange(null); + return; + } + const fps = assertNumber(this.fps); + const resolution = assertInstanceof(this.resolution, Resolution); + const profile = this.selectedProfile; + assert(profile !== null); + + const maxLevel = h264.Levels[h264.Levels.length - 1]; + if (!h264.checkLevelLimits(maxLevel, fps, resolution)) { + reportError( + ErrorType.NO_AVAILABLE_LEVEL, ErrorLevel.WARNING, + new Error( + `No available level for profile=${ + h264.getProfileName(profile)}, ` + + `resolution=${resolution}, ` + + `fps=${fps}`)); + this.disableBitrateSlider(); + this.onChange(null); + return; + } + const maxBitrate = h264.getMaxBitrate(profile, maxLevel); + + // The slider is used to select bitrate multiplier with respect to + // resolution pixels. It comply with chrome's logic of selecting default + // bitrate with multiplier 2. Limits multiplier up to 15 for confining + // result video size. + const max = Math.min(Math.floor(maxBitrate / resolution.area), 15); + this.bitrateMultiplierInput.max = max.toString(); + this.bitrateMultiplierInput.value = + (this.bitrateMultiplierInput.valueAsNumber || Math.min(max, 2)) + .toString(); + this.updateBitrate(); + this.bitrateSlider.hidden = false; + } + + private initBitrateSlider() { + for (const evt of ['input', 'change']) { + this.bitrateMultiplierInput.addEventListener( + evt, () => this.updateBitrate()); + } + } + + private initVideoProfile() { + // TODO(b/151047420): Remove options and use the largest supported profile. + for (const profile of h264.profileValues) { + const tpl = util.instantiateTemplate('#video-profile-option-template'); + const option = dom.getFrom(tpl, 'option', HTMLOptionElement); + option.value = profile.toString(); + option.textContent = h264.getProfileName(profile); + this.videoProfile.appendChild(option); + } + + this.videoProfile.addEventListener( + 'change', () => this.updateBitrateRange()); + } + + initialize(): void { + this.initVideoProfile(); + this.initBitrateSlider(); + + for (const s of preconditions) { + state.addObserver(s, () => this.updateBitrateRange()); + } + } + + updateValues(resolution: Resolution, fps: number): void { + this.resolution = resolution; + this.fps = fps; + // TODO(b/151047420): Restore profile/bitrate preference for current camera, + // resolution, fps. + this.updateBitrateRange(); + } +}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera_intent.js b/ash/webui/camera_app_ui/resources/js/views/camera_intent.js deleted file mode 100644 index e7ee685..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/camera_intent.js +++ /dev/null
@@ -1,186 +0,0 @@ -// Copyright (c) 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// eslint-disable-next-line no-unused-vars -import {assert, assertNotReached} from '../assert.js'; -import { - PhotoConstraintsPreferrer, // eslint-disable-line no-unused-vars - VideoConstraintsPreferrer, // eslint-disable-line no-unused-vars -} from '../device/constraints_preferrer.js'; -// eslint-disable-next-line no-unused-vars -import {DeviceInfoUpdater} from '../device/device_info_updater.js'; -import {I18nString} from '../i18n_string.js'; -// eslint-disable-next-line no-unused-vars -import {Intent} from '../intent.js'; -import * as metrics from '../metrics.js'; -// eslint-disable-next-line no-unused-vars -import {FileAccessEntry} from '../models/file_system_access_entry.js'; -// eslint-disable-next-line no-unused-vars -import {ResultSaver} from '../models/result_saver.js'; -import {VideoSaver} from '../models/video_saver.js'; -// eslint-disable-next-line no-unused-vars -import {PerfLogger} from '../perf.js'; -import {scaleImage} from '../thumbnailer.js'; -// eslint-disable-next-line no-unused-vars -import {Mode, Resolution} from '../type.js'; -import * as util from '../util.js'; - -import {Camera} from './camera.js'; -// eslint-disable-next-line no-unused-vars -import {PhotoResult, VideoResult} from './camera/mode/index.js'; -import * as review from './review.js'; - -/** - * The maximum number of pixels in the downscaled intent photo result. Reference - * from GCA: https://goto.google.com/gca-inline-bitmap-max-pixel-num - * @type {number} - * @const - */ -const DOWNSCALE_INTENT_MAX_PIXEL_NUM = 50 * 1024; - -/** - * @typedef {{ - * resolution: !Resolution, - * duration?: number, - * }} - */ -let MetricArgs; // eslint-disable-line no-unused-vars - -/** - * Camera-intent-view controller. - */ -export class CameraIntent extends Camera { - /** - * @param {!Intent} intent - * @param {!DeviceInfoUpdater} infoUpdater - * @param {!PhotoConstraintsPreferrer} photoPreferrer - * @param {!VideoConstraintsPreferrer} videoPreferrer - * @param {!Mode} mode - * @param {!PerfLogger} perfLogger - */ - constructor( - intent, infoUpdater, photoPreferrer, videoPreferrer, mode, perfLogger) { - const resultSaver = /** @type {!ResultSaver} */ ({ - savePhoto: async (blob) => { - if (intent.shouldDownScale) { - const image = await util.blobToImage(blob); - const ratio = Math.sqrt( - DOWNSCALE_INTENT_MAX_PIXEL_NUM / (image.width * image.height)); - blob = await scaleImage( - blob, Math.floor(image.width * ratio), - Math.floor(image.height * ratio)); - } - const buf = await blob.arrayBuffer(); - await this.intent_.appendData(new Uint8Array(buf)); - }, - startSaveVideo: async (outputVideoRotation) => { - return VideoSaver.createForIntent(intent, outputVideoRotation); - }, - finishSaveVideo: async (video) => { - this.videoResultFile_ = await video.endWrite(); - }, - saveGif: () => { - assertNotReached(); - }, - }); - super( - resultSaver, infoUpdater, photoPreferrer, videoPreferrer, mode, - perfLogger, /* facing= */ null); - - /** - * @type {!Intent} - * @private - */ - this.intent_ = intent; - - /** - * @type {?PhotoResult} - * @private - */ - this.photoResult_ = null; - - /** - * @type {?FileAccessEntry} - * @private - */ - this.videoResultFile_ = null; - } - - /** - * @param {!MetricArgs} metricArgs - * @return {!Promise<void>} - * @private - */ - reviewIntentResult_(metricArgs) { - return this.prepareReview(async () => { - const confirmed = await this.review.startReview(new review.OptionGroup({ - template: review.ButtonGroupTemplate.intent, - options: [ - new review.Option( - { - label: I18nString.CONFIRM_REVIEW_BUTTON, - templateId: 'review-intent-button-template', - }, - {exitValue: true}), - new review.Option( - { - label: I18nString.CANCEL_REVIEW_BUTTON, - templateId: 'review-intent-button-template', - }, - {exitValue: false}), - ], - - })); - metrics.sendCaptureEvent({ - facing: this.facingMode, - ...metricArgs, - intentResult: confirmed ? metrics.IntentResultType.CONFIRMED : - metrics.IntentResultType.CANCELED, - shutterType: this.shutterType, - }); - if (confirmed) { - await this.intent_.finish(); - - const appWindow = window.appWindow; - if (appWindow === null) { - window.close(); - } else { - // For test session, we notify tests and let test close the window for - // us. - await appWindow.notifyClosingItself(); - } - } else { - await this.intent_.clearData(); - } - }); - } - - /** - * @override - */ - async onPhotoCaptureDone(pendingPhotoResult) { - await super.onPhotoCaptureDone(pendingPhotoResult); - const {blob, resolution} = await pendingPhotoResult; - await this.review.setReviewPhoto(blob); - await this.reviewIntentResult_({resolution}); - } - - /** - * @override - */ - async onVideoCaptureDone(videoResult) { - await super.onVideoCaptureDone(videoResult); - assert(this.videoResultFile_ !== null); - await this.review.setReviewVideo(this.videoResultFile_); - await this.reviewIntentResult_( - {resolution: videoResult.resolution, duration: videoResult.duration}); - } - - /** - * @override - */ - async startWithDevice(deviceId) { - return this.startWithMode(deviceId, this.defaultMode); - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera_intent.ts b/ash/webui/camera_app_ui/resources/js/views/camera_intent.ts new file mode 100644 index 0000000..a466c7a --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/camera_intent.ts
@@ -0,0 +1,140 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assert, assertNotReached} from '../assert.js'; +import { + PhotoConstraintsPreferrer, + VideoConstraintsPreferrer, +} from '../device/constraints_preferrer.js'; +import {DeviceInfoUpdater} from '../device/device_info_updater.js'; +import {I18nString} from '../i18n_string.js'; +import {Intent} from '../intent.js'; +import * as metrics from '../metrics.js'; +import {FileAccessEntry} from '../models/file_system_access_entry.js'; +import {VideoSaver} from '../models/video_saver.js'; +import {PerfLogger} from '../perf.js'; +import {scaleImage} from '../thumbnailer.js'; +import {Mode, Resolution} from '../type.js'; +import * as util from '../util.js'; + +import {Camera} from './camera.js'; +import {PhotoResult, VideoResult} from './camera/mode/index.js'; +import * as review from './review.js'; + +/** + * The maximum number of pixels in the downscaled intent photo result. Reference + * from GCA: https://goto.google.com/gca-inline-bitmap-max-pixel-num + */ +const DOWNSCALE_INTENT_MAX_PIXEL_NUM = 50 * 1024; + +interface MetricArgs { + resolution: Resolution; + duration?: number; +} + +/** + * Camera-intent-view controller. + */ +export class CameraIntent extends Camera { + private videoResultFile: FileAccessEntry|null = null; + + constructor( + private readonly intent: Intent, + infoUpdater: DeviceInfoUpdater, + photoPreferrer: PhotoConstraintsPreferrer, + videoPreferrer: VideoConstraintsPreferrer, + mode: Mode, + perfLogger: PerfLogger, + ) { + super( + { + savePhoto: async (blob) => { + if (intent.shouldDownScale) { + const image = await util.blobToImage(blob); + const ratio = Math.sqrt( + DOWNSCALE_INTENT_MAX_PIXEL_NUM / + (image.width * image.height)); + blob = await scaleImage( + blob, Math.floor(image.width * ratio), + Math.floor(image.height * ratio)); + } + const buf = await blob.arrayBuffer(); + await this.intent.appendData(new Uint8Array(buf)); + }, + startSaveVideo: async (outputVideoRotation) => { + return VideoSaver.createForIntent(intent, outputVideoRotation); + }, + finishSaveVideo: async (video) => { + this.videoResultFile = await video.endWrite(); + }, + saveGif: () => { + assertNotReached(); + }, + }, + infoUpdater, photoPreferrer, videoPreferrer, mode, perfLogger, + /* facing= */ null); + } + + private reviewIntentResult(metricArgs: MetricArgs): Promise<void> { + return this.prepareReview(async () => { + const confirmed = await this.review.startReview(new review.OptionGroup({ + template: review.ButtonGroupTemplate.intent, + options: [ + new review.Option( + { + label: I18nString.CONFIRM_REVIEW_BUTTON, + templateId: 'review-intent-button-template', + }, + {exitValue: true}), + new review.Option( + { + label: I18nString.CANCEL_REVIEW_BUTTON, + templateId: 'review-intent-button-template', + }, + {exitValue: false}), + ], + })); + metrics.sendCaptureEvent({ + facing: this.facingMode, + ...metricArgs, + intentResult: confirmed ? metrics.IntentResultType.CONFIRMED : + metrics.IntentResultType.CANCELED, + shutterType: this.shutterType, + }); + if (confirmed) { + await this.intent.finish(); + const appWindow = window.appWindow; + if (appWindow === null) { + window.close(); + } else { + // For test session, we notify tests and let test close the window for + // us. + await appWindow.notifyClosingItself(); + } + } else { + await this.intent.clearData(); + } + }); + } + + async onPhotoCaptureDone(pendingPhotoResult: Promise<PhotoResult>): + Promise<void> { + await super.onPhotoCaptureDone(pendingPhotoResult); + const {blob, resolution} = await pendingPhotoResult; + await this.review.setReviewPhoto(blob); + await this.reviewIntentResult({resolution}); + } + + async onVideoCaptureDone(videoResult: VideoResult): Promise<void> { + await super.onVideoCaptureDone(videoResult); + assert(this.videoResultFile !== null); + await this.review.setReviewVideo(this.videoResultFile); + await this.reviewIntentResult( + {resolution: videoResult.resolution, duration: videoResult.duration}); + } + + async startWithDevice(deviceId: string): Promise<boolean> { + return this.startWithMode(deviceId, this.defaultMode); + } +}
diff --git a/ash/webui/camera_app_ui/resources/js/views/dialog.js b/ash/webui/camera_app_ui/resources/js/views/dialog.js deleted file mode 100644 index 5456109..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/dialog.js +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assertString} from '../assert.js'; -import * as dom from '../dom.js'; -import {ViewName} from '../type.js'; // eslint-disable-line no-unused-vars - -import {View} from './view.js'; - -/** - * Creates the Dialog view controller. - */ -export class Dialog extends View { - /** - * @param {!ViewName} name View name of the dialog. - */ - constructor(name) { - super( - name, - {dismissByEsc: true, defaultFocusSelector: '.dialog-positive-button'}); - - /** - * @type {!HTMLButtonElement} - * @private - */ - this.positiveButton_ = - dom.getFrom(this.root, '.dialog-positive-button', HTMLButtonElement); - - /** - * @type {?HTMLButtonElement} - * @private - */ - this.negativeButton_ = (() => { - const btn = dom.getAllFrom( - this.root, '.dialog-negative-button', HTMLButtonElement)[0]; - return btn || null; - })(); - - /** - * @type {!HTMLElement} - * @private - */ - this.messageHolder_ = - dom.getFrom(this.root, '.dialog-msg-holder', HTMLElement); - - this.positiveButton_.addEventListener('click', () => this.leave(true)); - if (this.negativeButton_ !== null) { - this.negativeButton_.addEventListener('click', () => this.leave()); - } - } - - /** - * @override - */ - entering({message = undefined, cancellable = false} = {}) { - if (message !== undefined) { - this.messageHolder_.textContent = assertString(message); - } - if (this.negativeButton_ !== null) { - this.negativeButton_.hidden = !cancellable; - } - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/dialog.ts b/ash/webui/camera_app_ui/resources/js/views/dialog.ts new file mode 100644 index 0000000..b4bfcd6e --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/dialog.ts
@@ -0,0 +1,53 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assertString} from '../assert.js'; +import * as dom from '../dom.js'; +import {ViewName} from '../type.js'; + +import {DialogEnterOptions, View} from './view.js'; + +/** + * Creates the Dialog view controller. + */ +export class Dialog extends View { + private positiveButton: HTMLButtonElement; + private negativeButton: HTMLButtonElement|null; + private messageHolder: HTMLElement; + + /** + * @param name View name of the dialog. + */ + constructor(name: ViewName) { + super( + name, + {dismissByEsc: true, defaultFocusSelector: '.dialog-positive-button'}); + + this.positiveButton = + dom.getFrom(this.root, '.dialog-positive-button', HTMLButtonElement); + + this.negativeButton = (() => { + const btn = dom.getAllFrom( + this.root, '.dialog-negative-button', HTMLButtonElement)[0]; + return btn || null; + })(); + + this.messageHolder = + dom.getFrom(this.root, '.dialog-msg-holder', HTMLElement); + + this.positiveButton.addEventListener('click', () => this.leave(true)); + if (this.negativeButton !== null) { + this.negativeButton.addEventListener('click', () => this.leave()); + } + } + + entering({message, cancellable = false}: DialogEnterOptions = {}): void { + if (message !== undefined) { + this.messageHolder.textContent = assertString(message); + } + if (this.negativeButton !== null) { + this.negativeButton.hidden = !cancellable; + } + } +}
diff --git a/ash/webui/camera_app_ui/resources/js/views/view.ts b/ash/webui/camera_app_ui/resources/js/views/view.ts index 75cf32b..7911b32 100644 --- a/ash/webui/camera_app_ui/resources/js/views/view.ts +++ b/ash/webui/camera_app_ui/resources/js/views/view.ts
@@ -11,7 +11,7 @@ * message for message of the dialog view, cancellable for whether the dialog * view is cancellable. */ -interface DialogEnterOptions { +export interface DialogEnterOptions { message?: string; cancellable?: boolean; } @@ -40,6 +40,9 @@ } } +// TODO(pihsun): After we migrate all files into TypeScript, we can have some +// sort of "global" view registration, so we can enforce the enter / leave type +// at compile time. export type EnterOptions = DialogEnterOptions|WarningEnterOptions|PTZPanelOptions;
diff --git a/ash/webui/camera_app_ui/resources/js/views/warning.js b/ash/webui/camera_app_ui/resources/js/views/warning.js deleted file mode 100644 index 0662c28..0000000 --- a/ash/webui/camera_app_ui/resources/js/views/warning.js +++ /dev/null
@@ -1,98 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assert, assertString} from '../assert.js'; -import * as dom from '../dom.js'; -import {I18nString} from '../i18n_string.js'; -import * as loadTimeData from '../models/load_time_data.js'; -import {ViewName} from '../type.js'; - -import {View} from './view.js'; - -/** - * The type of warning. - * @enum {string} - */ -export const WarningType = { - CAMERA_PAUSED: I18nString.ERROR_MSG_CAMERA_PAUSED, - FILESYSTEM_FAILURE: I18nString.ERROR_MSG_FILE_SYSTEM_FAILED, - NO_CAMERA: I18nString.ERROR_MSG_NO_CAMERA, -}; - -/** - * @param {*} value The value to check. - * @return {!I18nString} - */ -function assertI18nString(value) { - assertString(value); - assert( - Object.values(I18nString).includes(value), - `${value} is not a valid I18nString`); - return /** @type {I18nString} */ (value); -} - -/** - * Creates the warning-view controller. - */ -export class Warning extends View { - /** - * @public - */ - constructor() { - super(ViewName.WARNING); - - /** - * @type {!Array<!I18nString>} - * @private - */ - this.errorNames_ = []; - } - - /** - * Updates the error message for the latest error-name in the stack. - * @private - */ - updateMessage_() { - const message = this.errorNames_[this.errorNames_.length - 1]; - dom.get('#error-msg', HTMLElement).textContent = - loadTimeData.getI18nMessage(message); - } - - /** - * @override - */ - entering(name) { - name = assertI18nString(name); - - // Remove the error-name from the stack to avoid duplication. Then make the - // error-name the latest one to show its message. - const index = this.errorNames_.indexOf(name); - if (index !== -1) { - this.errorNames_.splice(index, 1); - } - this.errorNames_.push(name); - this.updateMessage_(); - } - - /** - * @override - */ - leaving(...args) { - // Recovered error-name for leaving the view. - const name = assertI18nString(args[0]); - - // Remove the recovered error from the stack but don't leave the view until - // there is no error left in the stack. - const index = this.errorNames_.indexOf(name); - if (index !== -1) { - this.errorNames_.splice(index, 1); - } - if (this.errorNames_.length) { - this.updateMessage_(); - return false; - } - dom.get('#error-msg', HTMLElement).textContent = ''; - return true; - } -}
diff --git a/ash/webui/camera_app_ui/resources/js/views/warning.ts b/ash/webui/camera_app_ui/resources/js/views/warning.ts new file mode 100644 index 0000000..e64e55cd --- /dev/null +++ b/ash/webui/camera_app_ui/resources/js/views/warning.ts
@@ -0,0 +1,77 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assertString} from '../assert.js'; +import * as dom from '../dom.js'; +import {I18nString} from '../i18n_string.js'; +import * as loadTimeData from '../models/load_time_data.js'; +import {ViewName} from '../type.js'; +import {assertEnumVariant} from '../util.js'; + +import {EnterOptions, View} from './view.js'; + +/** + * The type of warning. + */ +export const WarningType = { + CAMERA_PAUSED: I18nString.ERROR_MSG_CAMERA_PAUSED, + FILESYSTEM_FAILURE: I18nString.ERROR_MSG_FILE_SYSTEM_FAILED, + NO_CAMERA: I18nString.ERROR_MSG_NO_CAMERA, +}; + +function assertI18nString(value: unknown): I18nString { + const stringValue = assertString(value); + return assertEnumVariant(I18nString, stringValue); +} + +/** + * Creates the warning-view controller. + */ +export class Warning extends View { + private readonly errorNames: I18nString[] = []; + + constructor() { + super(ViewName.WARNING); + } + + /** + * Updates the error message for the latest error-name in the stack. + */ + private updateMessage() { + const message = this.errorNames[this.errorNames.length - 1]; + dom.get('#error-msg', HTMLElement).textContent = + loadTimeData.getI18nMessage(message); + } + + entering(nameOption?: EnterOptions): void { + const name = assertI18nString(nameOption); + + // Remove the error-name from the stack to avoid duplication. Then make the + // error-name the latest one to show its message. + const index = this.errorNames.indexOf(name); + if (index !== -1) { + this.errorNames.splice(index, 1); + } + this.errorNames.push(name); + this.updateMessage(); + } + + leaving(condition?: unknown): boolean { + // Recovered error-name for leaving the view. + const name = assertI18nString(condition); + + // Remove the recovered error from the stack but don't leave the view until + // there is no error left in the stack. + const index = this.errorNames.indexOf(name); + if (index !== -1) { + this.errorNames.splice(index, 1); + } + if (this.errorNames.length) { + this.updateMessage(); + return false; + } + dom.get('#error-msg', HTMLElement).textContent = ''; + return true; + } +}
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html index 0bdfc39..1faf0ad 100644 --- a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html +++ b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html
@@ -27,18 +27,19 @@ width: 95%; } </style> -<template is="dom-if" if="[[shouldShowUpdateDialog_(dialogState)]]" restamp> +<template is="dom-if" + if="[[shouldShowUpdateDialog_(installationProgress.state)]]" restamp> <cr-dialog id="updateDialog" show-on-attach on-close="closeDialog_"> <div slot="title" id="updateDialogTitle" class="firmware-dialog-title-font"> - [[computeUpdateDialogTitle_(dialogState)]] + [[computeUpdateDialogTitle_(installationProgress.state)]] </div> <div slot="body" class="firmware-dialog-body-font"> <div> - [[computeUpdateDialogBodyText_(dialogState)]] + [[computeUpdateDialogBodyText_(installationProgress.state)]] </div> </div> - <div slot="footer" hidden$="[[!isUpdateInProgress_(dialogState)]]"> + <div slot="footer" hidden$="[[!isUpdateInProgress_(installationProgress.state)]]"> <label id="progress" class="firmware-dialog-installing-font"> [[computeProgressText_(installationProgress.percentage)]] </label> @@ -48,7 +49,7 @@ </paper-progress> </div> <div slot="button-container" - hidden$="[[isUpdateInProgress_(dialogState)]]"> + hidden$="[[isUpdateInProgress_(installationProgress.state)]]"> <cr-button class="action-button" on-click="closeDialog_" id="updateDoneButton">
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js index 6749573..12ac9e1 100644 --- a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js +++ b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js
@@ -19,13 +19,6 @@ import {getUpdateProvider} from './mojo_interface_provider.js'; import {mojoString16ToString} from './mojo_utils.js'; -/** @enum {number} */ -export const DialogState = { - CLOSED: 0, - UPDATING: 2, - UPDATE_DONE: 3, -}; - /** * @fileoverview * 'firmware-update-dialog' displays information related to a firmware update. @@ -57,17 +50,10 @@ type: Object, }, - /** @type {?InstallationProgress} */ + /** @type {!InstallationProgress} */ installationProgress: { type: Object, }, - - /** @type {!DialogState} */ - dialogState: { - type: Number, - value: DialogState.CLOSED, - computed: 'onStateChanged_(installationProgress.state)' - }, }; } @@ -109,28 +95,10 @@ } /** @protected */ - onStateChanged_() { - if (!this.installationProgress) { - return DialogState.CLOSED; - } - // TODO(michaelcheco): Handle restarting and failed states. - switch (this.installationProgress.state) { - case UpdateState.kUnknown: - case UpdateState.kIdle: - return DialogState.CLOSED; - case UpdateState.kUpdating: - case UpdateState.kRestarting: - return DialogState.UPDATING; - case UpdateState.kFailed: - case UpdateState.kSuccess: - return DialogState.UPDATE_DONE; - } - } - - /** @protected */ closeDialog_() { - this.dialogState = DialogState.CLOSED; - this.installationProgress = null; + // Resetting |installationProgress| triggers a call to + // |shouldShowUpdateDialog_|. + this.installationProgress = {percentage: 0, state: UpdateState.kIdle}; } /** @protected */ @@ -165,8 +133,14 @@ * @return {boolean} */ shouldShowUpdateDialog_() { - return this.isUpdateInProgress_() || - this.dialogState === DialogState.UPDATE_DONE; + /** @type {!Array<!UpdateState>} */ + const activeDialogStates = [ + UpdateState.kUpdating, + UpdateState.kRestarting, + UpdateState.kFailed, + UpdateState.kSuccess, + ]; + return activeDialogStates.includes(this.installationProgress.state); } /** @@ -185,7 +159,7 @@ * @return {boolean} */ isUpdateInProgress_() { - return this.dialogState === DialogState.UPDATING; + return this.installationProgress.state === UpdateState.kUpdating; } /** @@ -213,7 +187,7 @@ */ computeUpdateDialogBodyText_() { const {deviceName, deviceVersion} = this.update; - return this.dialogState === DialogState.UPDATE_DONE ? + return this.installationProgress.state === UpdateState.kSuccess ? this.i18n( 'hasBeenUpdated', mojoString16ToString(deviceName), deviceVersion) : this.i18n('updatingInfo');
diff --git a/base/message_loop/message_pump_for_io.h b/base/message_loop/message_pump_for_io.h index 1b65f2a8..b6cc2ddb 100644 --- a/base/message_loop/message_pump_for_io.h +++ b/base/message_loop/message_pump_for_io.h
@@ -16,7 +16,7 @@ #include "base/message_loop/message_pump_io_ios.h" #elif defined(OS_MAC) #include "base/message_loop/message_pump_kqueue.h" -#elif defined(OS_NACL_SFI) +#elif defined(OS_NACL) #include "base/message_loop/message_pump_default.h" #elif defined(OS_FUCHSIA) #include "base/message_loop/message_pump_fuchsia.h" @@ -33,7 +33,7 @@ using MessagePumpForIO = MessagePumpIOSForIO; #elif defined(OS_MAC) using MessagePumpForIO = MessagePumpKqueue; -#elif defined(OS_NACL_SFI) +#elif defined(OS_NACL) using MessagePumpForIO = MessagePumpDefault; #elif defined(OS_FUCHSIA) using MessagePumpForIO = MessagePumpFuchsia;
diff --git a/base/message_loop/message_pump_glib_unittest.cc b/base/message_loop/message_pump_glib_unittest.cc index 2a05e5b..3fcbde3 100644 --- a/base/message_loop/message_pump_glib_unittest.cc +++ b/base/message_loop/message_pump_glib_unittest.cc
@@ -554,6 +554,9 @@ } void TearDown() override { + // Wait for the IO thread to exit before closing FDs which may have been + // passed to it. + io_thread_.Stop(); if (IGNORE_EINTR(close(pipefds_[0])) < 0) PLOG(ERROR) << "close"; if (IGNORE_EINTR(close(pipefds_[1])) < 0)
diff --git a/base/message_loop/message_pump_unittest.cc b/base/message_loop/message_pump_unittest.cc index fe86036..eb6c16e 100644 --- a/base/message_loop/message_pump_unittest.cc +++ b/base/message_loop/message_pump_unittest.cc
@@ -24,7 +24,7 @@ #include <windows.h> #endif -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) +#if defined(OS_POSIX) && !defined(OS_NACL) #include "base/message_loop/message_pump_libevent.h" #endif @@ -79,7 +79,7 @@ void AddPostDoWorkExpectations( testing::StrictMock<MockMessagePumpDelegate>& delegate) { -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) +#if defined(OS_POSIX) && !defined(OS_NACL) if ((GetParam() == MessagePumpType::UI && std::is_same<MessagePumpForUI, MessagePumpLibevent>::value) || (GetParam() == MessagePumpType::IO && @@ -89,7 +89,7 @@ EXPECT_CALL(delegate, OnBeginWorkItem); EXPECT_CALL(delegate, OnEndWorkItem); } -#endif // defined(OS_POSIX) && !defined(OS_NACL_SFI) +#endif // defined(OS_POSIX) && !defined(OS_NACL) } std::unique_ptr<MessagePump> message_pump_;
diff --git a/base/task/current_thread.cc b/base/task/current_thread.cc index 9e033bdc..dbbf82e 100644 --- a/base/task/current_thread.cc +++ b/base/task/current_thread.cc
@@ -204,7 +204,7 @@ return static_cast<MessagePumpForIO*>(current_->GetMessagePump()); } -#if !defined(OS_NACL_SFI) +#if !defined(OS_NACL) #if defined(OS_WIN) HRESULT CurrentIOThread::RegisterIOHandler( @@ -244,7 +244,7 @@ } #endif -#endif // !defined(OS_NACL_SFI) +#endif // !defined(OS_NACL) #if defined(OS_FUCHSIA) // Additional watch API for native platform resources.
diff --git a/base/task/current_thread.h b/base/task/current_thread.h index 7ca1e0e..5da7cf2a 100644 --- a/base/task/current_thread.h +++ b/base/task/current_thread.h
@@ -266,7 +266,7 @@ CurrentIOThread* operator->() { return this; } -#if !defined(OS_NACL_SFI) +#if !defined(OS_NACL) #if defined(OS_WIN) // Please see MessagePumpWin for definitions of these methods. @@ -298,7 +298,7 @@ MessagePumpForIO::ZxHandleWatcher* delegate); #endif // defined(OS_FUCHSIA) -#endif // !defined(OS_NACL_SFI) +#endif // !defined(OS_NACL) private: explicit CurrentIOThread(
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc index 44e3c7f..e517776 100644 --- a/base/task/thread_pool/thread_pool_impl.cc +++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -168,7 +168,7 @@ // FileDescriptorWatcher in the scope in which tasks run. ServiceThread::Options service_thread_options; service_thread_options.message_pump_type = -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) +#if defined(OS_POSIX) && !defined(OS_NACL) MessagePumpType::IO; #else MessagePumpType::DEFAULT; @@ -178,11 +178,11 @@ if (g_synchronous_thread_start_for_testing) service_thread_.WaitUntilThreadStarted(); -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) +#if defined(OS_POSIX) && !defined(OS_NACL) // Needs to happen after starting the service thread to get its // task_runner(). task_tracker_->set_io_thread_task_runner(service_thread_.task_runner()); -#endif // defined(OS_POSIX) && !defined(OS_NACL_SFI) +#endif // defined(OS_POSIX) && !defined(OS_NACL) // Update the CanRunPolicy based on |has_disable_best_effort_switch_|. UpdateCanRunPolicy();
diff --git a/base/task/thread_pool/thread_pool_impl.h b/base/task/thread_pool/thread_pool_impl.h index a56392e7..2708fc7 100644 --- a/base/task/thread_pool/thread_pool_impl.h +++ b/base/task/thread_pool/thread_pool_impl.h
@@ -31,7 +31,7 @@ #include "base/task/updateable_sequenced_task_runner.h" #include "build/build_config.h" -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) +#if defined(OS_POSIX) && !defined(OS_NACL) #include "base/task/thread_pool/task_tracker_posix.h" #include "third_party/abseil-cpp/absl/types/optional.h" #endif @@ -51,7 +51,7 @@ public PooledTaskRunnerDelegate { public: using TaskTrackerImpl = -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) +#if defined(OS_POSIX) && !defined(OS_NACL) TaskTrackerPosix; #else TaskTracker;
diff --git a/build/android/pylib/local/device/local_device_test_run.py b/build/android/pylib/local/device/local_device_test_run.py index 3fa75c3..3a27c84 100644 --- a/build/android/pylib/local/device/local_device_test_run.py +++ b/build/android/pylib/local/device/local_device_test_run.py
@@ -3,6 +3,7 @@ # found in the LICENSE file. import fnmatch +import hashlib import logging import posixpath import signal @@ -274,10 +275,10 @@ # Sort by hash so we don't put all tests in a slow suite in the same # partition. def _SortTests(self, tests): - return sorted( - tests, - key=lambda t: hash( - self._GetUniqueTestName(t[0] if isinstance(t, list) else t))) + return sorted(tests, + key=lambda t: hashlib.sha256( + self._GetUniqueTestName(t[0] if isinstance(t, list) else t + ).encode()).hexdigest()) # Partition tests evenly into |num_desired_partitions| partitions where # possible. However, many constraints make partitioning perfectly impossible.
diff --git a/build/build_config.h b/build/build_config.h index 1b25276..ebd66fe 100644 --- a/build/build_config.h +++ b/build/build_config.h
@@ -52,7 +52,6 @@ #if defined(__native_client__) // __native_client__ must be first, so that other OS_ defines are not set. #define OS_NACL 1 -#define OS_NACL_SFI #elif defined(ANDROID) #define OS_ANDROID 1 #elif defined(__APPLE__)
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index f017fdc6..7c8f770 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -7.20220111.2.2 +7.20220112.0.1
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index 96c8be9..7c8f770 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -7.20220111.3.1 +7.20220112.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index d22b94c3..7c8f770 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -7.20220111.2.3 +7.20220112.0.1
diff --git a/chrome/VERSION b/chrome/VERSION index d36fc56..444224c 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=99 MINOR=0 -BUILD=4824 +BUILD=4825 PATCH=0
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 418eef00..3d3d6bba 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -389,7 +389,6 @@ "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInternalStateHandler.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java", - "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerSupplier.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchNetworkCommunicator.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchObserver.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java index 13f34d7..06c75827 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java
@@ -82,6 +82,7 @@ import org.chromium.chrome.browser.autofill_assistant.proto.KeyboardValueFillStrategy; import org.chromium.chrome.browser.autofill_assistant.proto.LoginDetailsProto; import org.chromium.chrome.browser.autofill_assistant.proto.ModelProto.ModelValue; +import org.chromium.chrome.browser.autofill_assistant.proto.PaymentInstrumentProto; import org.chromium.chrome.browser.autofill_assistant.proto.PopupListSectionProto; import org.chromium.chrome.browser.autofill_assistant.proto.ProcessedActionProto; import org.chromium.chrome.browser.autofill_assistant.proto.ProcessedActionStatusProto; @@ -989,4 +990,59 @@ assertThat(getElementValue(getWebContents(), "profile_name"), is("John Doe")); assertThat(getElementValue(getWebContents(), "email"), is("johndoe@google.com")); } + + /** + * Load and show a card from backend. + * TODO(b/214022384): Fill it into a form (requires unmasking). + */ + @Test + @MediumTest + public void testShowBackendCard() throws Exception { + UserDataProto.Builder + data = UserDataProto.newBuilder().setLocale("en-US").addAvailablePaymentInstruments( + PaymentInstrumentProto.newBuilder() + .putCardValues(55, AutofillEntryProto.newBuilder().setValue("2050").build()) + .putCardValues(53, AutofillEntryProto.newBuilder().setValue("7").build()) + .putCardValues( + 51, AutofillEntryProto.newBuilder().setValue("John Doe").build()) + .setNetwork("visaCC") + .setLastFourDigits("1111") + .putAddressValues( + 35, AutofillEntryProto.newBuilder().setValue("80302").build()) + .putAddressValues( + 36, AutofillEntryProto.newBuilder().setValue("US").build()) + .putAddressValues( + 33, AutofillEntryProto.newBuilder().setValue("Boulder").build()) + .putAddressValues(30, + AutofillEntryProto.newBuilder().setValue("123 Broadway St").build()) + .putAddressValues( + 34, AutofillEntryProto.newBuilder().setValue("CO").build()) + .putAddressValues( + 7, AutofillEntryProto.newBuilder().setValue("John Doe").build())); + + ArrayList<ActionProto> list = new ArrayList<>(); + list.add(ActionProto.newBuilder() + .setCollectUserData(CollectUserDataProto.newBuilder() + .setUserData(data) + .setRequestPaymentMethod(true) + .setBillingAddressName("billing_address") + .addSupportedBasicCardNetworks("visa") + .setRequestTermsAndConditions(false)) + .build()); + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + SupportedScriptProto.newBuilder() + .setPath("form_target_website.html") + .setPresentation(PresentationProto.newBuilder().setAutostart(true)) + .build(), + list); + + AutofillAssistantTestService testService = + new AutofillAssistantTestService(Collections.singletonList(script)); + startAutofillAssistant(mTestRule.getActivity(), testService); + + waitUntilViewMatchesCondition(allOf(withId(R.id.credit_card_number), + isDescendantOfA(withId(R.id.payment_method_summary))), + allOf(withText(containsString("1111")), isDisplayed())); + waitUntilViewMatchesCondition(withContentDescription("Continue"), isEnabled()); + } }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java index 1b77772c..fb8430e 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
@@ -33,7 +33,6 @@ import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; -import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagerSupplier; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.fullscreen.FullscreenManager; import org.chromium.chrome.browser.fullscreen.FullscreenOptions; @@ -486,8 +485,7 @@ if (VrModuleProvider.getDelegate().isInVr()) return false; // Don't open the accessory inside the contextual search panel. - ContextualSearchManager contextualSearch = - ContextualSearchManagerSupplier.getValueOrNullFrom(mWindowAndroid); + ContextualSearchManager contextualSearch = mActivity.getContextualSearchManager(); if (contextualSearch != null && contextualSearch.isSearchPanelOpened()) return false; // If an accessory sheet was opened, the accessory bar must be visible.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index eb62eaa8..99a4267 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1608,7 +1608,7 @@ protected RootUiCoordinator createRootUiCoordinator() { return new TabbedRootUiCoordinator(this, this::onOmniboxFocusChanged, getShareDelegateSupplier(), getActivityTabProvider(), mTabModelProfileSupplier, - mBookmarkBridgeSupplier, mContextualSearchManagerSupplier, + mBookmarkBridgeSupplier, this::getContextualSearchManager, getTabModelSelectorSupplier(), mStartSurfaceSupplier, mIntentMetadataOneshotSupplier, mLayoutStateProviderOneshotSupplier, mStartSurfaceParentTabSupplier, getBrowserControlsManager(), getWindowAndroid(), @@ -2620,7 +2620,7 @@ // TODO(crbug.com/1157310): Transition this::method refs to dedicated suppliers. mTabModalHandler = new TabModalLifetimeHandler(this, getLifecycleDispatcher(), manager, this::getAppBrowserControlsVisibilityDelegate, this::getTabObscuringHandler, - this::getToolbarManager, mContextualSearchManagerSupplier, + this::getToolbarManager, this::getContextualSearchManager, getTabModelSelectorSupplier(), this::getBrowserControlsManager, this::getFullscreenManager); return manager;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/DEPS index a288fdd6..c65c5ff7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/DEPS +++ b/chrome/android/java/src/org/chromium/chrome/browser/DEPS
@@ -24,6 +24,9 @@ "LaunchIntentDispatcher\.java": [ "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java", ], + "ContextualSearchTabHelper\.java": [ + "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java", + ], "BaseCustomTabActivity\.java": [ "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java", ],
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 c3aad0f..ad9c155 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
@@ -99,7 +99,6 @@ import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager.ContextualSearchTabPromotionDelegate; -import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagerSupplier; import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule; import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent; import org.chromium.chrome.browser.dependency_injection.ModuleFactoryOverrides; @@ -282,9 +281,6 @@ // TODO(crbug.com/1209864): Move ownership to RootUiCoordinator. private final UnownedUserDataSupplier<BrowserControlsManager> mBrowserControlsManagerSupplier = new BrowserControlsManagerSupplier(); - // Provided as a supplier by other clasess in ChromeActivity hierarchy. - protected final UnownedUserDataSupplier<ContextualSearchManager> - mContextualSearchManagerSupplier = new ContextualSearchManagerSupplier(); protected TabModelSelectorProfileSupplier mTabModelProfileSupplier = new TabModelSelectorProfileSupplier(mTabModelSelectorSupplier); @@ -325,6 +321,7 @@ private ObservableSupplierImpl<LayoutManagerImpl> mLayoutManagerSupplier = new ObservableSupplierImpl<>(); private InsetObserverView mInsetObserverView; + private ContextualSearchManager mContextualSearchManager; private SnackbarManager mSnackbarManager; // Timestamp in ms when initial layout inflation begins @@ -493,7 +490,6 @@ mTabModelSelectorSupplier.attach(getWindowAndroid().getUnownedUserDataHost()); mTabCreatorManagerSupplier.attach(getWindowAndroid().getUnownedUserDataHost()); mManualFillingComponentSupplier.attach(getWindowAndroid().getUnownedUserDataHost()); - mContextualSearchManagerSupplier.attach(getWindowAndroid().getUnownedUserDataHost()); mBrowserControlsManagerSupplier.attach(getWindowAndroid().getUnownedUserDataHost()); // BrowserControlsManager is ready immediately. mBrowserControlsManagerSupplier.set( @@ -509,7 +505,7 @@ // clang-format off return new RootUiCoordinator(this, null, getShareDelegateSupplier(), getActivityTabProvider(), mTabModelProfileSupplier, mBookmarkBridgeSupplier, - mContextualSearchManagerSupplier, getTabModelSelectorSupplier(), + this::getContextualSearchManager, getTabModelSelectorSupplier(), new OneshotSupplierImpl<>(), new OneshotSupplierImpl<>(), new OneshotSupplierImpl<>(), () -> null, mBrowserControlsManagerSupplier.get(), getWindowAndroid(), @@ -980,10 +976,10 @@ // TODO(1107916): Move contextual search initialization to the RootUiCoordinator. if (ContextualSearchFieldTrial.isEnabled()) { - mContextualSearchManagerSupplier.set(new ContextualSearchManager(this, this, + mContextualSearchManager = new ContextualSearchManager(this, this, mRootUiCoordinator.getScrimCoordinator(), getActivityTabProvider(), getFullscreenManager(), getBrowserControlsManager(), getWindowAndroid(), - getTabModelSelectorSupplier().get(), () -> getLastUserInteractionTime())); + getTabModelSelectorSupplier().get(), () -> getLastUserInteractionTime()); } TraceEvent.end("ChromeActivity:CompositorInitialization"); @@ -1089,20 +1085,18 @@ final SyncService syncService = SyncService.get(); if (syncService != null && syncService.isSyncingUrlsWithKeystorePassphrase()) { - ContextReporter.SelectionReporter controller = null; - if (mContextualSearchManagerSupplier.hasValue()) { - controller = new ContextReporter.SelectionReporter() { - @Override - public void enable(Callback<GSAContextDisplaySelection> callback) { - mContextualSearchManagerSupplier.get().enableContextReporting(callback); - } + ContextReporter.SelectionReporter controller = + getContextualSearchManager() != null ? new ContextReporter.SelectionReporter() { + @Override + public void enable(Callback<GSAContextDisplaySelection> callback) { + getContextualSearchManager().enableContextReporting(callback); + } - @Override - public void disable() { - mContextualSearchManagerSupplier.get().disableContextReporting(); - } - }; - } + @Override + public void disable() { + getContextualSearchManager().disableContextReporting(); + } + } : null; mContextReporter = AppHooks.get().createGsaHelper().getContextReporter( getActivityTabProvider(), mTabModelSelectorSupplier, controller); @@ -1532,10 +1526,10 @@ @SuppressLint("NewApi") @Override protected final void onDestroy() { - if (mContextualSearchManagerSupplier.hasValue()) { - mContextualSearchManagerSupplier.get().destroy(); + if (mContextualSearchManager != null) { + mContextualSearchManager.destroy(); + mContextualSearchManager = null; } - mContextualSearchManagerSupplier.destroy(); if (mSnackbarManager != null) { SnackbarManagerProvider.detach(mSnackbarManager); @@ -2156,6 +2150,13 @@ } /** + * @return The {@code ContextualSearchManager} or {@code null} if none; + */ + public ContextualSearchManager getContextualSearchManager() { + return mContextualSearchManager; + } + + /** * Exits the fullscreen mode, if any. Does nothing if no fullscreen is present. * @return Whether the fullscreen mode is currently showing. */ @@ -2198,8 +2199,8 @@ mActivityTabProvider.setLayoutStateProvider(layoutManager); - if (mContextualSearchManagerSupplier.hasValue()) { - mContextualSearchManagerSupplier.get().initialize(contentContainer, layoutManager, + if (mContextualSearchManager != null) { + mContextualSearchManager.initialize(contentContainer, layoutManager, mRootUiCoordinator.getBottomSheetController(), compositorViewHolder, getControlContainerHeightResource() == ActivityUtils.NO_RESOURCE_ID ? 0f
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerSupplier.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerSupplier.java deleted file mode 100644 index 6dddecd..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerSupplier.java +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextualsearch; - -import androidx.annotation.Nullable; - -import org.chromium.base.UnownedUserDataKey; -import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.base.supplier.UnownedUserDataSupplier; -import org.chromium.ui.base.WindowAndroid; - -/** - * A {@link UnownedUserDataSupplier} which manages the supplier and UnownedUserData for a - * {@link ContextualSearchManager}. - */ -public class ContextualSearchManagerSupplier - extends UnownedUserDataSupplier<ContextualSearchManager> { - private static final UnownedUserDataKey<ContextualSearchManagerSupplier> KEY = - new UnownedUserDataKey<ContextualSearchManagerSupplier>( - ContextualSearchManagerSupplier.class); - - /** - * Returns {@link ContextualSearchManager} supplier associated with the given {@link - * WindowAndroid} or {@code null}. - */ - public static @Nullable ObservableSupplier<ContextualSearchManager> from( - @Nullable WindowAndroid windowAndroid) { - if (windowAndroid == null) return null; - return KEY.retrieveDataFromHost(windowAndroid.getUnownedUserDataHost()); - } - - /** Retrieves a {@link ContextualSearchManager} from {@link WindowAndroid}. */ - public static @Nullable ContextualSearchManager getValueOrNullFrom( - @Nullable WindowAndroid windowAndroid) { - ObservableSupplier<ContextualSearchManager> supplier = from(windowAndroid); - return supplier == null ? null : supplier.get(); - } - - public ContextualSearchManagerSupplier() { - super(KEY); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java index 6f85415..eb2e1e2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java
@@ -4,14 +4,15 @@ package org.chromium.chrome.browser.contextualsearch; +import android.app.Activity; import android.content.Context; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; +import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial.ContextualSearchSwitch; import org.chromium.chrome.browser.firstrun.FirstRunStatus; @@ -48,6 +49,12 @@ */ private WebContents mWebContents; + /** + * The {@link ContextualSearchManager} that's managing this tab. This may point to + * the manager from another activity during reparenting, or be {@code null} during startup. + */ + private ContextualSearchManager mContextualSearchManager; + /** The GestureListener used for handling events from the current WebContents. */ private GestureStateListener mGestureStateListener; @@ -95,9 +102,7 @@ public void onPageLoadStarted(Tab tab, GURL url) { updateHooksForTab(tab); ContextualSearchManager manager = getContextualSearchManager(tab); - if (manager != null) { - manager.onBasePageLoadStarted(); - } + if (manager != null) manager.onBasePageLoadStarted(); } @Override @@ -146,6 +151,7 @@ } removeContextualSearchHooks(mWebContents); mWebContents = null; + mContextualSearchManager = null; mSelectionClientManager = null; mGestureStateListener = null; } @@ -156,6 +162,7 @@ updateHooksForTab(tab); } else { removeContextualSearchHooks(mWebContents); + mContextualSearchManager = null; } } @@ -188,7 +195,8 @@ private void updateHooksForTab(Tab tab) { WebContents currentWebContents = tab.getWebContents(); boolean webContentsChanged = currentWebContents != mWebContents; - if (webContentsChanged) { + if (webContentsChanged || mContextualSearchManager != getContextualSearchManager(tab)) { + mContextualSearchManager = getContextualSearchManager(tab); if (webContentsChanged && currentWebContents != null) { // Ensure the hooks are cleared on the old web contents before proceeding. All of // the objects associated with the web content need to be recreated in order for @@ -257,9 +265,9 @@ mSelectionClientManager.removeContextualSearchSelectionClient()); } // Also make sure the UI is hidden if the device is offline. - ContextualSearchManager manager = getContextualSearchManager(mTab); - if (manager != null && !isDeviceOnline(manager)) { - manager.hideContextualSearch(StateChangeReason.UNKNOWN); + ContextualSearchManager contextualSearchManager = getContextualSearchManager(mTab); + if (contextualSearchManager != null && !isDeviceOnline(contextualSearchManager)) { + contextualSearchManager.hideContextualSearch(StateChangeReason.UNKNOWN); } } } @@ -312,12 +320,16 @@ } /** - * Gets the {@link ContextualSearchManager} associated with the given tab. + * Gets the {@link ContextualSearchManager} associated with the given tab's activity. * @param tab The {@link Tab} that we're getting the manager for. * @return The Contextual Search manager controlling that Tab. */ - private ContextualSearchManager getContextualSearchManager(@NonNull Tab tab) { - return ContextualSearchManagerSupplier.getValueOrNullFrom(tab.getWindowAndroid()); + private ContextualSearchManager getContextualSearchManager(Tab tab) { + Activity activity = tab.getWindowAndroid().getActivity().get(); + if (activity instanceof ChromeActivity) { + return ((ChromeActivity) activity).getContextualSearchManager(); + } + return null; } // ============================================================================================ @@ -341,9 +353,9 @@ @CalledByNative void onShowUnhandledTapUIIfNeeded(int x, int y, int fontSizeDips, int textRunLength) { // Only notify the manager if we currently have a valid listener. - ContextualSearchManager manager = getContextualSearchManager(mTab); - if (mGestureStateListener != null && manager != null) { - manager.onShowUnhandledTapUIIfNeeded(x, y, fontSizeDips, textRunLength); + if (mGestureStateListener != null && getContextualSearchManager(mTab) != null) { + getContextualSearchManager(mTab).onShowUnhandledTapUIIfNeeded( + x, y, fontSizeDips, textRunLength); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java index 8b6e698..807987c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -154,7 +154,7 @@ mBaseCustomTabRootUiCoordinator = new BaseCustomTabRootUiCoordinator(this, getShareDelegateSupplier(), getActivityTabProvider(), mTabModelProfileSupplier, mBookmarkBridgeSupplier, - mContextualSearchManagerSupplier, getTabModelSelectorSupplier(), + this::getContextualSearchManager, getTabModelSelectorSupplier(), getBrowserControlsManager(), getWindowAndroid(), getLifecycleDispatcher(), getLayoutManagerSupplier(), /* menuOrKeyboardActionController= */ this, this::getActivityThemeColor,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate.java index a6834771..acbdece 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate.java
@@ -19,6 +19,7 @@ import androidx.mediarouter.media.MediaRouter; import org.chromium.base.ContextUtils; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.base.SplitCompatService; import org.chromium.chrome.browser.notifications.NotificationConstants; @@ -165,7 +166,19 @@ Intent i = new Intent(getContext(), ChromeMediaNotificationControllerServices.PlaybackListenerService.class); i.setAction(intent.getAction()); - getContext().startService(i); + boolean succeeded = true; + try { + getContext().startService(i); + } catch (RuntimeException e) { + // This happens occasionally with "cannot start foreground service". It's not + // at all clear what causes it; no combination of multi-window / background + // unplugging headphones has managed to repro it locally. While it might be + // possible to trampoline this through an activity like we do elsewhere for + // notifications, that's a fairly invasive change without a local repro. So, + // for now, just log that this happened and move on. https://crbug.com/1245017 + succeeded = false; + } + RecordHistogram.recordBooleanHistogram("Media.Android.BecomingNoisy", succeeded); } }; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java index b235abb..7ccbde21 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
@@ -13,6 +13,7 @@ import android.app.Instrumentation.ActivityMonitor; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.graphics.Point; import android.os.SystemClock; import android.support.test.InstrumentationRegistry; @@ -30,6 +31,7 @@ import org.junit.ClassRule; import org.junit.Rule; +import org.chromium.base.ContextUtils; import org.chromium.base.FeatureList; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; @@ -49,7 +51,6 @@ import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.locale.LocaleManagerDelegate; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; -import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule; @@ -220,10 +221,7 @@ sActivityTestRule.loadUrl(mTestServer.getURL(mTestPage)); - mManager = TestThreadUtils.runOnUiThreadBlocking(() -> { - return ContextualSearchManagerSupplier.getValueOrNullFrom( - sActivityTestRule.getActivity().getWindowAndroid()); - }); + mManager = sActivityTestRule.getActivity().getContextualSearchManager(); mTestHost = new ContextualSearchInstrumentationTestHost(); Assert.assertNotNull(mManager); @@ -1030,10 +1028,14 @@ */ private void resetCounters() { TestThreadUtils.runOnUiThreadBlocking(() -> { - SharedPreferencesManager prefs = SharedPreferencesManager.getInstance(); + // TODO(donnd): Use SharedPreferencesManager instead to access SharedPreferences. + SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); boolean freStatus = - prefs.readBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, false); - prefs.writeBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, freStatus); + prefs.getBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, false); + prefs.edit() + .clear() + .putBoolean(ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, freStatus) + .apply(); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index b2696fd..45ab0b33 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -283,10 +283,7 @@ sActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE)); - mManager = TestThreadUtils.runOnUiThreadBlocking(() -> { - return ContextualSearchManagerSupplier.getValueOrNullFrom( - sActivityTestRule.getActivity().getWindowAndroid()); - }); + mManager = sActivityTestRule.getActivity().getContextualSearchManager(); mTestHost = new ContextualSearchManagerTestHost(); Assert.assertNotNull(mManager); @@ -3743,10 +3740,9 @@ // Trigger on a word and wait for the selection to be established. triggerNode(activity2.getActivityTab(), "search"); CriteriaHelper.pollUiThread(() -> { - String selection = - ContextualSearchManagerSupplier.getValueOrNullFrom(activity2.getWindowAndroid()) - .getSelectionController() - .getSelectedText(); + String selection = activity2.getContextualSearchManager() + .getSelectionController() + .getSelectedText(); Criteria.checkThat(selection, Matchers.is("Search")); }); TestThreadUtils.runOnUiThreadBlocking(() -> activity2.getCurrentTabModel().closeAllTabs());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java index 09947c48..751bb96e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java
@@ -20,7 +20,6 @@ import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; -import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagerSupplier; import org.chromium.chrome.browser.firstrun.DisableFirstRun; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabbed_mode.TabbedRootUiCoordinator; @@ -159,15 +158,14 @@ @Feature({"PreviewTab"}) public void testSuppressContextualSearch() throws Throwable { ChromeActivity activity = mActivityTestRule.getActivity(); - ContextualSearchManager csManager = TestThreadUtils.runOnUiThreadBlocking(() -> { - return ContextualSearchManagerSupplier.getValueOrNullFrom(activity.getWindowAndroid()); - }); + ContextualSearchManager csManager = activity.getContextualSearchManager(); Assert.assertFalse("Contextual Search should be active", csManager.isSuppressed()); - TestThreadUtils.runOnUiThreadBlocking(() -> { - mEphemeralTabCoordinator.requestOpenSheet( - new GURL(mTestServer.getServer().getURL(PREVIEW_TAB)), "PreviewTab", false); - }); + TestThreadUtils.runOnUiThreadBlocking( + () + -> mEphemeralTabCoordinator.requestOpenSheet( + new GURL(mTestServer.getServer().getURL(PREVIEW_TAB)), "PreviewTab", + false)); endAnimations(); Assert.assertTrue("The Preview Tab did not open", mEphemeralTabCoordinator.isOpened()); Assert.assertTrue("Contextual Search should be suppressed", csManager.isSuppressed());
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 599783f..4fb2ca1 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3573,29 +3573,6 @@ "accuracy_tips/accuracy_service_delegate.h", "accuracy_tips/accuracy_service_factory.cc", "accuracy_tips/accuracy_service_factory.h", - "apps/app_discovery_service/app_discovery_features.cc", - "apps/app_discovery_service/app_discovery_features.h", - "apps/app_discovery_service/app_discovery_service.cc", - "apps/app_discovery_service/app_discovery_service.h", - "apps/app_discovery_service/app_discovery_service_factory.cc", - "apps/app_discovery_service/app_discovery_service_factory.h", - "apps/app_discovery_service/app_discovery_util.h", - "apps/app_discovery_service/app_fetcher_manager.cc", - "apps/app_discovery_service/app_fetcher_manager.h", - "apps/app_discovery_service/play_extras.cc", - "apps/app_discovery_service/play_extras.h", - "apps/app_discovery_service/recommended_arc_app_fetcher.cc", - "apps/app_discovery_service/recommended_arc_app_fetcher.h", - "apps/app_discovery_service/remote_url_search/remote_url_client.cc", - "apps/app_discovery_service/remote_url_search/remote_url_client.h", - "apps/app_discovery_service/remote_url_search/remote_url_fetcher.cc", - "apps/app_discovery_service/remote_url_search/remote_url_fetcher.h", - "apps/app_discovery_service/remote_url_search/remote_url_index.cc", - "apps/app_discovery_service/remote_url_search/remote_url_index.h", - "apps/app_discovery_service/result.cc", - "apps/app_discovery_service/result.h", - "apps/app_discovery_service/test_fetcher.cc", - "apps/app_discovery_service/test_fetcher.h", "apps/app_service/app_icon/app_icon_factory.cc", "apps/app_service/app_icon/app_icon_factory.h", "apps/app_service/app_icon/app_icon_loader.cc", @@ -4557,6 +4534,29 @@ if (is_chromeos_ash) { assert(enable_system_notifications) sources += [ + "apps/app_discovery_service/app_discovery_features.cc", + "apps/app_discovery_service/app_discovery_features.h", + "apps/app_discovery_service/app_discovery_service.cc", + "apps/app_discovery_service/app_discovery_service.h", + "apps/app_discovery_service/app_discovery_service_factory.cc", + "apps/app_discovery_service/app_discovery_service_factory.h", + "apps/app_discovery_service/app_discovery_util.h", + "apps/app_discovery_service/app_fetcher_manager.cc", + "apps/app_discovery_service/app_fetcher_manager.h", + "apps/app_discovery_service/play_extras.cc", + "apps/app_discovery_service/play_extras.h", + "apps/app_discovery_service/recommended_arc_app_fetcher.cc", + "apps/app_discovery_service/recommended_arc_app_fetcher.h", + "apps/app_discovery_service/remote_url_search/remote_url_client.cc", + "apps/app_discovery_service/remote_url_search/remote_url_client.h", + "apps/app_discovery_service/remote_url_search/remote_url_fetcher.cc", + "apps/app_discovery_service/remote_url_search/remote_url_fetcher.h", + "apps/app_discovery_service/remote_url_search/remote_url_index.cc", + "apps/app_discovery_service/remote_url_search/remote_url_index.h", + "apps/app_discovery_service/result.cc", + "apps/app_discovery_service/result.h", + "apps/app_discovery_service/test_fetcher.cc", + "apps/app_discovery_service/test_fetcher.h", "apps/app_service/app_icon/arc_activity_adaptive_icon_impl.cc", "apps/app_service/app_icon/arc_activity_adaptive_icon_impl.h", "apps/app_service/app_icon/arc_icon_once_loader.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index f7cbd57..efb5d7c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3184,6 +3184,10 @@ {"enable-wireguard", flag_descriptions::kEnableWireGuardName, flag_descriptions::kEnableWireGuardDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kEnableWireGuard)}, + {"enforce-ash-extension-keeplist", + flag_descriptions::kEnforceAshExtensionKeeplistName, + flag_descriptions::kEnforceAshExtensionKeeplistDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kEnforceAshExtensionKeeplist)}, {"esim-policy", flag_descriptions::kESimPolicyName, flag_descriptions::kESimPolicyDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kESimPolicy)}, @@ -5584,11 +5588,6 @@ #endif #if BUILDFLAG(IS_CHROMEOS_ASH) - {"app-service-external-protocol", - flag_descriptions::kAppServiceExternalProtocolName, - flag_descriptions::kAppServiceExternalProtocolDescription, kOsCrOS, - FEATURE_VALUE_TYPE(features::kAppServiceExternalProtocol)}, - {"arc-ghost-window", flag_descriptions::kArcGhostWindowName, flag_descriptions::kArcGhostWindowDescription, kOsCrOS, FEATURE_VALUE_TYPE(full_restore::features::kArcGhostWindow)},
diff --git a/chrome/browser/android/autofill_assistant/client_android.cc b/chrome/browser/android/autofill_assistant/client_android.cc index 64f660a..cbf066a 100644 --- a/chrome/browser/android/autofill_assistant/client_android.cc +++ b/chrome/browser/android/autofill_assistant/client_android.cc
@@ -656,7 +656,7 @@ base::DefaultTickClock::GetInstance(), RuntimeManager::GetForWebContents(GetWebContents())->GetWeakPtr(), std::move(service), std::move(tts_controller), ukm::UkmRecorder::Get(), - AnnotateDomModelServiceFactory::GetInstance()->GetForBrowserContext( + dependencies_->GetAnnotateDomModelService( GetWebContents()->GetBrowserContext())); controller_->SetStatusMessage(status_message); if (progress_bar_config) {
diff --git a/chrome/browser/android/autofill_assistant/dependencies.h b/chrome/browser/android/autofill_assistant/dependencies.h index e48a316..70bc6c3 100644 --- a/chrome/browser/android/autofill_assistant/dependencies.h +++ b/chrome/browser/android/autofill_assistant/dependencies.h
@@ -9,7 +9,9 @@ #include "base/android/scoped_java_ref.h" #include "base/strings/string_piece.h" #include "chrome/browser/android/autofill_assistant/assistant_field_trial_util.h" +#include "components/autofill_assistant/content/browser/annotate_dom_model_service.h" #include "components/variations/service/variations_service.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" namespace autofill_assistant { @@ -38,6 +40,9 @@ virtual std::string GetChromeSignedInEmailAddress( content::WebContents* web_contents) const = 0; + virtual AnnotateDomModelService* GetAnnotateDomModelService( + content::BrowserContext* browser_context) const = 0; + protected: Dependencies(JNIEnv* env, const base::android::JavaParamRef<jobject>& java_object);
diff --git a/chrome/browser/android/autofill_assistant/dependencies_chrome.cc b/chrome/browser/android/autofill_assistant/dependencies_chrome.cc index 72f1ebf8..e33f64df 100644 --- a/chrome/browser/android/autofill_assistant/dependencies_chrome.cc +++ b/chrome/browser/android/autofill_assistant/dependencies_chrome.cc
@@ -7,13 +7,16 @@ #include "base/android/scoped_java_ref.h" #include "base/strings/string_piece.h" #include "chrome/android/features/autofill_assistant/jni_headers/AssistantStaticDependenciesChrome_jni.h" +#include "chrome/browser/android/autofill_assistant/annotate_dom_model_service_factory.h" #include "chrome/browser/android/autofill_assistant/assistant_field_trial_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" +#include "components/autofill_assistant/content/browser/annotate_dom_model_service.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" using ::base::StringPiece; @@ -62,4 +65,10 @@ return account_info.email; } +AnnotateDomModelService* DependenciesChrome::GetAnnotateDomModelService( + content::BrowserContext* browser_context) const { + return AnnotateDomModelServiceFactory::GetInstance()->GetForBrowserContext( + browser_context); +} + } // namespace autofill_assistant
diff --git a/chrome/browser/android/autofill_assistant/dependencies_chrome.h b/chrome/browser/android/autofill_assistant/dependencies_chrome.h index 46f00b8..db870f0 100644 --- a/chrome/browser/android/autofill_assistant/dependencies_chrome.h +++ b/chrome/browser/android/autofill_assistant/dependencies_chrome.h
@@ -10,8 +10,10 @@ #include "base/android/scoped_java_ref.h" #include "base/strings/string_piece.h" #include "chrome/browser/android/autofill_assistant/assistant_field_trial_util.h" +#include "components/autofill_assistant/content/browser/annotate_dom_model_service.h" #include "components/metrics/metrics_service_accessor.h" #include "components/variations/service/variations_service.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" namespace autofill_assistant { @@ -30,6 +32,9 @@ std::string GetChromeSignedInEmailAddress( content::WebContents* web_contents) const override; + + AnnotateDomModelService* GetAnnotateDomModelService( + content::BrowserContext* browser_context) const override; }; } // namespace autofill_assistant
diff --git a/chrome/browser/apps/app_discovery_service/app_discovery_service_unittest.cc b/chrome/browser/apps/app_discovery_service/app_discovery_service_unittest.cc index ab78a6b..954800e 100644 --- a/chrome/browser/apps/app_discovery_service/app_discovery_service_unittest.cc +++ b/chrome/browser/apps/app_discovery_service/app_discovery_service_unittest.cc
@@ -69,14 +69,15 @@ std::vector<Result> fake_results; fake_results.emplace_back( - Result(AppSource::kPlay, kTestAppId, kTestAppTitle, nullptr)); + Result(AppSource::kTestSource, kTestAppId, kTestAppTitle, nullptr)); test_fetcher()->SetResults(std::move(fake_results)); app_discovery_service->GetApps( - ResultType::kRecommendedArcApps, + ResultType::kTestType, base::BindLambdaForTesting([this](std::vector<Result> results) { EXPECT_EQ(results.size(), 1u); - CheckResult(results[0], AppSource::kPlay, kTestAppId, kTestAppTitle); + CheckResult(results[0], AppSource::kTestSource, kTestAppId, + kTestAppTitle); EXPECT_FALSE(results[0].GetSourceExtras()); })); } @@ -91,13 +92,13 @@ auto play_extras = std::make_unique<PlayExtras>( kTestPlayAppPackageName, kTestIconUrl, kTestPlayAppCategory, kTestPlayAppDescription, kTestPlayAppContentRating, kTestIconUrl, true, - false, false); + false, false, false); fake_results.emplace_back(Result(AppSource::kPlay, kTestAppId, kTestAppTitle, std::move(play_extras))); test_fetcher()->SetResults(std::move(fake_results)); app_discovery_service->GetApps( - ResultType::kRecommendedArcApps, + ResultType::kTestType, base::BindLambdaForTesting([this](std::vector<Result> results) { GURL kTestIconUrl(kTestPlayAppIconUrl); EXPECT_EQ(results.size(), 1u); @@ -114,6 +115,7 @@ EXPECT_EQ(play_extras->GetHasInAppPurchases(), true); EXPECT_EQ(play_extras->GetWasPreviouslyInstalled(), false); EXPECT_EQ(play_extras->GetContainsAds(), false); + EXPECT_EQ(play_extras->GetOptimizedForChrome(), false); })); }
diff --git a/chrome/browser/apps/app_discovery_service/app_discovery_util.h b/chrome/browser/apps/app_discovery_service/app_discovery_util.h index 28ae988..cb90d5f 100644 --- a/chrome/browser/apps/app_discovery_service/app_discovery_util.h +++ b/chrome/browser/apps/app_discovery_service/app_discovery_util.h
@@ -13,11 +13,13 @@ namespace apps { enum class ResultType { + kTestType, kRecommendedArcApps, kRemoteUrlSearch, }; enum class AppSource { + kTestSource, kPlay, };
diff --git a/chrome/browser/apps/app_discovery_service/app_fetcher_manager.cc b/chrome/browser/apps/app_discovery_service/app_fetcher_manager.cc index d3ac823d..0c2426ff 100644 --- a/chrome/browser/apps/app_discovery_service/app_fetcher_manager.cc +++ b/chrome/browser/apps/app_discovery_service/app_fetcher_manager.cc
@@ -24,16 +24,17 @@ void AppFetcherManager::GetApps(ResultType result_type, ResultCallback callback) { - if (g_test_fetcher_) { - g_test_fetcher_->GetApps(std::move(callback)); - return; - } - switch (result_type) { + case ResultType::kTestType: + DCHECK(g_test_fetcher_); + g_test_fetcher_->GetApps(std::move(callback)); + return; case ResultType::kRecommendedArcApps: + DCHECK(recommended_arc_app_fetcher_); recommended_arc_app_fetcher_->GetApps(std::move(callback)); return; case ResultType::kRemoteUrlSearch: + DCHECK(remote_url_fetcher_); remote_url_fetcher_->GetApps(std::move(callback)); return; }
diff --git a/chrome/browser/apps/app_discovery_service/play_extras.cc b/chrome/browser/apps/app_discovery_service/play_extras.cc index d89d8ae..d3a29ac 100644 --- a/chrome/browser/apps/app_discovery_service/play_extras.cc +++ b/chrome/browser/apps/app_discovery_service/play_extras.cc
@@ -14,7 +14,8 @@ const GURL& content_rating_icon_url, const bool has_in_app_purchases, const bool was_previously_installed, - const bool contains_ads) + const bool contains_ads, + const bool optimized_for_chrome) : package_name_(package_name), icon_url_(icon_url), category_(category), @@ -23,7 +24,8 @@ content_rating_icon_url_(content_rating_icon_url), has_in_app_purchases_(has_in_app_purchases), was_previously_installed_(was_previously_installed), - contains_ads_(contains_ads) {} + contains_ads_(contains_ads), + optimized_for_chrome_(optimized_for_chrome) {} PlayExtras::~PlayExtras() = default; @@ -63,6 +65,10 @@ return contains_ads_; } +bool PlayExtras::GetOptimizedForChrome() const { + return optimized_for_chrome_; +} + PlayExtras* PlayExtras::AsPlayExtras() { return this; }
diff --git a/chrome/browser/apps/app_discovery_service/play_extras.h b/chrome/browser/apps/app_discovery_service/play_extras.h index 29cb65ac..4efa24d 100644 --- a/chrome/browser/apps/app_discovery_service/play_extras.h +++ b/chrome/browser/apps/app_discovery_service/play_extras.h
@@ -22,7 +22,8 @@ const GURL& content_rating_icon_url, const bool in_app_purchases, const bool previously_installed, - const bool contains_ads); + const bool contains_ads, + const bool optimized_for_chrome); PlayExtras(const PlayExtras&) = delete; PlayExtras& operator=(const PlayExtras&) = delete; ~PlayExtras() override; @@ -38,6 +39,7 @@ // that this user owns. bool GetWasPreviouslyInstalled() const; bool GetContainsAds() const; + bool GetOptimizedForChrome() const; // Result::SourceExtras: PlayExtras* AsPlayExtras() override; @@ -52,6 +54,7 @@ bool has_in_app_purchases_; bool was_previously_installed_; bool contains_ads_; + bool optimized_for_chrome_; }; } // namespace apps
diff --git a/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher.cc b/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher.cc index d4d3be19..1285b06 100644 --- a/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher.cc +++ b/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher.cc
@@ -6,11 +6,97 @@ #include <utility> +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/apps/app_discovery_service/play_extras.h" +#include "chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher.h" + namespace apps { +RecommendedArcAppFetcher::RecommendedArcAppFetcher() = default; +RecommendedArcAppFetcher::~RecommendedArcAppFetcher() = default; + void RecommendedArcAppFetcher::GetApps(ResultCallback callback) { - // TODO(crbug.com/1223321) : Implement. - std::move(callback).Run({}); + callback_ = std::move(callback); + recommend_apps_fetcher_ = ash::RecommendAppsFetcher::Create(this); + recommend_apps_fetcher_->Start(); +} + +void RecommendedArcAppFetcher::OnLoadSuccess(const base::Value& app_list) { + if (!callback_) + return; + if (!app_list.is_dict()) { + std::move(callback_).Run({}); + return; + } + + const base::Value* app_value = app_list.FindListKey("recommendedApp"); + if (!app_value || !app_value->is_list()) { + std::move(callback_).Run({}); + return; + } + + base::Value::ConstListView apps = app_value->GetList(); + if (apps.empty()) { + std::move(callback_).Run({}); + return; + } + + std::vector<Result> results; + for (auto& big_app : apps) { + if (big_app.is_dict()) { + const base::Value* app = big_app.FindDictKey("androidApp"); + if (!app) { + continue; + } + const std::string* package_name = app->FindStringKey("packageName"); + const std::string* title = app->FindStringKey("title"); + if (!package_name || !title) + continue; + const std::string* icon_url = app->FindStringPath("icon.imageUri"); + const std::string* category = app->FindStringKey("category"); + const std::string* app_description = + app->FindStringPath("appDescription.shortDescription"); + const std::string* content_rating = + app->FindStringPath("contentRating.name"); + const std::string* content_rating_url = + app->FindStringPath("contentRating.image.imageUri"); + const std::string* in_app_purchases = + app->FindStringPath("inAppPurchaseInformation.disclaimerText"); + const std::string* previously_installed = + app->FindStringPath("fastAppReinstall.explanationText"); + const std::string* contain_ads = + app->FindStringPath("adsInformation.disclaimerText"); + const base::Value* optimized_for_chrome = + big_app.FindDictKey("merchCurated"); + + auto extras = std::make_unique<PlayExtras>( + *package_name, icon_url ? GURL(*icon_url) : GURL(), + category ? base::UTF8ToUTF16(*category) : u"", + app_description ? base::UTF8ToUTF16(*app_description) : u"", + content_rating ? base::UTF8ToUTF16(*content_rating) : u"", + content_rating_url ? GURL(*content_rating_url) : GURL(), + (in_app_purchases != nullptr), (previously_installed != nullptr), + (contain_ads != nullptr), (optimized_for_chrome != nullptr)); + results.emplace_back(Result(AppSource::kPlay, *package_name, + base::UTF8ToUTF16(*title), + std::move(extras))); + } + } + std::move(callback_).Run(std::move(results)); +} + +void RecommendedArcAppFetcher::OnLoadError() { + if (callback_) + std::move(callback_).Run({}); +} + +void RecommendedArcAppFetcher::OnParseResponseError() { + if (callback_) + std::move(callback_).Run({}); +} + +void RecommendedArcAppFetcher::SetCallbackForTesting(ResultCallback callback) { + callback_ = std::move(callback); } } // namespace apps
diff --git a/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher.h b/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher.h index e09861ca..eef6829 100644 --- a/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher.h +++ b/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher.h
@@ -5,20 +5,39 @@ #ifndef CHROME_BROWSER_APPS_APP_DISCOVERY_SERVICE_RECOMMENDED_ARC_APP_FETCHER_H_ #define CHROME_BROWSER_APPS_APP_DISCOVERY_SERVICE_RECOMMENDED_ARC_APP_FETCHER_H_ +#include "base/values.h" #include "chrome/browser/apps/app_discovery_service/app_discovery_util.h" #include "chrome/browser/apps/app_discovery_service/app_fetcher_manager.h" +#include "chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_delegate.h" + +namespace ash { +class RecommendAppsFetcher; +} namespace apps { -class RecommendedArcAppFetcher : public AppFetcher { +class RecommendedArcAppFetcher : public AppFetcher, + public ash::RecommendAppsFetcherDelegate { public: - RecommendedArcAppFetcher() = default; + RecommendedArcAppFetcher(); RecommendedArcAppFetcher(const RecommendedArcAppFetcher&) = delete; RecommendedArcAppFetcher& operator=(const RecommendedArcAppFetcher&) = delete; - ~RecommendedArcAppFetcher() override = default; + ~RecommendedArcAppFetcher() override; // AppFetcher: void GetApps(ResultCallback callback) override; + + // RecommendAppsFetcherDelegate: + void OnLoadSuccess(const base::Value& app_list) override; + void OnLoadError() override; + void OnParseResponseError() override; + + // For Testing: + void SetCallbackForTesting(ResultCallback callback); + + private: + apps::ResultCallback callback_; + std::unique_ptr<ash::RecommendAppsFetcher> recommend_apps_fetcher_; }; } // namespace apps
diff --git a/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher_unittest.cc b/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher_unittest.cc new file mode 100644 index 0000000..a3d5515 --- /dev/null +++ b/chrome/browser/apps/app_discovery_service/recommended_arc_app_fetcher_unittest.cc
@@ -0,0 +1,119 @@ +// Copyright 2021 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/apps/app_discovery_service/recommended_arc_app_fetcher.h" + +#include "base/json/json_reader.h" +#include "base/logging.h" +#include "base/test/bind.h" +#include "chrome/browser/apps/app_discovery_service/play_extras.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace apps { + +class RecommendedArcAppFetcherTest : public testing::Test { + public: + RecommendedArcAppFetcherTest() = default; + + void SetUp() override { + arc_app_fetcher_ = std::make_unique<RecommendedArcAppFetcher>(); + } + + RecommendedArcAppFetcher* arc_app_fetcher() { return arc_app_fetcher_.get(); } + + private: + content::BrowserTaskEnvironment task_environment_; + std::unique_ptr<RecommendedArcAppFetcher> arc_app_fetcher_; +}; + +TEST_F(RecommendedArcAppFetcherTest, OnLoadSuccess) { + const std::string response = + R"json({"recommendedApp": [{ + "androidApp": { + "packageName": "com.game.name", + "title": "NameOfFunGame", + "icon": { + "imageUri": "https://play-lh.googleusercontent.com/1234IDECLAREATHUMBWAR", + "dimensions": { + "width": 512, + "height": 512 + } + }, + "starRating": { + "averageRating": 4.3319736 + }, + "category": "Casual", + "appDescription": { + "shortDescription": "Wow this game is so fun!" + }, + "contentRating": { + "name": "General", + "image": { + "imageUri": "https://play-lh.googleusercontent.com/5678WHODOWEAPPRECIATE", + "dimensions": { + "width": 272, + "height": 272 + } + }, + "imageCanBeDisplayedWithoutName": false + }, + "downloadsInformation": { + "numDownloadsRounded": "100000000" + }, + "adsInformation": { + "disclaimerText": "Contains ads" + }, + "inAppPurchaseInformation": { + "disclaimerText": "In-app purchases" + } + }, + "merchCurated": { + } + }]})json"; + arc_app_fetcher()->SetCallbackForTesting( + base::BindLambdaForTesting([](std::vector<Result> results) { + ASSERT_EQ(results.size(), 1u); + EXPECT_EQ(results[0].GetAppSource(), AppSource::kPlay); + EXPECT_EQ(results[0].GetAppId(), "com.game.name"); + EXPECT_EQ(results[0].GetAppTitle(), u"NameOfFunGame"); + EXPECT_TRUE(results[0].GetSourceExtras()); + auto* play_extras = results[0].GetSourceExtras()->AsPlayExtras(); + EXPECT_TRUE(play_extras); + EXPECT_EQ(play_extras->GetPackageName(), "com.game.name"); + EXPECT_EQ( + play_extras->GetIconUrl(), + GURL( + "https://play-lh.googleusercontent.com/1234IDECLAREATHUMBWAR")); + EXPECT_EQ(play_extras->GetCategory(), u"Casual"); + EXPECT_EQ(play_extras->GetDescription(), u"Wow this game is so fun!"); + EXPECT_EQ(play_extras->GetContentRating(), u"General"); + EXPECT_EQ( + play_extras->GetContentRatingIconUrl(), + GURL( + "https://play-lh.googleusercontent.com/5678WHODOWEAPPRECIATE")); + EXPECT_EQ(play_extras->GetHasInAppPurchases(), true); + EXPECT_EQ(play_extras->GetWasPreviouslyInstalled(), false); + EXPECT_EQ(play_extras->GetContainsAds(), true); + EXPECT_EQ(play_extras->GetOptimizedForChrome(), true); + })); + absl::optional<base::Value> output = + base::JSONReader::ReadAndReturnValueWithError(response).value; + ASSERT_TRUE(output.has_value()); + arc_app_fetcher()->OnLoadSuccess(std::move(output.value())); +} + +TEST_F(RecommendedArcAppFetcherTest, OnLoadError) { + arc_app_fetcher()->SetCallbackForTesting(base::BindLambdaForTesting( + [](std::vector<Result> results) { ASSERT_EQ(results.size(), 0); })); + arc_app_fetcher()->OnLoadError(); +} + +TEST_F(RecommendedArcAppFetcherTest, OnParseResponseError) { + arc_app_fetcher()->SetCallbackForTesting(base::BindLambdaForTesting( + [](std::vector<Result> results) { ASSERT_EQ(results.size(), 0); })); + arc_app_fetcher()->OnParseResponseError(); +} + +} // namespace apps
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc index 63691b5a..fb07756 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -41,6 +41,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/arc/arc_web_contents_data.h" #include "chrome/browser/chromeos/extensions/gfx_utils.h" +#include "chrome/browser/extensions/extension_keeplist_ash.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_uninstall_dialog.h" #include "chrome/browser/extensions/extension_util.h" @@ -186,10 +187,10 @@ bool is_quickoffice = extension->id() == extension_misc::kQuickOfficeComponentExtensionId; if (extension->is_app() || is_quickoffice) { + auto launch_source = params.launch_source; content::WebContents* web_contents = LaunchImpl(std::move(params)); - if (params.launch_source == apps::mojom::LaunchSource::kFromArc && - web_contents) { + if (launch_source == apps::mojom::LaunchSource::kFromArc && web_contents) { // Add a flag to remember this web_contents originated in the ARC context. web_contents->SetUserData( &arc::ArcWebContentsData::kArcTransitionFlag, @@ -759,7 +760,7 @@ const bool disable_for_lacros = extension->is_platform_app() && crosapi::browser_util::IsLacrosChromeAppsEnabled() && - !apps::ExtensionAppRunsInAsh(extension->id()); + !extensions::ExtensionAppRunsInAsh(extension->id()); const bool is_app_disabled = base::Contains(disabled_apps_, extension->id()) || disable_for_lacros; @@ -779,7 +780,7 @@ const bool disable_for_lacros = extension->is_platform_app() && crosapi::browser_util::IsLacrosChromeAppsEnabled() && - !apps::ExtensionAppRunsInAsh(extension->id()); + !extensions::ExtensionAppRunsInAsh(extension->id()); const bool is_app_disabled = base::Contains(disabled_apps_, extension->id()) || disable_for_lacros;
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_util.cc b/chrome/browser/apps/app_service/publishers/extension_apps_util.cc index 02fbe86..0d353b82 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_util.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_util.cc
@@ -4,14 +4,6 @@ #include "chrome/browser/apps/app_service/publishers/extension_apps_util.h" -#include <set> - -#include "base/containers/contains.h" -#include "base/no_destructor.h" -#include "chrome/browser/ash/file_manager/app_id.h" -#include "chrome/common/extensions/extension_constants.h" -#include "extensions/common/constants.h" - namespace apps { extensions::UninstallReason GetExtensionUninstallReason( @@ -29,16 +21,4 @@ } } -#if BUILDFLAG(IS_CHROMEOS_ASH) -bool ExtensionAppRunsInAsh(const std::string& app_id) { - static base::NoDestructor<std::set<std::string>> keep_list( - {file_manager::kAudioPlayerAppId, extension_misc::kFeedbackExtensionId, - extension_misc::kFilesManagerAppId, extension_misc::kGoogleKeepAppId, - extension_misc::kCalculatorAppId, extension_misc::kTextEditorAppId, - extension_misc::kInAppPaymentsSupportAppId, - extension_misc::kWallpaperManagerId}); - return base::Contains(*keep_list, app_id); -} -#endif - } // namespace apps
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_util.h b/chrome/browser/apps/app_service/publishers/extension_apps_util.h index c57be66..d6c1e91 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_util.h +++ b/chrome/browser/apps/app_service/publishers/extension_apps_util.h
@@ -5,9 +5,6 @@ #ifndef CHROME_BROWSER_APPS_APP_SERVICE_PUBLISHERS_EXTENSION_APPS_UTIL_H_ #define CHROME_BROWSER_APPS_APP_SERVICE_PUBLISHERS_EXTENSION_APPS_UTIL_H_ -#include <string> - -#include "build/chromeos_buildflags.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "extensions/browser/uninstall_reason.h" @@ -16,14 +13,6 @@ // Converts an apps UninstallSource to an extension uninstall reason. extensions::UninstallReason GetExtensionUninstallReason( apps::mojom::UninstallSource uninstall_source); - -#if BUILDFLAG(IS_CHROMEOS_ASH) -// Some extension apps will continue to run in ash until they are either -// deprecated or migrated. This function returns whether a given app_id is on -// that keep list. This function must only be called from the UI thread. -bool ExtensionAppRunsInAsh(const std::string& app_id); -#endif - } // namespace apps #endif // CHROME_BROWSER_APPS_APP_SERVICE_PUBLISHERS_EXTENSION_APPS_UTIL_H_
diff --git a/chrome/browser/apps/intent_helper/OWNERS b/chrome/browser/apps/intent_helper/OWNERS index d339cb2..047993d 100644 --- a/chrome/browser/apps/intent_helper/OWNERS +++ b/chrome/browser/apps/intent_helper/OWNERS
@@ -1,6 +1,8 @@ -dominickn@chromium.org mxcai@chromium.org +tsergeant@chromium.org # For ARC related code djacobo@chromium.org # For ARC related code, backup reviewers file://chrome/browser/ash/arc/OWNERS +# For backup +dominickn@chromium.org
diff --git a/chrome/browser/ash/arc/intent_helper/arc_external_protocol_dialog.cc b/chrome/browser/ash/arc/intent_helper/arc_external_protocol_dialog.cc index 5e662b8..703c157 100644 --- a/chrome/browser/ash/arc/intent_helper/arc_external_protocol_dialog.cc +++ b/chrome/browser/ash/arc/intent_helper/arc_external_protocol_dialog.cc
@@ -502,16 +502,13 @@ // |package_name| matches a valid option and return the index. const size_t selected_app_index = GetAppIndex(handlers, selected_app_package); - // Make sure that the instance at least supports HandleUrl. + // Make sure ARC intent helper instance is connected. auto* arc_service_manager = ArcServiceManager::Get(); - mojom::IntentHelperInstance* instance = nullptr; - if (arc_service_manager) { - instance = ARC_GET_INSTANCE_FOR_METHOD( - arc_service_manager->arc_bridge_service()->intent_helper(), HandleUrl); - } - - if (!instance) + if (!arc_service_manager || !arc_service_manager->arc_bridge_service() + ->intent_helper() + ->IsConnected()) { reason = apps::IntentPickerCloseReason::ERROR_AFTER_PICKER; + } if (reason == apps::IntentPickerCloseReason::OPEN_APP || reason == apps::IntentPickerCloseReason::STAY_IN_CHROME) { @@ -529,9 +526,10 @@ DCHECK(arc_service_manager); if (should_persist) { - if (ARC_GET_INSTANCE_FOR_METHOD( - arc_service_manager->arc_bridge_service()->intent_helper(), - AddPreferredPackage)) { + mojom::IntentHelperInstance* instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_service_manager->arc_bridge_service()->intent_helper(), + AddPreferredPackage); + if (instance) { instance->AddPreferredPackage( handlers[selected_app_index]->package_name); } @@ -556,8 +554,7 @@ [[fallthrough]]; case apps::IntentPickerCloseReason::ERROR_AFTER_PICKER: LOG(ERROR) << "IntentPickerBubbleView returned CloseReason::ERROR: " - << "instance=" << instance - << ", selected_app_index=" << selected_app_index + << "selected_app_index=" << selected_app_index << ", handlers.size=" << handlers.size(); [[fallthrough]]; case apps::IntentPickerCloseReason::DIALOG_DEACTIVATED: @@ -668,16 +665,6 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); auto* arc_service_manager = ArcServiceManager::Get(); - if (!arc_service_manager) { - // ARC is not running anymore. Show the Chrome OS dialog. - ShowExternalProtocolDialogWithoutApps(render_process_host_id, routing_id, - url, initiating_origin, - std::move(handled_cb)); - return; - } - - auto* instance = ARC_GET_INSTANCE_FOR_METHOD( - arc_service_manager->arc_bridge_service()->intent_helper(), HandleUrl); WebContents* web_contents = tab_util::GetWebContentsByID(render_process_host_id, routing_id); @@ -688,7 +675,11 @@ // We only reach here if Chrome doesn't think it can handle the URL. If ARC is // not running anymore, or Chrome is the only candidate returned, show the // usual Chrome OS dialog that says we cannot handle the URL. - if (!instance || !intent_helper_bridge || handlers.empty() || + if (!arc_service_manager || + !arc_service_manager->arc_bridge_service() + ->intent_helper() + ->IsConnected() || + !intent_helper_bridge || handlers.empty() || IsChromeOnlyAppCandidate(handlers)) { ShowExternalProtocolDialogWithoutApps(render_process_host_id, routing_id, url, initiating_origin,
diff --git a/chrome/browser/ash/arc/process/arc_process.cc b/chrome/browser/ash/arc/process/arc_process.cc index ba79fca..7f93bda 100644 --- a/chrome/browser/ash/arc/process/arc_process.cc +++ b/chrome/browser/ash/arc/process/arc_process.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "ash/components/arc/arc_features.h" #include "ash/components/arc/mojom/process.mojom.h" #include "base/strings/string_util.h" @@ -15,9 +16,16 @@ namespace { -constexpr char kCloudDpcrocessName[] = +constexpr const char kCloudDpcrocessName[] = "com.google.android.apps.work.clouddpc.arc"; +constexpr const char* kGmsCoreProtectedServices[] = { + "com.google.process.gservices", + "com.google.android.gms", + "com.google.android.gms.persistent", + "com.google.android.gms.unstable", +}; + bool IsImportantState(ProcessState state) { switch (state) { case ProcessState::IMPORTANT_FOREGROUND: @@ -96,13 +104,15 @@ ArcProcess& ArcProcess::operator=(ArcProcess&& other) = default; bool ArcProcess::IsImportant() const { - return IsImportantState(process_state()) || IsArcProtected(); + return IsImportantState(process_state()) || IsArcProtected() || + IsGmsCoreProtected(); } bool ArcProcess::IsPersistent() const { // Protect PERSISTENT, PERSISTENT_UI, our HOME and custom set of ARC processes // since they should have lower priority to be killed. - return IsPersistentState(process_state()) || IsArcProtected(); + return IsPersistentState(process_state()) || IsArcProtected() || + IsGmsCoreProtected(); } bool ArcProcess::IsCached() const { @@ -117,6 +127,17 @@ return process_name() == kCloudDpcrocessName; } +bool ArcProcess::IsGmsCoreProtected() const { + if (!base::FeatureList::IsEnabled(arc::kGmsCoreLowMemoryKillerProtection)) + return false; + + for (const char* service : kGmsCoreProtectedServices) { + if (process_name() == service) + return true; + } + return false; +} + std::ostream& operator<<(std::ostream& out, const ArcProcess& arc_process) { out << "process_name: " << arc_process.process_name() << ", pid: " << arc_process.pid()
diff --git a/chrome/browser/ash/arc/process/arc_process.h b/chrome/browser/ash/arc/process/arc_process.h index 96ac21e..32d4be0 100644 --- a/chrome/browser/ash/arc/process/arc_process.h +++ b/chrome/browser/ash/arc/process/arc_process.h
@@ -73,6 +73,10 @@ // Returns true if this is ARC protected process which we don't allow to kill. bool IsArcProtected() const; + // Returns true if this is key GMS Core or related service which we don't + // allow to kill. + bool IsGmsCoreProtected() const; + base::ProcessId nspid_; base::ProcessId pid_; std::string process_name_;
diff --git a/chrome/browser/ash/arc/process/arc_process_unittest.cc b/chrome/browser/ash/arc/process/arc_process_unittest.cc index 046b084..4fd51e0 100644 --- a/chrome/browser/ash/arc/process/arc_process_unittest.cc +++ b/chrome/browser/ash/arc/process/arc_process_unittest.cc
@@ -9,13 +9,22 @@ #include <list> #include <sstream> +#include "ash/components/arc/arc_features.h" #include "ash/components/arc/mojom/process.mojom.h" +#include "base/test/scoped_feature_list.h" #include "testing/gtest/include/gtest/gtest.h" namespace arc { namespace { +ArcProcess CreateFromPattern(const ArcProcess& pattern, + const std::string process_name) { + return ArcProcess(pattern.nspid(), pattern.pid(), process_name, + pattern.process_state(), pattern.is_focused(), + pattern.last_activity_time()); +} + // Tests that ArcProcess objects can be sorted by their priority (higher to // lower). This is critical for the OOM handler to work correctly. TEST(ArcProcess, TestSorting) { @@ -209,6 +218,60 @@ EXPECT_FALSE(s.str().empty()); } +TEST(ArcProcess, GmsCoreProtection) { + const ArcProcess pattern(0 /* nspid */, 0 /* pid */, + std::string() /* process_name */, + mojom::ProcessState::CACHED_EMPTY, + false /* is_focused */, 0 /* last_activity_time */); + + EXPECT_FALSE(CreateFromPattern(pattern, "com.google.process.gservices") + .IsPersistent()); + EXPECT_FALSE( + CreateFromPattern(pattern, "com.google.process.gservices").IsImportant()); + EXPECT_FALSE( + CreateFromPattern(pattern, "com.google.android.gms").IsPersistent()); + EXPECT_FALSE( + CreateFromPattern(pattern, "com.google.android.gms").IsImportant()); + EXPECT_FALSE(CreateFromPattern(pattern, "com.google.android.gms.persistent") + .IsPersistent()); + EXPECT_FALSE(CreateFromPattern(pattern, "com.google.android.gms.persistent") + .IsImportant()); + EXPECT_FALSE( + CreateFromPattern(pattern, "com.google.android.gms.ui").IsPersistent()); + EXPECT_FALSE( + CreateFromPattern(pattern, "com.google.android.gms.ui").IsImportant()); + EXPECT_FALSE(CreateFromPattern(pattern, "com.google.android.gms.unstable") + .IsPersistent()); + EXPECT_FALSE(CreateFromPattern(pattern, "com.google.android.gms.unstable") + .IsImportant()); + + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatureState(kGmsCoreLowMemoryKillerProtection, + true /* enabled */); + + EXPECT_TRUE(CreateFromPattern(pattern, "com.google.process.gservices") + .IsPersistent()); + EXPECT_TRUE( + CreateFromPattern(pattern, "com.google.process.gservices").IsImportant()); + EXPECT_TRUE( + CreateFromPattern(pattern, "com.google.android.gms").IsPersistent()); + EXPECT_TRUE( + CreateFromPattern(pattern, "com.google.android.gms").IsImportant()); + EXPECT_TRUE(CreateFromPattern(pattern, "com.google.android.gms.persistent") + .IsPersistent()); + EXPECT_TRUE(CreateFromPattern(pattern, "com.google.android.gms.persistent") + .IsImportant()); + // GMS UI is not protected. + EXPECT_FALSE( + CreateFromPattern(pattern, "com.google.android.gms.ui").IsPersistent()); + EXPECT_FALSE( + CreateFromPattern(pattern, "com.google.android.gms.ui").IsImportant()); + EXPECT_TRUE(CreateFromPattern(pattern, "com.google.android.gms.unstable") + .IsPersistent()); + EXPECT_TRUE(CreateFromPattern(pattern, "com.google.android.gms.unstable") + .IsImportant()); +} + } // namespace } // namespace arc
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.cc b/chrome/browser/ash/crosapi/browser_data_migrator.cc index fe24d69..9a2513cd 100644 --- a/chrome/browser/ash/crosapi/browser_data_migrator.cc +++ b/chrome/browser/ash/crosapi/browser_data_migrator.cc
@@ -11,7 +11,6 @@ #include "base/callback_helpers.h" #include "base/command_line.h" #include "base/containers/contains.h" -#include "base/containers/span.h" #include "base/feature_list.h" #include "base/files/file.h" #include "base/files/file_enumerator.h" @@ -40,68 +39,6 @@ namespace ash { namespace { -// The base names of files and directories directly under the original profile -// data directory that does not need to be copied nor need to remain in ash e.g. -// cache data. -constexpr const char* const kNoCopyPathsDeprecated[] = {kTmpDir, "Cache"}; -constexpr const char* const kNoCopyPaths[] = { - kTmpDir, - "Cache", - "Code Cache", - "crash", - "blob_storage", - "GCache", - "data_reduction_proxy_leveldb", - "previews_opt_out.db", - "Download Service", - "Network Persistent State", - "Reporting and NEL", - "TransportSecurity", - "optimization_guide_hint_cache_store", - "Site Characteristics Database", - "Network Action Predictor"}; -// The base names of files and directories that should remain in ash data -// directory. -constexpr const char* const kAshDataPathsDeprecated[]{"Downloads", "MyFiles"}; -constexpr const char* const kAshDataPaths[] = {"FullRestoreData", - "Downloads", - "MyFiles", - "arc.apps", - "crostini.icons", - "PreferredApps", - "autobrightness", - "extension_install_log", - "google-assistant-library", - "login-times", - "logout-times", - "structured_metrics", - "PrintJobDatabase", - "PPDCache", - "BudgetDatabase", - "RLZ Data", - "app_ranker.pb", - "zero_state_group_ranker.pb", - "zero_state_local_files.pb"}; -// The base names of files/dirs that are needed only by the browser part of -// chrome i.e. data that should be moved to lacros. -constexpr const char* const kLacrosDataPathsDeprecated[]{"Bookmarks"}; -constexpr const char* const kLacrosDataPaths[]{"AutofillStrikeDatabase", - "Bookmarks", - "Cookies", - "Extension Cookies", - "Extension Rules", - "Extension State", - "Extensions", - "Local App Settings", - "Local Extension Settings", - "Managed Extension Settings", - "Sync App Settings", - "DNR Extension Rules", - "Favicons", - "History", - "Top Sites", - "Shortcuts", - "Sessions"}; // Flag values for `switches::kForceBrowserDataMigrationForTesting`. const char kBrowserDataMigrationForceSkip[] = "force-skip"; const char kBrowserDataMigrationForceMigration[] = "force-migration"; @@ -113,82 +50,14 @@ // vector<TargetItem> in TargetInfo. constexpr char kLacrosCategory[] = "lacros"; constexpr char kCommonCategory[] = "common"; - -// Enable these to fallback to an older version of paths lists. -const base::Feature kLacrosProfileMigrationUseDeprecatedNoCopyPaths{ - "LacrosProfileMigrationUseDeprecatedNoCopyPaths", - base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kLacrosProfileMigrationUseDeprecatedAshDataPaths{ - "LacrosProfileMigrationUseDeprecatedAshDataPaths", - base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kLacrosProfileMigrationUseDeprecatedLacrosDataPaths{ - "LacrosProfileMigrationUseDeprecatedLacrosDataPaths", - base::FEATURE_DISABLED_BY_DEFAULT}; - -// Ensures that each path in UDD appears in one of `kNoCopyPaths`, -// `kAshDataPaths` or `kLacrosDataPaths`. -constexpr bool HasNoOverlapBetweenPathsSets() { - for (const char* no_copy_path : kNoCopyPaths) { - for (const char* ash_data_path : kAshDataPaths) { - if (base::StringPiece(no_copy_path) == base::StringPiece(ash_data_path)) - return false; - } - } - - for (const char* ash_data_path : kAshDataPaths) { - for (const char* lacros_data_path : kLacrosDataPaths) { - if (base::StringPiece(ash_data_path) == - base::StringPiece(lacros_data_path)) - return false; - } - } - - for (const char* lacros_data_path : kLacrosDataPaths) { - for (const char* no_copy_path : kNoCopyPaths) { - if (base::StringPiece(lacros_data_path) == - base::StringPiece(no_copy_path)) - return false; - } - } - - return true; -} - -static_assert(HasNoOverlapBetweenPathsSets(), - "There must be no overlap between kNoCopyPaths, kAshDataPaths " - "and kLacrosDataPaths"); - -base::span<const char* const> GetNoCopyDataPaths() { - if (base::FeatureList::IsEnabled( - kLacrosProfileMigrationUseDeprecatedNoCopyPaths)) { - return base::make_span(kNoCopyPathsDeprecated); - } - return base::make_span(kNoCopyPaths); -} - -base::span<const char* const> GetAshDataPaths() { - if (base::FeatureList::IsEnabled( - kLacrosProfileMigrationUseDeprecatedAshDataPaths)) { - return base::make_span(kAshDataPathsDeprecated); - } - return base::make_span(kAshDataPaths); -} - -base::span<const char* const> GetLacrosDataPaths() { - if (base::FeatureList::IsEnabled( - kLacrosProfileMigrationUseDeprecatedLacrosDataPaths)) { - return base::make_span(kLacrosDataPathsDeprecated); - } - return base::make_span(kLacrosDataPaths); -} } // namespace CancelFlag::CancelFlag() : cancelled_(false) {} CancelFlag::~CancelFlag() = default; BrowserDataMigratorImpl::TargetInfo::TargetInfo() - : ash_data_size(0), - no_copy_data_size(0), + : remain_in_ash_data_size(0), + deletable_data_size(0), lacros_data_size(0), common_data_size(0) {} BrowserDataMigratorImpl::TargetInfo::TargetInfo(TargetInfo&&) = default; @@ -210,7 +79,7 @@ } int64_t BrowserDataMigratorImpl::TargetInfo::TotalDirSize() const { - return no_copy_data_size + ash_data_size + lacros_data_size + + return deletable_data_size + remain_in_ash_data_size + lacros_data_size + common_data_size; } @@ -435,7 +304,8 @@ target_info->TotalCopySize() / 1024 / 1024, 1, 10000, 100); UMA_HISTOGRAM_CUSTOM_COUNTS( - kAshDataSize, target_info->ash_data_size / 1024 / 1024, 1, 10000, 100); + kAshDataSize, target_info->remain_in_ash_data_size / 1024 / 1024, 1, + 10000, 100); UMA_HISTOGRAM_CUSTOM_COUNTS(kLacrosDataSize, target_info->lacros_data_size / 1024 / 1024, 1, 10000, 100); @@ -443,7 +313,7 @@ target_info->common_data_size / 1024 / 1024, 1, 10000, 100); UMA_HISTOGRAM_CUSTOM_COUNTS(kNoCopyDataSize, - target_info->no_copy_data_size / 1024 / 1024, 1, + target_info->deletable_data_size / 1024 / 1024, 1, 10000, 100); if (!timer || final_status != FinalStatus::kSuccess) @@ -594,9 +464,6 @@ BrowserDataMigratorImpl::TargetInfo BrowserDataMigratorImpl::GetTargetInfo( const base::FilePath& original_user_dir) { TargetInfo target_info; - const base::span<const char* const> no_copy_data_paths = GetNoCopyDataPaths(); - const base::span<const char* const> ash_data_paths = GetAshDataPaths(); - const base::span<const char* const> lacros_data_paths = GetLacrosDataPaths(); base::FileEnumerator enumerator(original_user_dir, false /* recursive */, base::FileEnumerator::FILES | @@ -619,22 +486,22 @@ continue; } - if (base::Contains(ash_data_paths, entry.BaseName().value())) { - target_info.ash_data_items.emplace_back( + if (base::Contains(kRemainInAshDataPaths, entry.BaseName().value())) { + target_info.remain_in_ash_items.emplace_back( TargetItem{entry, size, item_type}); - target_info.ash_data_size += size; - } else if (base::Contains(no_copy_data_paths, entry.BaseName().value())) { - target_info.no_copy_data_items.emplace_back( + target_info.remain_in_ash_data_size += size; + } else if (base::Contains(kDeletablePaths, entry.BaseName().value())) { + target_info.deletable_items.emplace_back( TargetItem{entry, size, item_type}); - target_info.no_copy_data_size += size; - } else if (base::Contains(lacros_data_paths, entry.BaseName().value())) { + target_info.deletable_data_size += size; + } else if (base::Contains(kLacrosDataPaths, entry.BaseName().value())) { // Items that should be moved to lacros. target_info.lacros_data_items.emplace_back( TargetItem{entry, size, item_type}); target_info.lacros_data_size += size; - } else { - // Items that are not explicitly ash, no_copy or lacros are put into - // common category. + } else if (base::Contains(kCommonDataPaths, entry.BaseName().value())) { + // Items that are not explicitly ash, deletable_data or lacros are put + // into common category. target_info.common_data_items.emplace_back( TargetItem{entry, size, item_type}); target_info.common_data_size += size; @@ -659,11 +526,11 @@ break; case Mode::kDeleteAndCopy: required_space = - target_info.TotalCopySize() - target_info.no_copy_data_size; + target_info.TotalCopySize() - target_info.deletable_data_size; break; case Mode::kDeleteAndMove: required_space = - target_info.common_data_size - target_info.no_copy_data_size; + target_info.common_data_size - target_info.deletable_data_size; break; case Mode::kCopy: default: @@ -862,11 +729,11 @@ TargetInfo target_info = GetTargetInfo(profile_data_dir); base::UmaHistogramCustomCounts(kDryRunNoCopyDataSize, - target_info.no_copy_data_size / 1024 / 1024, 1, - 10000, 100); - base::UmaHistogramCustomCounts(kDryRunAshDataSize, - target_info.ash_data_size / 1024 / 1024, 1, - 10000, 100); + target_info.deletable_data_size / 1024 / 1024, + 1, 10000, 100); + base::UmaHistogramCustomCounts( + kDryRunAshDataSize, target_info.remain_in_ash_data_size / 1024 / 1024, 1, + 10000, 100); base::UmaHistogramCustomCounts(kDryRunLacrosDataSize, target_info.lacros_data_size / 1024 / 1024, 1, 10000, 100); @@ -876,8 +743,8 @@ browser_data_migrator_util::RecordTotalSize(target_info.TotalDirSize()); - RecordTargetItemSizes(target_info.no_copy_data_items); - RecordTargetItemSizes(target_info.ash_data_items); + RecordTargetItemSizes(target_info.deletable_items); + RecordTargetItemSizes(target_info.remain_in_ash_items); RecordTargetItemSizes(target_info.lacros_data_items); RecordTargetItemSizes(target_info.common_data_items);
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.h b/chrome/browser/ash/crosapi/browser_data_migrator.h index ddb2fff..12ec54c 100644 --- a/chrome/browser/ash/crosapi/browser_data_migrator.h +++ b/chrome/browser/ash/crosapi/browser_data_migrator.h
@@ -71,6 +71,101 @@ constexpr char kDryRunDeleteAndMoveMigrationHasEnoughDiskSpace[] = "Ash.BrowserDataMigrator.DryRunHasEnoughDiskSpace.DeleteAndMove"; +// The base names of files/dirs directly under the original profile +// data directory that can be deleted if needed because they are temporary +// storages. +constexpr const char* const kDeletablePaths[] = { + kTmpDir, + "blob_storage", + "Cache", + "Code Cache", + "crash", + "data_reduction_proxy_leveldb", + "Download Service", + "GCache", + "heavy_ad_intervention_opt_out.db", + "Network Action Predictor", + "Network Persistent State", + "optimization_guide_hint_cache_store", + "previews_opt_out.db", + "Reporting and NEL", + "Site Characteristics Database", + "TransportSecurity"}; + +// The base names of files/dirs that should remain in ash data +// directory. +constexpr const char* const kRemainInAshDataPaths[] = { + "AccountManagerTokens.bin", + "Accounts", + "app_ranker.pb", + "arc.apps", + "autobrightness", + "BudgetDatabase", + "crostini.icons", + "Downloads", + "extension_install_log", + "FullRestoreData", + "GCM Store", + "google-assistant-library", + "GPUCache", + "login-times", + "logout-times", + "MyFiles", + "NearbySharePublicCertificateDatabase", + "PPDCache", + "PreferredApps", + "PreferredApps", + "PrintJobDatabase", + "README", + "RLZ Data", + "smartcharging", + "structured_metrics", + "Translate Ranker Model", + "Trusted Vault", + "WebRTC Logs", + "webrtc_event_logs", + "zero_state_group_ranker.pb", + "zero_state_local_files.pb"}; + +// The base names of files/dirs that are required for browsing and should be +// moved to lacros data dir. +constexpr const char* const kLacrosDataPaths[]{"AutofillStrikeDatabase", + "Bookmarks", + "Cookies", + "databases", + "DNR Extension Rules", + "Extension Cookies", + "Extension Rules", + "Extension State", + "Extensions", + "Favicons", + "File System", + "History", + "IndexedDB", + "Local App Settings", + "Local Extension Settings", + "Managed Extension Settings", + "QuotaManager", + "Service Worker", + "Session Storage", + "Sessions", + "Shortcuts", + "Sync App Settings", + "Top Sites", + "Visited Links", + "Web Applications", + "Web Data"}; + +// The base names of files/dirs that are required by both ash and lacros and +// thus should be copied to lacros while keeping the original files/dirs in ash +// data dir. +constexpr const char* const kCommonDataPaths[]{"Affiliation Database", + "Login Data", + "Platform Notifications", + "Policy", + "Preferences", + "shared_proto_db"}; + // Local state pref name, which is used to keep track of what step migration is // at. This ensures that ash does not get repeatedly for migration. // 1. The user logs in and restarts ash if necessary to apply flags. @@ -142,17 +237,17 @@ TargetInfo(TargetInfo&&); // Items that should stay in ash data dir. - std::vector<TargetItem> ash_data_items; + std::vector<TargetItem> remain_in_ash_items; // Items that should be moved to lacros data dir. std::vector<TargetItem> lacros_data_items; // Items that will be duplicated in both ash and lacros data dir. std::vector<TargetItem> common_data_items; // Items that can be deleted from both ash and lacros data dir. - std::vector<TargetItem> no_copy_data_items; - // The total size of `ash_data_items`. - int64_t ash_data_size; + std::vector<TargetItem> deletable_items; + // The total size of `remain_in_ash_items`. + int64_t remain_in_ash_data_size; // The total size of items that can be deleted during the migration. - int64_t no_copy_data_size; + int64_t deletable_data_size; // The total size of `lacros_data_items`. int64_t lacros_data_size; // The total size of `common_data_items`. @@ -254,16 +349,16 @@ static void DryRunToCollectUMA(const base::FilePath& profile_data_dir); private: - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, ManipulateMigrationAttemptCount); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, GetTargetInfo); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, CopyDirectory); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, SetupTmpDir); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, CancelSetupTmpDir); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, RecordStatus); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, MigrateInternal); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, Migrate); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, MigrateCancelled); + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, GetTargetInfo); + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, CopyDirectory); + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, SetupTmpDir); + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, CancelSetupTmpDir); + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, RecordStatus); + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, MigrateInternal); + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, Migrate); + FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorImplTest, MigrateCancelled); // Sets the value of `kMigrationStep` in Local State. static void SetMigrationStep(PrefService* local_state, MigrationStep step);
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc b/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc index 26c2591f..ad096a2b 100644 --- a/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc +++ b/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc
@@ -10,6 +10,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" +#include "base/strings/stringprintf.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" @@ -47,14 +48,51 @@ } // namespace -class BrowserDataMigratorTest : public ::testing::Test { +TEST(BrowserDataMigratorTest, NoPathOverlaps) { + base::span<const char* const> remain_in_ash_paths = + base::make_span(kRemainInAshDataPaths); + base::span<const char* const> lacros_data_paths = + base::make_span(kLacrosDataPaths); + base::span<const char* const> deletable_paths = + base::make_span(kDeletablePaths); + base::span<const char* const> common_data_paths = + base::make_span(kCommonDataPaths); + + std::vector<base::span<const char* const>> paths_groups{ + remain_in_ash_paths, lacros_data_paths, deletable_paths, + common_data_paths}; + + auto overlap_checker = [](base::span<const char* const> paths_group_a, + base::span<const char* const> paths_group_b) { + for (const char* path_a : paths_group_a) { + for (const char* path_b : paths_group_b) { + if (base::StringPiece(path_a) == base::StringPiece(path_b)) { + LOG(ERROR) << "The following path appears in multiple sets: " + << path_a; + return false; + } + } + } + + return true; + }; + + for (int i = 0; i < paths_groups.size() - 1; i++) { + for (int j = i + 1; j < paths_groups.size(); j++) { + SCOPED_TRACE(base::StringPrintf("i %d j %d", i, j)); + EXPECT_TRUE(overlap_checker(paths_groups[i], paths_groups[j])); + } + } +} + +class BrowserDataMigratorImplTest : public ::testing::Test { public: void SetUp() override { // Setup `user_data_dir_` as below. // ./ /* user_data_dir_ */ // |- 'First Run' // |- user/ /* from_dir_ */ - // |- Cache /* no copy */ + // |- Cache /* deletable */ // |- Downloads/data /* ash */ // |- FullRestoreData /* ash */ // |- Bookmarks /* lacros */ @@ -114,7 +152,7 @@ TestingPrefServiceSimple pref_service_; }; -TEST_F(BrowserDataMigratorTest, ManipulateMigrationAttemptCount) { +TEST_F(BrowserDataMigratorImplTest, ManipulateMigrationAttemptCount) { const std::string user_id_hash = "user"; EXPECT_EQ(BrowserDataMigratorImpl::GetMigrationAttemptCountForUser( @@ -139,27 +177,31 @@ 0); } -TEST_F(BrowserDataMigratorTest, GetTargetInfo) { +TEST_F(BrowserDataMigratorImplTest, GetTargetInfo) { BrowserDataMigratorImpl::TargetInfo target_info = BrowserDataMigratorImpl::GetTargetInfo(from_dir_); - EXPECT_EQ(target_info.ash_data_size, kFileSize * 2 /* expect two files */); - EXPECT_EQ(target_info.no_copy_data_size, kFileSize /* expect one file */); + EXPECT_EQ(target_info.remain_in_ash_data_size, + kFileSize * 2 /* expect two files */); + EXPECT_EQ(target_info.deletable_data_size, kFileSize /* expect one file */); EXPECT_EQ(target_info.lacros_data_size, kFileSize * 2 /* expect two files */); EXPECT_EQ(target_info.common_data_size, kFileSize * 2 /* expect two file */); // Check for ash data. - std::vector<BrowserDataMigratorImpl::TargetItem> expected_ash_data_items = { - {from_dir_.Append(kDownloads), kFileSize, - BrowserDataMigratorImpl::TargetItem::ItemType::kDirectory}, - {from_dir_.Append(kFullRestoreData), kFileSize, - BrowserDataMigratorImpl::TargetItem::ItemType::kFile}}; - std::sort(target_info.ash_data_items.begin(), - target_info.ash_data_items.end(), TargetItemComparator()); - ASSERT_EQ(target_info.ash_data_items.size(), expected_ash_data_items.size()); - for (int i = 0; i < target_info.ash_data_items.size(); i++) { - SCOPED_TRACE(target_info.ash_data_items[i].path.value()); - EXPECT_EQ(target_info.ash_data_items[i], expected_ash_data_items[i]); + std::vector<BrowserDataMigratorImpl::TargetItem> + expected_remain_in_ash_items = { + {from_dir_.Append(kDownloads), kFileSize, + BrowserDataMigratorImpl::TargetItem::ItemType::kDirectory}, + {from_dir_.Append(kFullRestoreData), kFileSize, + BrowserDataMigratorImpl::TargetItem::ItemType::kFile}}; + std::sort(target_info.remain_in_ash_items.begin(), + target_info.remain_in_ash_items.end(), TargetItemComparator()); + ASSERT_EQ(target_info.remain_in_ash_items.size(), + expected_remain_in_ash_items.size()); + for (int i = 0; i < target_info.remain_in_ash_items.size(); i++) { + SCOPED_TRACE(target_info.remain_in_ash_items[i].path.value()); + EXPECT_EQ(target_info.remain_in_ash_items[i], + expected_remain_in_ash_items[i]); } // Check for lacros data. @@ -193,7 +235,7 @@ } } -TEST_F(BrowserDataMigratorTest, CopyDirectory) { +TEST_F(BrowserDataMigratorImplTest, CopyDirectory) { const base::FilePath copy_from = user_data_dir_.GetPath().Append("copy_from"); const base::FilePath copy_to = user_data_dir_.GetPath().Append("copy_to"); @@ -240,12 +282,9 @@ EXPECT_FALSE(base::PathExists(copy_to.Append(kFirstRun))); } -TEST_F(BrowserDataMigratorTest, DryRunToCollectUMA) { +TEST_F(BrowserDataMigratorImplTest, DryRunToCollectUMA) { base::HistogramTester histogram_tester; - ASSERT_TRUE(base::WriteFile(from_dir_.Append(FILE_PATH_LITERAL("abcd")), - kDataContent, kFileSize)); - BrowserDataMigratorImpl::DryRunToCollectUMA(from_dir_); std::string uma_name_cache = @@ -266,9 +305,6 @@ std::string uma_name_afiiliation_database = std::string(browser_data_migrator_util::kUserDataStatsRecorderDataSize) + "AffiliationDatabase"; - std::string uma_name_unknown = - std::string(browser_data_migrator_util::kUserDataStatsRecorderDataSize) + - browser_data_migrator_util::kUnknownUMAName; histogram_tester.ExpectTotalCount(uma_name_cache, 1); histogram_tester.ExpectTotalCount(uma_name_downloads, 1); @@ -276,7 +312,6 @@ histogram_tester.ExpectTotalCount(uma_name_bookmarks, 1); histogram_tester.ExpectTotalCount(uma_name_cookies, 1); histogram_tester.ExpectTotalCount(uma_name_afiiliation_database, 1); - histogram_tester.ExpectTotalCount(uma_name_unknown, 1); histogram_tester.ExpectBucketCount(uma_name_cache, kFileSize / 1024 / 1024, 1); @@ -290,8 +325,6 @@ 1); histogram_tester.ExpectBucketCount(uma_name_afiiliation_database, kFileSize * 2 / 1024 / 1024, 1); - histogram_tester.ExpectBucketCount(uma_name_unknown, kFileSize / 1024 / 1024, - 1); histogram_tester.ExpectBucketCount(kDryRunNoCopyDataSize, kFileSize / 1024 / 1024, 1); @@ -300,7 +333,7 @@ histogram_tester.ExpectBucketCount(kDryRunLacrosDataSize, kFileSize / 1024 / 1024, 1); histogram_tester.ExpectBucketCount(kDryRunCommonDataSize, - kFileSize * 3 / 1024 / 1024, 1); + kFileSize * 2 / 1024 / 1024, 1); histogram_tester.ExpectTotalCount(kDryRunCopyMigrationHasEnoughDiskSpace, 1); histogram_tester.ExpectTotalCount(kDryRunMoveMigrationHasEnoughDiskSpace, 1); @@ -310,7 +343,7 @@ kDryRunDeleteAndMoveMigrationHasEnoughDiskSpace, 1); } -TEST_F(BrowserDataMigratorTest, RecordStatus) { +TEST_F(BrowserDataMigratorImplTest, RecordStatus) { { // If `FinalStatus::kSkipped`, only record the status and do not record // copied data size or total time. @@ -333,10 +366,10 @@ base::HistogramTester histogram_tester; BrowserDataMigratorImpl::TargetInfo target_info; - target_info.ash_data_size = /* 300 MBs */ 300 * 1024 * 1024; + target_info.remain_in_ash_data_size = /* 300 MBs */ 300 * 1024 * 1024; target_info.lacros_data_size = /* 400 MBs */ 400 * 1024 * 1024; target_info.common_data_size = /* 500 MBs */ 500 * 1024 * 1024; - target_info.no_copy_data_size = /* 600 MBs */ 600 * 1024 * 1024; + target_info.deletable_data_size = /* 600 MBs */ 600 * 1024 * 1024; base::ElapsedTimer timer; @@ -355,17 +388,17 @@ histogram_tester.ExpectBucketCount( kCopiedDataSize, target_info.TotalCopySize() / (1024 * 1024), 1); histogram_tester.ExpectBucketCount( - kAshDataSize, target_info.ash_data_size / (1024 * 1024), 1); + kAshDataSize, target_info.remain_in_ash_data_size / (1024 * 1024), 1); histogram_tester.ExpectBucketCount( kLacrosDataSize, target_info.lacros_data_size / (1024 * 1024), 1); histogram_tester.ExpectBucketCount( kCommonDataSize, target_info.common_data_size / (1024 * 1024), 1); histogram_tester.ExpectBucketCount( - kNoCopyDataSize, target_info.no_copy_data_size / (1024 * 1024), 1); + kNoCopyDataSize, target_info.deletable_data_size / (1024 * 1024), 1); } } -TEST_F(BrowserDataMigratorTest, SetupTmpDir) { +TEST_F(BrowserDataMigratorImplTest, SetupTmpDir) { base::FilePath tmp_dir = from_dir_.Append(kTmpDir); scoped_refptr<CancelFlag> cancel_flag = base::MakeRefCounted<CancelFlag>(); BrowserDataMigratorImpl::TargetInfo target_info = @@ -392,7 +425,7 @@ .Append(kDataFile))); } -TEST_F(BrowserDataMigratorTest, CancelSetupTmpDir) { +TEST_F(BrowserDataMigratorImplTest, CancelSetupTmpDir) { base::FilePath tmp_dir = from_dir_.Append(kTmpDir); scoped_refptr<CancelFlag> cancel_flag = base::MakeRefCounted<CancelFlag>(); FakeMigrationProgressTracker progress_tracker; @@ -413,7 +446,7 @@ base::PathExists(tmp_dir.Append(kLacrosProfilePath).Append(kCookies))); } -TEST_F(BrowserDataMigratorTest, MigrateInternal) { +TEST_F(BrowserDataMigratorImplTest, MigrateInternal) { base::HistogramTester histogram_tester; { @@ -476,7 +509,7 @@ kFileSize * 4 / (1024 * 1024), 1); } -TEST_F(BrowserDataMigratorTest, Migrate) { +TEST_F(BrowserDataMigratorImplTest, Migrate) { base::test::TaskEnvironment task_environment; scoped_refptr<CancelFlag> cancelled = base::MakeRefCounted<CancelFlag>(); std::unique_ptr<MigrationProgressTracker> progress_tracker = @@ -517,7 +550,7 @@ version_info::GetVersion()); } -TEST_F(BrowserDataMigratorTest, MigrateCancelled) { +TEST_F(BrowserDataMigratorImplTest, MigrateCancelled) { base::test::TaskEnvironment task_environment; scoped_refptr<CancelFlag> cancelled = base::MakeRefCounted<CancelFlag>(); std::unique_ptr<MigrationProgressTracker> progress_tracker =
diff --git a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc index 77d4e031..652a8a5f 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
@@ -834,7 +834,8 @@ OobeScreenWaiter(EnrollmentScreenView::kScreenId).Wait(); enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - EXPECT_EQ(EnrollmentScreen::Result::BACK, enrollment_ui_.WaitForScreenExit()); + EXPECT_EQ(EnrollmentScreen::Result::BACK_TO_AUTO_ENROLLMENT_CHECK, + enrollment_ui_.WaitForScreenExit()); } // Device is disabled. @@ -990,7 +991,8 @@ // User can't skip. enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - EXPECT_EQ(EnrollmentScreen::Result::BACK, enrollment_ui_.WaitForScreenExit()); + EXPECT_EQ(EnrollmentScreen::Result::BACK_TO_AUTO_ENROLLMENT_CHECK, + enrollment_ui_.WaitForScreenExit()); enrollment_screen()->OnLoginDone(FakeGaiaMixin::kEnterpriseUser1, FakeGaiaMixin::kFakeAuthCode); @@ -1034,7 +1036,8 @@ // User can't skip. enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - EXPECT_EQ(EnrollmentScreen::Result::BACK, enrollment_ui_.WaitForScreenExit()); + EXPECT_EQ(EnrollmentScreen::Result::BACK_TO_AUTO_ENROLLMENT_CHECK, + enrollment_ui_.WaitForScreenExit()); // Domain is actually different from what the server sent down. But Chrome // does not enforce that domain if device is not locked.
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.cc b/chrome/browser/ash/login/enrollment/enrollment_screen.cc index 82d0891..63eb308 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.cc
@@ -111,6 +111,8 @@ return "TpmError"; case Result::TPM_DBUS_ERROR: return "TpmDbusError"; + case Result::BACK_TO_AUTO_ENROLLMENT_CHECK: + return "BackToAutoEnrollmentCheck"; } } @@ -478,8 +480,10 @@ // The callback passed to ClearAuth is called either immediately or gets // wrapped in a callback bound to a weak pointer from `weak_factory_` - in // either case, passing exit_callback_ directly should be safe. - ClearAuth(base::BindRepeating( - exit_callback_, config_.is_forced() ? Result::BACK : Result::COMPLETED)); + ClearAuth(base::BindRepeating(exit_callback_, + config_.is_forced() + ? Result::BACK_TO_AUTO_ENROLLMENT_CHECK + : Result::BACK)); } void EnrollmentScreen::OnConfirmationClosed() {
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.h b/chrome/browser/ash/login/enrollment/enrollment_screen.h index dc6f299a..69d867c 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.h +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.h
@@ -51,7 +51,8 @@ BACK, SKIPPED_FOR_TESTS, TPM_ERROR, - TPM_DBUS_ERROR + TPM_DBUS_ERROR, + BACK_TO_AUTO_ENROLLMENT_CHECK, }; static std::string GetResultString(Result result);
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc index ac36163..42a1951 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc
@@ -161,7 +161,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepTPMChecking); test::OobeJS().TapOnPath(kEnrollmentTPMCheckCancelButton); EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); - EXPECT_EQ(screen_result, EnrollmentScreen::Result::COMPLETED); + EXPECT_EQ(screen_result, EnrollmentScreen::Result::BACK); } INSTANTIATE_TEST_SUITE_P(All, @@ -175,7 +175,7 @@ enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); - EXPECT_EQ(EnrollmentScreen::Result::COMPLETED, screen_result); + EXPECT_EQ(EnrollmentScreen::Result::BACK, screen_result); } IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, TestSuccess) { @@ -212,7 +212,7 @@ enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); - EXPECT_EQ(EnrollmentScreen::Result::COMPLETED, screen_result); + EXPECT_EQ(EnrollmentScreen::Result::BACK, screen_result); } IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, EnrollmentSpinner) { @@ -256,7 +256,8 @@ enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); - EXPECT_EQ(EnrollmentScreen::Result::BACK, screen_result); + EXPECT_EQ(EnrollmentScreen::Result::BACK_TO_AUTO_ENROLLMENT_CHECK, + screen_result); } class MultiAuthEnrollmentScreenTest : public EnrollmentScreenTest { @@ -289,7 +290,8 @@ enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); - EXPECT_EQ(EnrollmentScreen::Result::BACK, screen_result); + EXPECT_EQ(EnrollmentScreen::Result::BACK_TO_AUTO_ENROLLMENT_CHECK, + screen_result); } class ProvisionedEnrollmentScreenTest : public EnrollmentScreenTest { @@ -320,7 +322,8 @@ enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); - EXPECT_EQ(EnrollmentScreen::Result::BACK, screen_result); + EXPECT_EQ(EnrollmentScreen::Result::BACK_TO_AUTO_ENROLLMENT_CHECK, + screen_result); } class OobeCompletedUnownedTest : public OobeBaseTest {
diff --git a/chrome/browser/ash/login/help_app_launcher.cc b/chrome/browser/ash/login/help_app_launcher.cc index c465d3a..e4bda34 100644 --- a/chrome/browser/ash/login/help_app_launcher.cc +++ b/chrome/browser/ash/login/help_app_launcher.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ash/login/ui/login_web_dialog.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/locale_settings.h" #include "content/public/browser/browser_thread.h" @@ -26,9 +27,6 @@ using ::content::BrowserThread; using ::extensions::ExtensionRegistry; -// Official HelpApp extension id. -const char kExtensionId[] = "honijodknafkokifofgiaalefdiedpko"; - const char kHelpAppFormat[] = "chrome-extension://%s/oobe.html?id=%d"; const char* g_extension_id_for_test = nullptr; @@ -49,7 +47,7 @@ if (!registry) return; - const char* extension_id = kExtensionId; + const char* extension_id = extension_misc::kHelpAppExtensionId; if (g_extension_id_for_test && *g_extension_id_for_test != '\0') { extension_id = g_extension_id_for_test; }
diff --git a/chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc b/chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc index a863d77..0587dcea 100644 --- a/chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc +++ b/chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_impl.cc
@@ -16,7 +16,9 @@ #include "base/strings/string_util.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" +#include "chrome/browser/about_flags.h" #include "chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_delegate.h" +#include "chrome/common/chrome_features.h" #include "content/public/browser/gpu_data_manager.h" #include "extensions/common/api/system_display.h" #include "gpu/config/gpu_info.h" @@ -40,6 +42,9 @@ constexpr const char kGetAppListUrl[] = "https://android.clients.google.com/fdfe/chrome/getfastreinstallappslist"; +constexpr const char kGetRevisedAppListUrl[] = + "https://android.clients.google.com/fdfe/chrome/getSetupAppRecommendations"; + constexpr int kResponseErrorNotEnoughApps = 5; constexpr int kResponseErrorNotFirstTimeChromebookUser = 6; @@ -430,7 +435,11 @@ })"); auto resource_request = std::make_unique<network::ResourceRequest>(); - resource_request->url = GURL(kGetAppListUrl); + if (base::FeatureList::IsEnabled(features::kAppDiscoveryForOobe)) { + resource_request->url = GURL(kGetRevisedAppListUrl); + } else { + resource_request->url = GURL(kGetAppListUrl); + } resource_request->method = "GET"; resource_request->load_flags = net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE; @@ -500,13 +509,23 @@ base::StringPiece response_body_json(*response_body); if (base::StartsWith(response_body_json, json_xss_prevention_prefix)) response_body_json.remove_prefix(json_xss_prevention_prefix.length()); - absl::optional<base::Value> output = ParseResponse(response_body_json); - if (!output.has_value()) { - RecordUmaResponseAppCount(0); - delegate_->OnParseResponseError(); - return; - } + absl::optional<base::Value> output; + if (base::FeatureList::IsEnabled(features::kAppDiscoveryForOobe)) { + output = + base::JSONReader::ReadAndReturnValueWithError(response_body_json).value; + if (!output.has_value()) { + delegate_->OnParseResponseError(); + return; + } + } else { + output = ParseResponse(response_body_json); + if (!output.has_value()) { + RecordUmaResponseAppCount(0); + delegate_->OnParseResponseError(); + return; + } + } delegate_->OnLoadSuccess(std::move(output.value())); }
diff --git a/chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc b/chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc index 57a43d7..802105e0 100644 --- a/chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc +++ b/chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher_impl_unittest.cc
@@ -15,10 +15,12 @@ #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/values.h" #include "chrome/browser/ash/login/screens/recommend_apps/fake_recommend_apps_fetcher_delegate.h" #include "chrome/browser/ash/login/screens/recommend_apps/recommend_apps_fetcher.h" +#include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/user_manager/scoped_user_manager.h" @@ -307,6 +309,10 @@ header_reader.GetSystemAvailableFeatures()); } + void EnableAppDiscoveryFlag() { + scoped_feature_list_.InitAndEnableFeature(features::kAppDiscoveryForOobe); + } + FakeRecommendAppsFetcherDelegate delegate_; network::TestURLLoaderFactory test_url_loader_factory_; std::unique_ptr<RecommendAppsFetcher> recommend_apps_fetcher_; @@ -319,10 +325,17 @@ private: void InterceptRequest(const network::ResourceRequest& request) { - ASSERT_EQ( - "https://android.clients.google.com/fdfe/chrome/" - "getfastreinstallappslist", - request.url.spec()); + if (base::FeatureList::IsEnabled(features::kAppDiscoveryForOobe)) { + ASSERT_EQ( + "https://android.clients.google.com/fdfe/chrome/" + "getSetupAppRecommendations", + request.url.spec()); + } else { + ASSERT_EQ( + "https://android.clients.google.com/fdfe/chrome/" + "getfastreinstallappslist", + request.url.spec()); + } if (request_waiter_) request_waiter_->Quit(); } @@ -333,6 +346,7 @@ } content::BrowserTaskEnvironment task_environment_; + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<base::RunLoop> request_waiter_; }; @@ -1379,4 +1393,65 @@ recommend_apps_fetcher_->Start(); } +TEST_F(RecommendAppsFetcherImplTest, AppDiscoveryValidResponse) { + EnableAppDiscoveryFlag(); + + ASSERT_TRUE(recommend_apps_fetcher_); + + recommend_apps_fetcher_->Start(); + + cros_display_config_->Flush(); + ASSERT_TRUE(cros_display_config_->RunGetDisplayUnitInfoListCallback( + CreateDisplayUnitInfo(Dpi(117, 117), absl::nullopt))); + + ASSERT_TRUE(arc_features_callback_); + std::move(arc_features_callback_).Run(CreateArcFeaturesForTest()); + + network::ResourceRequest* request = WaitForAppListRequest(); + ASSERT_TRUE(request); + + const std::string response = + R"({"recommendedApp": [{ + "androidApp": { + "packageName": "com.game.name", + "title": "NameOfFunGame", + "icon": { + "imageUri": "https://play-lh.googleusercontent.com/1234IDECLAREATHUMBWAR", + "dimensions": { + "width": 512, + "height": 512 + } + } + } + }]})"; + + test_url_loader_factory_.AddResponse(request->url.spec(), response); + + EXPECT_EQ(FakeRecommendAppsFetcherDelegate::Result::SUCCESS, + delegate_.WaitForResult()); +} + +TEST_F(RecommendAppsFetcherImplTest, AppDiscoveryParseErrorResponse) { + EnableAppDiscoveryFlag(); + + ASSERT_TRUE(recommend_apps_fetcher_); + + recommend_apps_fetcher_->Start(); + + cros_display_config_->Flush(); + ASSERT_TRUE(cros_display_config_->RunGetDisplayUnitInfoListCallback( + CreateDisplayUnitInfo(Dpi(117, 117), absl::nullopt))); + + ASSERT_TRUE(arc_features_callback_); + std::move(arc_features_callback_).Run(CreateArcFeaturesForTest()); + + network::ResourceRequest* request = WaitForAppListRequest(); + ASSERT_TRUE(request); + + test_url_loader_factory_.AddResponse(request->url.spec(), ")}]'!2%^$"); + + EXPECT_EQ(FakeRecommendAppsFetcherDelegate::Result::PARSE_ERROR, + delegate_.WaitForResult()); +} + } // namespace ash
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc index 75e7d52..c5bb074f 100644 --- a/chrome/browser/ash/login/wizard_controller.cc +++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -1423,12 +1423,11 @@ << EnrollmentScreen::GetResultString(result) << ")."; switch (result) { case EnrollmentScreen::Result::COMPLETED: - case EnrollmentScreen::Result::SKIPPED_FOR_TESTS: OnEnrollmentDone(); break; case EnrollmentScreen::Result::BACK: - retry_auto_enrollment_check_ = true; - ShowAutoEnrollmentCheckScreen(); + case EnrollmentScreen::Result::SKIPPED_FOR_TESTS: + ShowPackagedLicenseScreen(); break; case EnrollmentScreen::Result::TPM_ERROR: DCHECK(switches::IsTpmDynamic()); @@ -1440,6 +1439,10 @@ wizard_context_->tpm_dbus_error = true; AdvanceToScreen(TpmErrorView::kScreenId); break; + case EnrollmentScreen::Result::BACK_TO_AUTO_ENROLLMENT_CHECK: + retry_auto_enrollment_check_ = true; + ShowAutoEnrollmentCheckScreen(); + break; } }
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc index 6029f0a..66108cbb 100644 --- a/chrome/browser/ash/login/wizard_controller_browsertest.cc +++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -2177,7 +2177,8 @@ // Make sure enterprise enrollment page shows up right after update screen. CheckCurrentScreen(EnrollmentScreenView::kScreenId); EXPECT_CALL(*mock_auto_enrollment_check_screen_, ShowImpl()).Times(1); - mock_enrollment_screen_->ExitScreen(EnrollmentScreen::Result::BACK); + mock_enrollment_screen_->ExitScreen( + EnrollmentScreen::Result::BACK_TO_AUTO_ENROLLMENT_CHECK); CheckCurrentScreen(AutoEnrollmentCheckScreenView::kScreenId); EXPECT_FALSE(StartupUtils::IsOobeCompleted());
diff --git a/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.cc b/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.cc index 75b96bf..00903511 100644 --- a/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.cc +++ b/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.cc
@@ -3,6 +3,10 @@ // found in the LICENSE file. #include "chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h" + +#include "base/callback.h" +#include "base/task/sequenced_task_runner.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "testing/gmock/include/gmock/gmock.h" namespace wallpaper_handlers { @@ -10,7 +14,7 @@ MockGooglePhotosCountFetcher::MockGooglePhotosCountFetcher(Profile* profile) : GooglePhotosCountFetcher(profile) { ON_CALL(*this, AddCallbackAndStartIfNecessary) - .WillByDefault([](OnGooglePhotosCountFetched callback) { + .WillByDefault([](base::OnceCallback<void(int)> callback) { base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), /*count=*/0)); });
diff --git a/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h b/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h index 8f20cbbc..68fc65c 100644 --- a/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h +++ b/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_MOCK_WALLPAPER_HANDLERS_H_ #define CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_MOCK_WALLPAPER_HANDLERS_H_ -#include "ash/webui/personalization_app/mojom/personalization_app.mojom.h" +#include "base/callback_forward.h" #include "chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h" #include "testing/gmock/include/gmock/gmock.h" @@ -24,11 +24,9 @@ ~MockGooglePhotosCountFetcher() override; // GooglePhotosCountFetcher: - using OnGooglePhotosCountFetched = ash::personalization_app::mojom:: - WallpaperProvider::FetchGooglePhotosCountCallback; MOCK_METHOD(void, AddCallbackAndStartIfNecessary, - (OnGooglePhotosCountFetched callback), + (base::OnceCallback<void(int)> callback), (override)); };
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc index d2a3f06..9504119 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h" -#include <tuple> #include <utility> #include "ash/constants/ash_features.h" @@ -403,8 +402,8 @@ surprise_me_image_response.resume_token()); } -template <typename... Args> -GooglePhotosFetcher<Args...>::GooglePhotosFetcher( +template <typename T> +GooglePhotosFetcher<T>::GooglePhotosFetcher( Profile* profile, const char* service_url, const net::NetworkTrafficAnnotationTag& traffic_annotation) @@ -419,11 +418,11 @@ identity_manager_observation_.Observe(identity_manager_); } -template <typename... Args> -GooglePhotosFetcher<Args...>::~GooglePhotosFetcher() = default; +template <typename T> +GooglePhotosFetcher<T>::~GooglePhotosFetcher() = default; -template <typename... Args> -void GooglePhotosFetcher<Args...>::AddCallbackAndStartIfNecessary( +template <typename T> +void GooglePhotosFetcher<T>::AddCallbackAndStartIfNecessary( ClientCallback callback) { pending_client_callbacks_.push_back(std::move(callback)); if (pending_client_callbacks_.size() > 1) @@ -441,8 +440,8 @@ signin::ConsentLevel::kSignin); } -template <typename... Args> -void GooglePhotosFetcher<Args...>::OnTokenReceived( +template <typename T> +void GooglePhotosFetcher<T>::OnTokenReceived( GoogleServiceAuthError error, signin::AccessTokenInfo token_info) { token_fetcher_.reset(); @@ -471,8 +470,8 @@ base::Unretained(this) /*`this` owns `url_loader_`.*/)); } -template <typename... Args> -void GooglePhotosFetcher<Args...>::OnJsonReceived( +template <typename T> +void GooglePhotosFetcher<T>::OnJsonReceived( std::unique_ptr<std::string> response_body) { const int net_error = url_loader_->NetError(); url_loader_.reset(); @@ -491,17 +490,13 @@ weak_factory_.GetWeakPtr()))); } -template <typename... Args> -void GooglePhotosFetcher<Args...>::OnResponseReady( +template <typename T> +void GooglePhotosFetcher<T>::OnResponseReady( absl::optional<base::Value> response) { - std::tuple<Args...> args = ParseResponse(std::move(response)); - std::apply( - [&](Args... args) { - for (auto& callback : pending_client_callbacks_) - std::move(callback).Run(std::forward<Args>(args)...); - pending_client_callbacks_.clear(); - }, - args); + T args = ParseResponse(std::move(response)); + for (auto& callback : pending_client_callbacks_) + std::move(callback).Run(args); + pending_client_callbacks_.clear(); } GooglePhotosCountFetcher::GooglePhotosCountFetcher(Profile* profile) @@ -513,21 +508,21 @@ GooglePhotosCountFetcher::~GooglePhotosCountFetcher() = default; -std::tuple<int> GooglePhotosCountFetcher::ParseResponse( +int GooglePhotosCountFetcher::ParseResponse( absl::optional<base::Value> response) { if (!response.has_value()) - return std::make_tuple(-1); + return -1; const base::Value* user = response->FindDictPath("user"); if (!user) - return std::make_tuple(-1); + return -1; const std::string* count_string = user->FindStringKey("numPhotos"); int64_t count; if (!count_string || !base::StringToInt64(*count_string, &count)) - return std::make_tuple(-1); + return -1; - return std::make_tuple(base::saturated_cast<int>(count)); + return base::saturated_cast<int>(count); } } // namespace wallpaper_handlers
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h index 8e6d7298..871c39b0e 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h
@@ -6,7 +6,6 @@ #define CHROME_BROWSER_ASH_WALLPAPER_HANDLERS_WALLPAPER_HANDLERS_H_ #include <memory> -#include <tuple> #include "base/callback.h" #include "base/scoped_observation.h" @@ -145,7 +144,8 @@ }; // Base class for common logic among fetchers that query the Google Photos API. -template <typename... Args> +// Parametrized by the client callback's argument type. +template <typename T> class GooglePhotosFetcher : public signin::IdentityManager::Observer { public: GooglePhotosFetcher( @@ -159,7 +159,7 @@ ~GooglePhotosFetcher() override; // Issues an API request if and only if one is not in progress. - using ClientCallback = base::OnceCallback<void(Args...)>; + using ClientCallback = base::OnceCallback<void(T)>; virtual void AddCallbackAndStartIfNecessary(ClientCallback callback); protected: @@ -167,8 +167,7 @@ // was an error in sending the request, receiving the response, or parsing the // response; otherwise, it will hold a response in the API's specified // structure. - virtual std::tuple<Args...> ParseResponse( - absl::optional<base::Value> response) = 0; + virtual T ParseResponse(absl::optional<base::Value> response) = 0; private: void OnTokenReceived(GoogleServiceAuthError error, @@ -218,7 +217,7 @@ private: // GooglePhotosFetcher: - std::tuple<int> ParseResponse(absl::optional<base::Value> response) override; + int ParseResponse(absl::optional<base::Value> response) override; }; } // namespace wallpaper_handlers
diff --git a/chrome/browser/chromeos/extensions/signin_screen_policy_provider_unittest.cc b/chrome/browser/chromeos/extensions/signin_screen_policy_provider_unittest.cc index 82e99bd..124df3c 100644 --- a/chrome/browser/chromeos/extensions/signin_screen_policy_provider_unittest.cc +++ b/chrome/browser/chromeos/extensions/signin_screen_policy_provider_unittest.cc
@@ -6,6 +6,7 @@ #include "base/memory/ref_counted.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/common/extensions/extension_constants.h" #include "components/version_info/version_info.h" #include "extensions/common/extension_builder.h" #include "extensions/common/features/feature_channel.h" @@ -18,8 +19,6 @@ namespace { const char kRandomExtensionId[] = "abacabadabacabaeabacabadabacabaf"; -// Gnubby -const char kGnubbyExtensionId[] = "beknehfpfkghjoafdifaflglpjkojoco"; // smart card connector const char kSampleSigninExtensionId[] = "khpfeaanjngmcnplbdlpegiifgpfgdco"; @@ -74,8 +73,8 @@ TEST_F(SigninScreenPolicyProviderTest, AllowEssentialExtension) { // Essential component extensions for the login screen should always work. - scoped_refptr<const extensions::Extension> extension = - CreateTestApp(kGnubbyExtensionId, ManifestLocation::kExternalComponent); + scoped_refptr<const extensions::Extension> extension = CreateTestApp( + extension_misc::kGnubbyAppId, ManifestLocation::kExternalComponent); std::u16string error; EXPECT_TRUE(provider_.UserMayLoad(extension.get(), &error)); EXPECT_TRUE(error.empty());
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc index cb4fca0..0851798d 100644 --- a/chrome/browser/client_hints/client_hints_browsertest.cc +++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -1549,8 +1549,7 @@ } // Flaky on all platforms. https://crbug.com/1285479. -IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, - DISABLED_DelegateToFoo_MetaName) { +IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, DelegateToFoo_MetaName) { // Go to a page which delegates hints to `foo.com`. GURL gurl = meta_name_accept_ch_delegation_foo(); SetClientHintExpectationsOnMainFrame(false);
diff --git a/chrome/browser/commerce/price_tracking/android/DEPS b/chrome/browser/commerce/price_tracking/android/DEPS index 26a8e4a..2da1d46 100644 --- a/chrome/browser/commerce/price_tracking/android/DEPS +++ b/chrome/browser/commerce/price_tracking/android/DEPS
@@ -2,11 +2,10 @@ "+chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingUtilities.java", "+chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java", "+chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java", - "+chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java", "+chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java", "+chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java", "+chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java", "+chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitions.java", "+components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java", "+components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcherFactory.java", -] +] \ No newline at end of file
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java index 9c96877e..893cfa9a 100644 --- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java +++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java
@@ -26,14 +26,12 @@ import org.chromium.base.IntentUtils; import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; -import org.chromium.chrome.browser.bookmarks.BookmarkBridge; import org.chromium.chrome.browser.browserservices.intents.WebappConstants; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.notifications.NotificationIntentInterceptor; import org.chromium.chrome.browser.notifications.NotificationUmaTracker; import org.chromium.chrome.browser.notifications.channels.ChromeChannelDefinitions; -import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.subscriptions.CommerceSubscription; import org.chromium.chrome.browser.subscriptions.CommerceSubscription.CommerceSubscriptionType; import org.chromium.chrome.browser.subscriptions.CommerceSubscription.SubscriptionManagementType; @@ -233,40 +231,19 @@ String.format( Locale.US, "Failed to remove subscriptions. Status: %d", status)); }; - BookmarkBridge bookmarkBridge = new BookmarkBridge(Profile.getLastUsedRegularProfile()); - - Runnable unsubscribeRunnable = () -> { - if (offerId != null) { - subscriptionsManager.unsubscribe( - new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, offerId, - SubscriptionManagementType.CHROME_MANAGED, - TrackingIdType.OFFER_ID), - callback); - } - if (clusterId != null) { - subscriptionsManager.unsubscribe( - new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, - clusterId, SubscriptionManagementType.USER_MANAGED, - TrackingIdType.PRODUCT_CLUSTER_ID), - callback); - } - }; - - // Only attempt to unsubscribe once the corresponding bookmarks can also be updated. - if (bookmarkBridge.isBookmarkModelLoaded()) { - unsubscribeRunnable.run(); - } else { - bookmarkBridge.addObserver(new BookmarkBridge.BookmarkModelObserver() { - @Override - public void bookmarkModelLoaded() { - unsubscribeRunnable.run(); - } - - @Override - public void bookmarkModelChanged() {} - }); + if (offerId != null) { + subscriptionsManager.unsubscribe( + new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, offerId, + SubscriptionManagementType.CHROME_MANAGED, TrackingIdType.OFFER_ID), + callback); } - + if (clusterId != null) { + subscriptionsManager.unsubscribe( + new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, clusterId, + SubscriptionManagementType.USER_MANAGED, + TrackingIdType.PRODUCT_CLUSTER_ID), + callback); + } if (recordMetrics) { NotificationUmaTracker.getInstance().onNotificationActionClick( NotificationUmaTracker.ActionType.PRICE_DROP_TURN_OFF_ALERT,
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java index e9afc28..2325625 100644 --- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java +++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java
@@ -22,7 +22,8 @@ /** Performs any deferred startup tasks required by {@link Subscriptions}. */ public void initDeferredStartupForActivity(TabModelSelector tabModelSelector, ActivityLifecycleDispatcher activityLifecycleDispatcher) { - if (mImplicitPriceDropSubscriptionsManager == null) { + if (CommerceSubscriptionsServiceConfig.isImplicitSubscriptionsEnabled() + && mImplicitPriceDropSubscriptionsManager == null) { mImplicitPriceDropSubscriptionsManager = new ImplicitPriceDropSubscriptionsManager( tabModelSelector, activityLifecycleDispatcher, mSubscriptionManager); }
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceConfig.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceConfig.java index 3af6f12..04da4850 100644 --- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceConfig.java +++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceConfig.java
@@ -24,6 +24,9 @@ private static final String STALE_TAB_LOWER_BOUND_SECONDS_PARAM = "price_tracking_stale_tab_lower_bound_seconds"; + private static final String IMPLICIT_SUBSCRIPTIONS_ENABLED_PARAM = + "implicit_subscriptions_enabled"; + private static final int DEFAULT_STALE_TAB_LOWER_BOUND_DAYS = 1; public static String getDefaultServiceUrl() { @@ -45,4 +48,13 @@ } return defaultValue; } + + public static boolean isImplicitSubscriptionsEnabled() { + if (FeatureList.isInitialized()) { + return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( + ChromeFeatureList.COMMERCE_PRICE_TRACKING, IMPLICIT_SUBSCRIPTIONS_ENABLED_PARAM, + true); + } + return true; + } }
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc index 5616953..578cdd2 100644 --- a/chrome/browser/devtools/devtools_browsertest.cc +++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -529,8 +529,10 @@ .Set("manifest_version", 2) // simple_test_page.html is currently the only page referenced outside // of its own extension in the tests - .Set("web_accessible_resources", - extensions::ListBuilder().Append("simple_test_page.html").Build()); + .Set("web_accessible_resources", extensions::ListBuilder() + .Append("simple_test_page.html") + .Append("source.map") + .Build()); // If |devtools_page| isn't empty, make it a devtools extension in the // manifest. @@ -567,6 +569,9 @@ " }\n" ");\n"); + dir->WriteFile(FILE_PATH_LITERAL("source.map"), + R"({"version":3,"sources":["foo.js"],"mappings":"AAyCAA"})"); + dir->WriteFile(FILE_PATH_LITERAL("sidebarpane_devtools_page.html"), "<html><head><script src='sidebarpane_devtools_page.js'>" "</script></head><body></body></html>"); @@ -2720,6 +2725,30 @@ CloseDevToolsWindow(); } +IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest, SourceMapsFromExtension) { + const Extension* extension = + LoadExtensionForTest("Non-DevTools Extension", "" /* devtools_page */, + "" /* panel_iframe_src */); + ASSERT_TRUE(extension); + OpenDevToolsWindow(kEmptyTestPage, /* is_docked */ false); + DispatchOnTestSuite(window_, "testSourceMapsFromExtension", + extension->id().c_str()); + CloseDevToolsWindow(); +} + +IN_PROC_BROWSER_TEST_F(DevToolsTest, SourceMapsFromDevtools) { + OpenDevToolsWindow(kEmptyTestPage, /* is_docked */ false); + DispatchOnTestSuite(window_, "testSourceMapsFromDevtools"); + CloseDevToolsWindow(); +} + +IN_PROC_BROWSER_TEST_F(DevToolsTest, + DoesNotCrashOnSourceMapsFromUnknownScheme) { + OpenDevToolsWindow(kEmptyTestPage, /* is_docked */ false); + DispatchOnTestSuite(window_, "testDoesNotCrashOnSourceMapsFromUnknownScheme"); + CloseDevToolsWindow(); +} + IN_PROC_BROWSER_TEST_F(DevToolsExtensionTest, ExtensionWebSocketOfflineNetworkConditions) { net::SpawnedTestServer websocket_server(
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index fb0a4345..3cdb9b58 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -1087,6 +1087,10 @@ "chrome_kiosk_delegate_chromeos.cc", "extension_assets_manager_chromeos.cc", "extension_assets_manager_chromeos.h", + "ash_extension_keeplist_manager.cc", + "ash_extension_keeplist_manager.h", + "extension_keeplist_ash.cc", + "extension_keeplist_ash.h", "extension_garbage_collector_chromeos.cc", "extension_garbage_collector_chromeos.h", "system_display/display_info_provider_chromeos.cc",
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc index ec104d5..6d98fd7 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc
@@ -69,7 +69,7 @@ } void SetProperties(const std::string& guid, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, bool allow_set_shared_config, VoidCallback success_callback, FailureCallback failure_callback) override { @@ -77,7 +77,7 @@ } void CreateNetwork(bool shared, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, StringCallback success_callback, FailureCallback failure_callback) override { StringResult(std::move(success_callback), std::move(failure_callback), @@ -100,13 +100,15 @@ if (fail_) { std::move(failure_callback).Run(kFailure); } else { - std::unique_ptr<base::ListValue> result(new base::ListValue); - std::unique_ptr<base::DictionaryValue> network(new base::DictionaryValue); - network->SetString(::onc::network_config::kType, - ::onc::network_config::kEthernet); - network->SetString(::onc::network_config::kGUID, kGuid); - result->Append(std::move(network)); - std::move(success_callback).Run(std::move(result)); + base::Value result(base::Value::Type::LIST); + base::Value network(base::Value::Type::DICTIONARY); + network.SetStringPath(::onc::network_config::kType, + ::onc::network_config::kEthernet); + network.SetStringPath(::onc::network_config::kGUID, kGuid); + result.Append(std::move(network)); + std::move(success_callback) + .Run(base::ListValue::From( + base::Value::ToUniquePtrValue(std::move(result)))); } } @@ -182,12 +184,12 @@ return result; } - std::unique_ptr<base::DictionaryValue> GetGlobalPolicy() override { - return std::make_unique<base::DictionaryValue>(); + base::Value GetGlobalPolicy() override { + return base::Value(base::Value::Type::DICTIONARY); } - std::unique_ptr<base::DictionaryValue> GetCertificateLists() override { - return std::make_unique<base::DictionaryValue>(); + base::Value GetCertificateLists() override { + return base::Value(base::Value::Type::DICTIONARY); } bool EnableNetworkType(const std::string& type) override { @@ -216,10 +218,10 @@ if (fail_) { std::move(failure_callback).Run(kFailure); } else { - std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue); - result->SetString(::onc::network_config::kGUID, guid); - result->SetString(::onc::network_config::kType, - ::onc::network_config::kWiFi); + base::Value result(base::Value::Type::DICTIONARY); + result.SetStringPath(::onc::network_config::kGUID, guid); + result.SetStringPath(::onc::network_config::kType, + ::onc::network_config::kWiFi); std::move(success_callback).Run(std::move(result)); } }
diff --git a/chrome/browser/extensions/ash_extension_keeplist_manager.cc b/chrome/browser/extensions/ash_extension_keeplist_manager.cc new file mode 100644 index 0000000..b7a7eb5 --- /dev/null +++ b/chrome/browser/extensions/ash_extension_keeplist_manager.cc
@@ -0,0 +1,118 @@ +// Copyright 2021 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/extensions/ash_extension_keeplist_manager.h" + +#include "ash/constants/ash_features.h" +#include "base/check.h" +#include "base/feature_list.h" +#include "chrome/browser/ash/crosapi/browser_util.h" +#include "chrome/browser/extensions/extension_keeplist_ash.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/profiles/profile.h" +#include "extensions/browser/extension_prefs.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/common/extension.h" + +namespace extensions { + +AshExtensionKeeplistManager::AshExtensionKeeplistManager( + Profile* profile, + ExtensionPrefs* extension_prefs, + ExtensionService* extension_service) + : extension_prefs_(extension_prefs), + extension_service_(extension_service), + registry_(ExtensionRegistry::Get(profile)) { + // We should enforce the keep list when Lacros is the only browser. However, + // Lacros as the only browser is not supported yet. To make it easy to test, + // allow enforcing the keep list with Lacros as primary browser. + // TODO(crbug.com/1268846): Enable the enforcement when Lacros is the only + // browser when Lacros as the only browser is supported. + should_enforce_keeplist_ = + crosapi::browser_util::IsLacrosPrimaryBrowser() && + base::FeatureList::IsEnabled( + chromeos::features::kEnforceAshExtensionKeeplist); + if (should_enforce_keeplist_) + registry_observation_.Observe(registry_); +} + +AshExtensionKeeplistManager::~AshExtensionKeeplistManager() = default; + +void AshExtensionKeeplistManager::Init() { + if (should_enforce_keeplist_) + ActivateKeeplistEnforcement(); + else + DeactivateKeeplistEnforcement(); +} + +void AshExtensionKeeplistManager::ActivateKeeplistEnforcement() { + DCHECK(should_enforce_keeplist_); + + std::unique_ptr<ExtensionSet> all_extensions = + registry_->GenerateInstalledExtensionsSet(); + + for (const auto& extension : *all_extensions) { + if (ShouldDisable(extension.get())) + Disable(extension->id()); + } +} + +bool AshExtensionKeeplistManager::ShouldDisable( + const Extension* extension) const { + if (extension->is_extension() && !ExtensionRunsInAsh(extension->id())) + return true; + + if (extension->is_platform_app() && + crosapi::browser_util::IsLacrosChromeAppsEnabled() && + !ExtensionAppRunsInAsh(extension->id())) { + return true; + } + + return false; +} + +void AshExtensionKeeplistManager::Disable(const std::string& extension_id) { + DCHECK(should_enforce_keeplist_); + + extension_service_->DisableExtension( + extension_id, disable_reason::DISABLE_NOT_ASH_KEEPLISTED); + + // An extension is not allowed to be disabled by user due to different reasons + // (shared module, installed as a component extension or installed by policy, + // etc.). We would log a message here to track the extensions that can't be + // disabled and analyze to see if we have missed any extensions in the keep + // list during the audit. + if (registry_->enabled_extensions().Contains(extension_id)) { + LOG(WARNING) << "Can not enforce disabling extension id:" << extension_id; + } +} + +void AshExtensionKeeplistManager::DeactivateKeeplistEnforcement() { + DCHECK(!should_enforce_keeplist_); + + std::unique_ptr<ExtensionSet> all_extensions = + registry_->GenerateInstalledExtensionsSet(); + + // Find all extensions disabled by keeplist enforcement, remove the disable + // reason. + for (const auto& extension : *all_extensions) { + if (extension_prefs_->HasDisableReason( + extension->id(), disable_reason::DISABLE_NOT_ASH_KEEPLISTED)) { + extension_service_->RemoveDisableReasonAndMaybeEnable( + extension->id(), disable_reason::DISABLE_NOT_ASH_KEEPLISTED); + } + } +} + +void AshExtensionKeeplistManager::OnExtensionReady( + content::BrowserContext* browser_context, + const Extension* extension) { + if (!should_enforce_keeplist_) + return; + + if (ShouldDisable(extension)) + Disable(extension->id()); +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/ash_extension_keeplist_manager.h b/chrome/browser/extensions/ash_extension_keeplist_manager.h new file mode 100644 index 0000000..8122ea1 --- /dev/null +++ b/chrome/browser/extensions/ash_extension_keeplist_manager.h
@@ -0,0 +1,77 @@ +// Copyright 2021 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_EXTENSIONS_ASH_EXTENSION_KEEPLIST_MANAGER_H_ +#define CHROME_BROWSER_EXTENSIONS_ASH_EXTENSION_KEEPLIST_MANAGER_H_ + +#include <string> + +#include "base/memory/raw_ptr.h" +#include "base/scoped_observation.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_registry_observer.h" + +class Profile; + +namespace extensions { +class ExtensionPrefs; +class ExtensionRegistry; +class ExtensionService; + +// This class manages the 1st party Ash extension keeplist. When Lacros becomes +// the only browser, all extensions should be installed in Lacros instead of +// Ash. However, there is a small exception set of 1st party extensions and +// platform apps we will keep running in Ash, since they are either needed to +// support some Chrome OS features such as accessibility, or are in the process +// of deprecation, or not completely Lacros compatible yet. This class will +// manage to disable all the extensions and platform apps in Ash if they are +// not in the keep list. +class AshExtensionKeeplistManager : private ExtensionRegistryObserver { + public: + AshExtensionKeeplistManager(Profile* profile, + ExtensionPrefs* extension_prefs, + ExtensionService* extension_service); + AshExtensionKeeplistManager(const AshExtensionKeeplistManager&) = delete; + AshExtensionKeeplistManager& operator=(const AshExtensionKeeplistManager&) = + delete; + ~AshExtensionKeeplistManager() override; + + void Init(); + + private: + // Returns true if |extension| should be disabled. + bool ShouldDisable(const Extension* extension) const; + + // Disables the extension with 'DISABLE_NOT_ASH_KEEPLISTED'. + void Disable(const std::string& extension_id); + + // Blocks all extensions not on the keeplist by disabling them with + // 'DISABLE_NOT_ASH_KEEPLISTED'. + void ActivateKeeplistEnforcement(); + + // Unblocks all extensions by removing 'DISABLE_NOT_ASH_KEEPLISTED' from + // disable reasons. It will be called when Lacros is not primary browser or + // features::kEnforceAshExtensionKeeplist is turned off. + void DeactivateKeeplistEnforcement(); + + // ExtensionRegistryObserver: + void OnExtensionReady(content::BrowserContext* browser_context, + const Extension* extension) override; + + // The |extension_prefs_|, |extension_service_| and |registry_| are passed + // from ctor and owned by the caller, and they are guaranteed to outlive this + // object. + raw_ptr<ExtensionPrefs> const extension_prefs_ = nullptr; // not owned + raw_ptr<ExtensionService> const extension_service_ = nullptr; // not owned + raw_ptr<ExtensionRegistry> const registry_ = nullptr; // not owned + + bool should_enforce_keeplist_ = false; + + base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver> + registry_observation_{this}; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_ASH_EXTENSION_KEEPLIST_MANAGER_H_
diff --git a/chrome/browser/extensions/extension_keeplist_ash.cc b/chrome/browser/extensions/extension_keeplist_ash.cc new file mode 100644 index 0000000..11fb755 --- /dev/null +++ b/chrome/browser/extensions/extension_keeplist_ash.cc
@@ -0,0 +1,61 @@ +// Copyright 2021 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/extensions/extension_keeplist_ash.h" + +#include <stddef.h> + +#include "base/containers/contains.h" +#include "base/no_destructor.h" +#include "base/strings/string_piece.h" +#include "chrome/browser/ash/file_manager/app_id.h" +#include "chrome/browser/ash/input_method/component_extension_ime_manager_delegate_impl.h" +#include "chrome/browser/ui/app_list/arc/arc_app_utils.h" +#include "chrome/common/buildflags.h" +#include "chrome/common/extensions/extension_constants.h" +#include "extensions/common/constants.h" + +namespace extensions { + +bool ExtensionRunsInAsh(const std::string& extension_id) { + static base::NoDestructor<std::set<base::StringPiece>> keep_list({ +#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION) + extension_misc::kHangoutServiceExtensionId, +#endif + extension_misc::kEspeakSpeechSynthesisExtensionId, + extension_misc::kGoogleSpeechSynthesisExtensionId, + extension_misc::kEnhancedNetworkTtsExtensionId, + extension_misc::kSelectToSpeakExtensionId, + extension_misc::kAccessibilityCommonExtensionId, + extension_misc::kChromeVoxExtensionId, + extension_misc::kSwitchAccessExtensionId, + extension_misc::kSigninProfileTestExtensionId, + extension_misc::kAssessmentAssistantExtensionId, + extension_misc::kQuickOfficeComponentExtensionId, + extension_misc::kQuickOfficeInternalExtensionId, + extension_misc::kQuickOfficeExtensionId, + extension_misc::kGuestModeTestExtensionId, + extension_misc::kCryptotokenExtensionId, + extension_misc::kKeyboardExtensionId, + extension_misc::kHelpAppExtensionId, extension_misc::kEchoExtensionId, + extension_misc::kGCSEExtensionId, extension_misc::kGnubbyV3ExtensionId, + file_manager::kImageLoaderExtensionId + }); + return base::Contains(*keep_list, extension_id) || + ash::input_method::ComponentExtensionIMEManagerDelegateImpl:: + IsIMEExtensionID(extension_id); +} + +bool ExtensionAppRunsInAsh(const std::string& app_id) { + static base::NoDestructor<std::set<base::StringPiece>> keep_list( + {file_manager::kAudioPlayerAppId, extension_misc::kFeedbackExtensionId, + extension_misc::kFilesManagerAppId, extension_misc::kGoogleKeepAppId, + extension_misc::kCalculatorAppId, extension_misc::kTextEditorAppId, + extension_misc::kInAppPaymentsSupportAppId, + extension_misc::kWallpaperManagerId, arc::kPlayStoreAppId, + extension_misc::kIdentityApiUiAppId, extension_misc::kGnubbyAppId}); + return base::Contains(*keep_list, app_id); +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/extension_keeplist_ash.h b/chrome/browser/extensions/extension_keeplist_ash.h new file mode 100644 index 0000000..9705bab --- /dev/null +++ b/chrome/browser/extensions/extension_keeplist_ash.h
@@ -0,0 +1,25 @@ +// Copyright 2021 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_EXTENSIONS_EXTENSION_KEEPLIST_ASH_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_KEEPLIST_ASH_H_ + +#include <string> + +namespace extensions { + +// Returns true if the extension is kept to run in Ash. A small list of +// 1st party extensions will continue to run in Ash either since they are +// used to support Chrome OS features such as text to speech or vox, +// or they are not compatible with Lacros yet. +bool ExtensionRunsInAsh(const std::string& extension_id); + +// Some extension apps will continue to run in Ash until they are either +// deprecated or migrated. This function returns whether a given app_id is on +// that keep list. This function must only be called from the UI thread. +bool ExtensionAppRunsInAsh(const std::string& app_id); + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_KEEPLIST_ASH_H_
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 3af18ca9..5501141 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -379,7 +379,12 @@ extension_registrar_(profile_, this), force_installed_tracker_(registry_, profile_), force_installed_metrics_(registry_, profile_, &force_installed_tracker_), - corrupted_extension_reinstaller_(profile_) { + corrupted_extension_reinstaller_(profile_) +#if BUILDFLAG(IS_CHROMEOS_ASH) + , + ash_keeplist_manager_(profile, extension_prefs, this) +#endif +{ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); TRACE_EVENT0("browser,startup", "ExtensionService::ExtensionService::ctor"); @@ -510,6 +515,10 @@ // Must be called after extensions are loaded. allowlist_.Init(); +#if BUILDFLAG(IS_CHROMEOS_ASH) + ash_keeplist_manager_.Init(); +#endif + // Check for updates especially for corrupted user installed extension from // the webstore. This will do nothing if an extension update check was // triggered before and is still running.
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index f8a8cf7e..863537c 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h
@@ -55,6 +55,10 @@ #error "Extensions must be enabled" #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/extensions/ash_extension_keeplist_manager.h" +#endif + class BlocklistedExtensionSyncServiceTest; class Profile; @@ -744,6 +748,10 @@ std::map<ExtensionPrefs::DelayReason, InstallGate*>; InstallGateRegistry install_delayer_registry_; +#if BUILDFLAG(IS_CHROMEOS_ASH) + AshExtensionKeeplistManager ash_keeplist_manager_; +#endif + FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, DestroyingProfileClearsExtensions); FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, SetUnsetBlocklistInPrefs);
diff --git a/chrome/browser/extensions/extension_sync_service.cc b/chrome/browser/extensions/extension_sync_service.cc index 6a76b2d..ca96123c 100644 --- a/chrome/browser/extensions/extension_sync_service.cc +++ b/chrome/browser/extensions/extension_sync_service.cc
@@ -83,7 +83,7 @@ return result; } -static_assert(extensions::disable_reason::DISABLE_REASON_LAST == (1LL << 21), +static_assert(extensions::disable_reason::DISABLE_REASON_LAST == (1LL << 22), "Please consider whether your new disable reason should be" " syncable, and if so update this bitmask accordingly!"); const int kKnownSyncableDisableReasons =
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 0566aea..29d63bb 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -170,11 +170,6 @@ "expiry_milestone": 96 }, { - "name": "app-service-external-protocol", - "owners": [ "chromeos-apps-foundation-team@google.com" ], - "expiry_milestone": 96 - }, - { "name": "apps-shortcut-default-off", "owners": [ "chrome-desktop-ui-sea@google.com", "cyan" ], "expiry_milestone": 99 @@ -365,7 +360,7 @@ { "name": "audio-url", "owners": [ "enshuo", "chromeos-audio@google.com" ], - "expiry_milestone": 98 + "expiry_milestone": 104 }, { "name": "auto-framing-override", @@ -3011,6 +3006,11 @@ "owners": [ "robsc", "napper", "jennyz", "thanhdng" ], "expiry_milestone": 98 }, + { + "name": "enforce-ash-extension-keeplist", + "owners": ["jennyz", "erikchen"], + "expiry_milestone": 130 + }, { "name": "enforce-system-aec", "owners": [ "peah" ],
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 28404f62..db2b1856 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3990,10 +3990,6 @@ const char kAppDiscoveryRemoteUrlSearchDescription[] = "Surface results from a URL in the app discovery service."; -const char kAppServiceExternalProtocolName[] = "App Service External Protocol"; -const char kAppServiceExternalProtocolDescription[] = - "Use the App Service to provide data for external protocol dialog."; - const char kArcAccountRestrictionsName[] = "Enable ARC account restrictions"; const char kArcAccountRestrictionsDescription[] = "ARC account restrictions feature for multi-profile account consistency"; @@ -4591,6 +4587,12 @@ "Enable the support of WireGuard VPN as a native VPN option. Requires a " "kernel version that support it."; +const char kEnforceAshExtensionKeeplistName[] = + "Enforce Ash extension keeplist"; +const char kEnforceAshExtensionKeeplistDescription[] = + "Enforce the Ash extension keeplist. Only the extensions and Chrome apps on" + " the keeplist are enabled in Ash."; + const char kESimPolicyName[] = "Enable ESim Policy"; const char kESimPolicyDescription[] = "Enable the support for policy controlled provisioning and configuration "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 118689d..012deca 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2290,9 +2290,6 @@ extern const char kAppDiscoveryRemoteUrlSearchName[]; extern const char kAppDiscoveryRemoteUrlSearchDescription[]; -extern const char kAppServiceExternalProtocolName[]; -extern const char kAppServiceExternalProtocolDescription[]; - extern const char kArcAccountRestrictionsName[]; extern const char kArcAccountRestrictionsDescription[]; @@ -2632,6 +2629,9 @@ extern const char kEnableWireGuardName[]; extern const char kEnableWireGuardDescription[]; +extern const char kEnforceAshExtensionKeeplistName[]; +extern const char kEnforceAshExtensionKeeplistDescription[]; + extern const char kExoGamepadVibrationName[]; extern const char kExoGamepadVibrationDescription[];
diff --git a/chrome/browser/lacros/browser_service_lacros.cc b/chrome/browser/lacros/browser_service_lacros.cc index f23ade8..b3afc4f 100644 --- a/chrome/browser/lacros/browser_service_lacros.cc +++ b/chrome/browser/lacros/browser_service_lacros.cc
@@ -9,6 +9,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/metrics/statistics_recorder.h" +#include "base/ranges/algorithm.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "chrome/browser/feedback/feedback_dialog_utils.h" @@ -17,6 +18,7 @@ #include "chrome/browser/lacros/system_logs/lacros_system_log_fetcher.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/sessions/session_restore.h" #include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -26,6 +28,7 @@ #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/profile_picker.h" +#include "chrome/browser/ui/startup/startup_tab.h" #include "chrome/browser/ui/views/tabs/tab_scrubber_chromeos.h" #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h" #include "chrome/common/channel_info.h" @@ -61,32 +64,21 @@ } } -// Finds any (Lacros) Browser which has a tab matching a given URL -// without ref (e.g. chrome://flags == chrome://flags/#). -// If such a tab exists, it gets activated, and true gets returned. -bool ActivateTabMatchingURLWithoutRef(Profile* profile, const GURL& url) { - BrowserList* browser_list = BrowserList::GetInstance(); - for (Browser* browser : *browser_list) { - if (browser->profile() == profile) { - TabStripModel* tab_strip = browser->tab_strip_model(); - for (int i = 0; i < tab_strip->count(); ++i) { - if (tab_strip->ContainsIndex(i) && !tab_strip->IsTabBlocked(i)) { - content::WebContents* content = tab_strip->GetWebContentsAt(i); - if (content->GetVisibleURL().EqualsIgnoringRef(url)) { - browser->window()->Activate(); - tab_strip->ActivateTabAt(i); - return true; - } - } - } - } - } - return false; -} - } // namespace +// A struct to keep the pending OpenUrl task. +struct BrowserServiceLacros::PendingOpenUrl { + Profile* profile; + GURL url; + OpenUrlCallback callback; +}; + BrowserServiceLacros::BrowserServiceLacros() { + session_restored_subscription_ = + SessionRestore::RegisterOnSessionRestoredCallback( + base::BindRepeating(&BrowserServiceLacros::OnSessionRestored, + weak_ptr_factory_.GetWeakPtr())); + auto* lacros_service = chromeos::LacrosService::Get(); const auto* init_params = lacros_service->init_params(); @@ -140,9 +132,9 @@ bool session_restore_available = false; if (should_trigger_session_restore) { - SessionService* sessionService = + SessionService* session_service = SessionServiceFactory::GetForProfileForSessionRestore(profile); - if (sessionService && sessionService->ShouldRestore(nullptr)) + if (session_service && session_service->ShouldRestore(nullptr)) session_restore_available = true; } @@ -270,29 +262,28 @@ Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy(); DCHECK(profile) << "No last used profile is found."; - // Try to re-activate an existing tab for a few specified URLs. - if (url.SchemeIs(content::kChromeUIScheme) && - (url.host() == chrome::kChromeUIFlagsHost || - url.host() == chrome::kChromeUIVersionHost || - url.host() == chrome::kChromeUIAboutHost || - url.host() == chrome::kChromeUIComponentsHost)) { - if (ActivateTabMatchingURLWithoutRef(profile, url)) { - std::move(callback).Run(); - return; - } + // If there is on-going session restoring task, wait for its completion. + if (SessionRestore::IsRestoring(profile)) { + pending_open_urls_.push_back( + PendingOpenUrl{profile, url, std::move(callback)}); + return; } - NavigateParams navigate_params( - profile, url, - ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | - ui::PAGE_TRANSITION_FROM_API)); - navigate_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; - // Ensure the browser window is showing when the URL is opened. This avoids - // the user being unaware a new tab with `url` has been opened (if the window - // was minimized for example). - navigate_params.window_action = NavigateParams::SHOW_WINDOW; - Navigate(&navigate_params); - std::move(callback).Run(); + // If there's no available browsers, but there's a session to be restored, + // trigger it, and wait for its completion. + SessionService* session_service = + SessionServiceFactory::GetForProfileForSessionRestore(profile); + if (!chrome::FindBrowserWithProfile(profile) && session_service && + session_service->ShouldRestore(nullptr)) { + pending_open_urls_.push_back( + PendingOpenUrl{profile, url, std::move(callback)}); + session_service->RestoreIfNecessary(StartupTabs(), + /* restore apps */ false); + return; + } + + // Otherwise, directly try to open the URL. + OpenUrlImpl(profile, url, std::move(callback)); } void BrowserServiceLacros::RestoreTab(RestoreTabCallback callback) { @@ -393,6 +384,55 @@ std::move(callback).Run(compressed_histograms); } +void BrowserServiceLacros::OnSessionRestored(Profile* profile, + int num_tabs_restored) { + if (pending_open_urls_.empty()) + return; + // Extract pending OpenUrl tasks for the restored |profile|. + std::vector<PendingOpenUrl> pendings; + for (auto& pending : pending_open_urls_) { + if (pending.profile == profile) { + pendings.push_back(std::move(pending)); + pending.profile = nullptr; // Mark as moved. + } + } + // Remove marked entries. + pending_open_urls_.erase(base::ranges::remove(pending_open_urls_, nullptr, + [](PendingOpenUrl& pending) { + return pending.profile; + }), + pending_open_urls_.end()); + + // Then, run for each. + for (auto& pending : pendings) + OpenUrlImpl(pending.profile, pending.url, std::move(pending.callback)); +} + +void BrowserServiceLacros::OpenUrlImpl(Profile* profile, + const GURL& url, + OpenUrlCallback callback) { + NavigateParams navigate_params( + profile, url, + ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | + ui::PAGE_TRANSITION_FROM_API)); + if (url.SchemeIs(content::kChromeUIScheme) && + (url.host() == chrome::kChromeUIFlagsHost || + url.host() == chrome::kChromeUIVersionHost || + url.host() == chrome::kChromeUIAboutHost || + url.host() == chrome::kChromeUIComponentsHost)) { + // Try to re-activate an existing tab for a few specified URLs. + navigate_params.disposition = WindowOpenDisposition::SWITCH_TO_TAB; + } else { + navigate_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + } + // Ensure the browser window is showing when the URL is opened. This avoids + // the user being unaware a new tab with `url` has been opened (if the window + // was minimized for example). + navigate_params.window_action = NavigateParams::SHOW_WINDOW; + Navigate(&navigate_params); + std::move(callback).Run(); +} + void BrowserServiceLacros::OnBrowserAdded(Browser* broser) { // Note: this happens only when ash-chrome is too old. // Please see the comment in the ctor for the detail.
diff --git a/chrome/browser/lacros/browser_service_lacros.h b/chrome/browser/lacros/browser_service_lacros.h index be26b25..34db564 100644 --- a/chrome/browser/lacros/browser_service_lacros.h +++ b/chrome/browser/lacros/browser_service_lacros.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "base/callback_list.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/browser_list_observer.h" #include "chromeos/crosapi/mojom/crosapi.mojom.h" @@ -15,6 +16,7 @@ #include "mojo/public/cpp/bindings/receiver.h" class GURL; +class Profile; class ScopedKeepAlive; // BrowserSerivce's Lacros implementation. @@ -50,6 +52,8 @@ void UpdateKeepAlive(bool enabled) override; private: + struct PendingOpenUrl; + void OnSystemInformationReady( GetFeedbackDataCallback callback, std::unique_ptr<system_logs::SystemLogsResponse> sys_info); @@ -57,13 +61,20 @@ void OnGetCompressedHistograms(GetHistogramsCallback callback, const std::string& compressed_histogram); + void OpenUrlImpl(Profile* profile, const GURL& url, OpenUrlCallback callback); + + // Called when a session is restored. + void OnSessionRestored(Profile* profile, int num_tabs_restored); + // BrowserListObserver: void OnBrowserAdded(Browser* browser) override; // Keeps the Lacros browser alive in the background. This is destroyed once // any browser window is opened. std::unique_ptr<ScopedKeepAlive> keep_alive_; + std::vector<PendingOpenUrl> pending_open_urls_; + base::CallbackListSubscription session_restored_subscription_; mojo::Receiver<crosapi::mojom::BrowserService> receiver_{this}; base::WeakPtrFactory<BrowserServiceLacros> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/media/extension_media_access_handler.cc b/chrome/browser/media/extension_media_access_handler.cc index 7690b6d..a0db8e5 100644 --- a/chrome/browser/media/extension_media_access_handler.cc +++ b/chrome/browser/media/extension_media_access_handler.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/media/webrtc/media_stream_device_permissions.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/pref_names.h" #include "content/public/browser/web_contents.h" #include "extensions/common/extension.h" @@ -29,7 +30,7 @@ // 8. Accessibility Common extension (used for Dictation) // Once http://crbug.com/292856 is fixed, remove this allowlist. bool IsMediaRequestAllowedForExtension(const extensions::Extension* extension) { - return extension->id() == "mppnpdlheglhdfmldimlhpnegondlapf" || + return extension->id() == extension_misc::kKeyboardExtensionId || extension->id() == "jokbpnebhdcladagohdnfgjcpejggllo" || extension->id() == "clffjmdilanldobdnedchkdbofoimcgb" || extension->id() == "nnckehldicaciogcbchegobnafnjkcne" ||
diff --git a/chrome/browser/metrics/extensions_metrics_provider.cc b/chrome/browser/metrics/extensions_metrics_provider.cc index 4410e77..7c108429 100644 --- a/chrome/browser/metrics/extensions_metrics_provider.cc +++ b/chrome/browser/metrics/extensions_metrics_provider.cc
@@ -121,8 +121,7 @@ content::BrowserContext* context) { ExtensionState state = NO_EXTENSIONS; for (extensions::ExtensionSet::const_iterator it = extensions.begin(); - it != extensions.end() && state < OFF_STORE; - ++it) { + it != extensions.end() && state < OFF_STORE; ++it) { // Combine the state of each extension, always favoring the higher state as // defined by the order of ExtensionState. state = std::max(state, IsOffStoreExtension(**it, verifier, context)); @@ -217,7 +216,7 @@ return ExtensionInstallProto::NO_BACKGROUND_SCRIPT; } -static_assert(extensions::disable_reason::DISABLE_REASON_LAST == (1LL << 21), +static_assert(extensions::disable_reason::DISABLE_REASON_LAST == (1LL << 22), "Adding a new disable reason? Be sure to include the new reason " "below, update the test to exercise it, and then adjust this " "value for DISABLE_REASON_LAST"); @@ -258,6 +257,10 @@ ExtensionInstallProto::REINSTALL}, {extensions::disable_reason::DISABLE_NOT_ALLOWLISTED, ExtensionInstallProto::NOT_ALLOWLISTED}, + // TODO(crbug.com/1268846): Uncomment after ExtensionInstallProto is + // updated in third party. + // {extensions::disable_reason::DISABLE_NOT_ASH_KEEPLISTED, + // ExtensionInstallProto::NOT_ASH_KEEPLISTED}, }; int disable_reasons = prefs->GetDisableReasons(id); @@ -365,8 +368,7 @@ DCHECK(metrics_state_manager_); } -ExtensionsMetricsProvider::~ExtensionsMetricsProvider() { -} +ExtensionsMetricsProvider::~ExtensionsMetricsProvider() = default; // static int ExtensionsMetricsProvider::HashExtension(const std::string& extension_id, @@ -469,8 +471,7 @@ std::set<int> buckets; for (extensions::ExtensionSet::const_iterator it = extensions->begin(); - it != extensions->end(); - ++it) { + it != extensions->end(); ++it) { buckets.insert(HashExtension((*it)->id(), client_key)); }
diff --git a/chrome/browser/new_tab_page/modules/task_module/BUILD.gn b/chrome/browser/new_tab_page/modules/task_module/BUILD.gn index d21ea57..fd065dc 100644 --- a/chrome/browser/new_tab_page/modules/task_module/BUILD.gn +++ b/chrome/browser/new_tab_page/modules/task_module/BUILD.gn
@@ -6,5 +6,6 @@ mojom("mojo_bindings") { sources = [ "task_module.mojom" ] + webui_module_path = "/" public_deps = [ "//url/mojom:url_mojom_gurl" ] }
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index c7d1ed61..7e74078 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -3164,8 +3164,8 @@ bool clipboard_changed_ = false; }; -// TODO(crbug.com/1268983): Fix flakiness on Linux and reenable. -#if defined(OS_LINUX) +// TODO(crbug.com/1121446): Fix flakiness. +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #define MAYBE_IndividualShiftRightArrowPresses \ DISABLED_IndividualShiftRightArrowPresses #else @@ -3219,8 +3219,8 @@ SendCopyCommandAndCheckCopyPasteClipboard("HEL"); } -// Flaky, http://crbug.com/1269104 -#if defined(OS_LINUX) +// Flaky, http://crbug.com/1121446 +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #define MAYBE_CombinedShiftRightArrowPresses \ DISABLED_CombinedShiftRightArrowPresses #else @@ -3254,7 +3254,7 @@ } // Flaky on Linux (https://crbug.com/1121446) -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #define MAYBE_CombinedShiftArrowPresses DISABLED_CombinedShiftArrowPresses #else #define MAYBE_CombinedShiftArrowPresses CombinedShiftArrowPresses
diff --git a/chrome/browser/resources/new_tab_page/BUILD.gn b/chrome/browser/resources/new_tab_page/BUILD.gn index 823c5a1..f188beda 100644 --- a/chrome/browser/resources/new_tab_page/BUILD.gn +++ b/chrome/browser/resources/new_tab_page/BUILD.gn
@@ -28,6 +28,9 @@ "js_module_root=" + rebase_path( "$root_gen_dir/mojom-webui/chrome/browser/new_tab_page/modules/drive", root_build_dir), + "js_module_root=" + rebase_path( + "$root_gen_dir/mojom-webui/chrome/browser/new_tab_page/modules/task_module", + root_build_dir), ] deps = [ @@ -355,12 +358,10 @@ generate_grd("build_task_module_mojo_grdp") { grd_prefix = grd_prefix out_grd = "$target_gen_dir/task_module_mojo_resources.grdp" - input_files = [ "task_module.mojom-lite.js" ] - input_files_base_dir = - rebase_path( - "$root_gen_dir/chrome/browser/new_tab_page/modules/task_module", + input_files = [ "task_module.mojom-webui.js" ] + input_files_base_dir = rebase_path( + "$root_gen_dir/mojom-webui/chrome/browser/new_tab_page/modules/task_module", root_build_dir) - resource_path_prefix = "modules/task_module" } generate_grd("build_chrome_cart_mojo_grdp") { @@ -522,7 +523,7 @@ "realbox/realbox.mojom-lite.js", "drive.mojom-webui.js", "photos.mojom-webui.js", - "modules/task_module/task_module.mojom-lite.js", + "task_module.mojom-webui.js", "foo.mojom-webui.js", "chrome_cart.mojom-webui.js", ]
diff --git a/chrome/browser/resources/new_tab_page/modules/recipes_v2/BUILD.gn b/chrome/browser/resources/new_tab_page/modules/recipes_v2/BUILD.gn index 9b14e88c..d385431cb 100644 --- a/chrome/browser/resources/new_tab_page/modules/recipes_v2/BUILD.gn +++ b/chrome/browser/resources/new_tab_page/modules/recipes_v2/BUILD.gn
@@ -9,6 +9,7 @@ deps = [ "..:module_descriptor", "..:module_header", + "//chrome/browser/new_tab_page/modules/task_module:mojo_bindings_webui_js", "//chrome/browser/resources/new_tab_page/modules/task_module:task_module_handler_proxy", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_auto_img",
diff --git a/chrome/browser/resources/new_tab_page/modules/recipes_v2/module.js b/chrome/browser/resources/new_tab_page/modules/recipes_v2/module.js index e18f9f1..26a2b10 100644 --- a/chrome/browser/resources/new_tab_page/modules/recipes_v2/module.js +++ b/chrome/browser/resources/new_tab_page/modules/recipes_v2/module.js
@@ -7,6 +7,7 @@ import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {I18nBehavior, loadTimeData} from '../../i18n_setup.js'; +import {TaskItem, TaskModuleType} from '../../task_module.mojom-webui.js'; import {ModuleDescriptorV2, ModuleHeight} from '../module_descriptor.js'; import {TaskModuleHandlerProxy} from '../task_module/task_module_handler_proxy.js'; @@ -26,7 +27,7 @@ static get properties() { return { - /** @type {!Array<!taskModule.mojom.TaskItem>} */ + /** @type {!Array<!TaskItem>} */ recipes: Array, }; } @@ -37,7 +38,7 @@ /** @return {!Promise<!HTMLElement>} */ async function createModule() { const {task} = await TaskModuleHandlerProxy.getHandler().getPrimaryTask( - taskModule.mojom.TaskModuleType.kRecipe); + TaskModuleType.kRecipe); const element = new RecipeModuleElement(); element.recipes = (task && task.taskItems) || []; return element;
diff --git a/chrome/browser/resources/new_tab_page/modules/task_module/BUILD.gn b/chrome/browser/resources/new_tab_page/modules/task_module/BUILD.gn index 1fa3765..12d79db 100644 --- a/chrome/browser/resources/new_tab_page/modules/task_module/BUILD.gn +++ b/chrome/browser/resources/new_tab_page/modules/task_module/BUILD.gn
@@ -11,6 +11,7 @@ "..:info_dialog", "..:module_descriptor", "../..:i18n_setup", + "//chrome/browser/new_tab_page/modules/task_module:mojo_bindings_webui_js", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_auto_img", "//ui/webui/resources/cr_elements/cr_grid", @@ -19,7 +20,9 @@ } js_library("task_module_handler_proxy") { - deps = [ "//chrome/browser/new_tab_page/modules/task_module:mojo_bindings_js_library_for_compile" ] + deps = [ + "//chrome/browser/new_tab_page/modules/task_module:mojo_bindings_webui_js", + ] } html_to_js("web_components") {
diff --git a/chrome/browser/resources/new_tab_page/modules/task_module/module.js b/chrome/browser/resources/new_tab_page/modules/task_module/module.js index cb515878..1897973 100644 --- a/chrome/browser/resources/new_tab_page/modules/task_module/module.js +++ b/chrome/browser/resources/new_tab_page/modules/task_module/module.js
@@ -10,6 +10,7 @@ import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {I18nBehavior, loadTimeData} from '../../i18n_setup.js'; +import {Task, TaskModuleType} from '../../task_module.mojom-webui.js'; import {InfoDialogElement} from '../info_dialog.js'; import {ModuleDescriptor} from '../module_descriptor.js'; @@ -34,13 +35,13 @@ static get properties() { return { - /** @type {!taskModule.mojom.TaskModuleType} */ + /** @type {!TaskModuleType} */ taskModuleType: { type: Number, observer: 'onTaskModuleTypeChange_', }, - /** @type {!taskModule.mojom.Task} */ + /** @type {!Task} */ task: Object, /** @private {string} */ @@ -75,9 +76,9 @@ */ computeTitle_() { switch (this.taskModuleType) { - case taskModule.mojom.TaskModuleType.kRecipe: + case TaskModuleType.kRecipe: return loadTimeData.getString('modulesRecipeTasksSentence'); - case taskModule.mojom.TaskModuleType.kShopping: + case TaskModuleType.kShopping: return this.task.title; default: return ''; @@ -90,9 +91,9 @@ */ computeDismissName_() { switch (this.taskModuleType) { - case taskModule.mojom.TaskModuleType.kRecipe: + case TaskModuleType.kRecipe: return loadTimeData.getString('modulesRecipeTasksLowerThese'); - case taskModule.mojom.TaskModuleType.kShopping: + case TaskModuleType.kShopping: return this.task.name; default: return ''; @@ -105,9 +106,9 @@ */ computeDisableName_() { switch (this.taskModuleType) { - case taskModule.mojom.TaskModuleType.kRecipe: + case TaskModuleType.kRecipe: return loadTimeData.getString('modulesRecipeTasksLower'); - case taskModule.mojom.TaskModuleType.kShopping: + case TaskModuleType.kShopping: return loadTimeData.getString('modulesShoppingTasksLower'); default: return ''; @@ -119,7 +120,7 @@ * @private */ isRecipe_() { - return this.taskModuleType === taskModule.mojom.TaskModuleType.kRecipe; + return this.taskModuleType === TaskModuleType.kRecipe; } /** @@ -127,16 +128,16 @@ * @private */ isShopping_() { - return this.taskModuleType === taskModule.mojom.TaskModuleType.kShopping; + return this.taskModuleType === TaskModuleType.kShopping; } /** @private */ onTaskModuleTypeChange_() { switch (this.taskModuleType) { - case taskModule.mojom.TaskModuleType.kRecipe: + case TaskModuleType.kRecipe: this.toggleAttribute('recipe'); break; - case taskModule.mojom.TaskModuleType.kShopping: + case TaskModuleType.kShopping: this.toggleAttribute('shopping'); break; } @@ -176,10 +177,10 @@ this.taskModuleType, this.task.name); let taskName = ''; switch (this.taskModuleType) { - case taskModule.mojom.TaskModuleType.kRecipe: + case TaskModuleType.kRecipe: taskName = loadTimeData.getString('modulesRecipeTasksSentence'); break; - case taskModule.mojom.TaskModuleType.kShopping: + case TaskModuleType.kShopping: taskName = this.task.name; break; } @@ -248,10 +249,10 @@ export const recipeTasksDescriptor = new ModuleDescriptor( /*id=*/ 'recipe_tasks', /*name=*/ loadTimeData.getString('modulesRecipeTasksSentence'), - createModule.bind(null, taskModule.mojom.TaskModuleType.kRecipe)); + createModule.bind(null, TaskModuleType.kRecipe)); /** @type {!ModuleDescriptor} */ export const shoppingTasksDescriptor = new ModuleDescriptor( /*id=*/ 'shopping_tasks', /*name=*/ loadTimeData.getString('modulesShoppingTasksSentence'), - createModule.bind(null, taskModule.mojom.TaskModuleType.kShopping)); + createModule.bind(null, TaskModuleType.kShopping));
diff --git a/chrome/browser/resources/new_tab_page/modules/task_module/task_module_handler_proxy.js b/chrome/browser/resources/new_tab_page/modules/task_module/task_module_handler_proxy.js index 1a5ba0f..587c51b 100644 --- a/chrome/browser/resources/new_tab_page/modules/task_module/task_module_handler_proxy.js +++ b/chrome/browser/resources/new_tab_page/modules/task_module/task_module_handler_proxy.js
@@ -2,27 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(crbug.com/1179821): Migrate to JS module Mojo bindings. -import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; -import 'chrome://resources/mojo/url/mojom/url.mojom-lite.js'; -import './task_module.mojom-lite.js'; +import {TaskModuleHandler, TaskModuleHandlerRemote} from '../../task_module.mojom-webui.js'; /** * @fileoverview This file provides a class that exposes the Mojo handler * interface used for retrieving a shopping task for a task module. */ -/** @type {?taskModule.mojom.TaskModuleHandlerRemote} */ +/** @type {?TaskModuleHandlerRemote} */ let handler = null; export class TaskModuleHandlerProxy { - /** @return {!taskModule.mojom.TaskModuleHandlerRemote} */ + /** @return {!TaskModuleHandlerRemote} */ static getHandler() { - return handler || - (handler = taskModule.mojom.TaskModuleHandler.getRemote()); + return handler || (handler = TaskModuleHandler.getRemote()); } - /** @param {!taskModule.mojom.TaskModuleHandlerRemote} newHandler */ + /** @param {!TaskModuleHandlerRemote} newHandler */ static setHandler(newHandler) { handler = newHandler; }
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html index a15e01dfa..b003163 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html +++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html
@@ -16,7 +16,7 @@ title="$i18n{moreActions}" id="moreNetworkDetail" on-click="onDotsClick_" - disabled="[[isDotsMenuButtonDisabled_(deviceState.*)]]"> + disabled="[[isDotsMenuButtonDisabled_(eSimNetworkState_, deviceState.*)]]"> </cr-icon-button> </template> <cr-lazy-render id="menu">
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html index 6527102..e4e146e4 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.html
@@ -193,14 +193,27 @@ label="$i18n{onScreenKeyboardLabel}" deep-link-focus-id$="[[Setting.kOnScreenKeyboard]]"> </settings-toggle-button> -<settings-toggle-button - id="enableDictation" - class="hr" - pref="{{prefs.settings.a11y.dictation}}" - label="$i18n{dictationLabel}" - sub-label="[[dictationSubtitle_]]" - deep-link-focus-id$="[[Setting.kDictation]]"> -</settings-toggle-button> +<template is="dom-if" if="[[isDictationCommandsFeatureEnabled_]]"> + <settings-toggle-button + id="enableDictation" + class="hr" + pref="{{prefs.settings.a11y.dictation}}" + label="$i18n{dictationLabel}" + sub-label="[[dictationSubtitle_]]" + deep-link-focus-id$="[[Setting.kDictation]]" + learn-more-url="[[dictationLearnMoreUrl_]]"> + </settings-toggle-button> +</template> +<template is="dom-if" if="[[!isDictationCommandsFeatureEnabled_]]"> + <settings-toggle-button + id="enableDictation" + class="hr" + pref="{{prefs.settings.a11y.dictation}}" + label="$i18n{dictationLabel}" + sub-label="[[dictationSubtitle_]]" + deep-link-focus-id$="[[Setting.kDictation]]"> + </settings-toggle-button> +</template> <template is="dom-if" if="[[areDictationLocalePrefsAllowed_]]"> <template is="dom-if" if="[[prefs.settings.a11y.dictation.value]]"> <div class="settings-box continuation indented">
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js index eac029d..6bbb493 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js
@@ -298,6 +298,25 @@ value: false, }, + /** @private */ + isDictationCommandsFeatureEnabled_: { + type: Boolean, + readOnly: true, + value() { + return loadTimeData.getBoolean('isDictationCommandsFeatureEnabled'); + } + }, + + /** + * TODO(crbug.com/1247299): This support page does not exist. Make sure to + * get the correct URL before launch. + * @private + */ + dictationLearnMoreUrl_: { + type: String, + value: 'https://support.google.com/chromebook?p=dictation', + }, + /** * |hasKeyboard_|, |hasMouse_|, |hasPointingStick_|, and |hasTouchpad_| * start undefined so observers don't trigger until they have been
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/multipart_uploader_unittest.cc b/chrome/browser/safe_browsing/cloud_content_scanning/multipart_uploader_unittest.cc index 085ba1b..0d7070c2 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/multipart_uploader_unittest.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/multipart_uploader_unittest.cc
@@ -326,7 +326,13 @@ INSTANTIATE_TEST_CASE_P(, MultipartUploadDataPipeRequestTest, testing::Bool()); -TEST_P(MultipartUploadDataPipeRequestTest, Retries) { +// Disabled due to flakiness on Windows https://crbug.com/1286638 +#if BUILDFLAG(IS_WIN) +#define MAYBE_Retries DISABLED_Retries +#else +#define MAYBE_Retries Retries +#endif +TEST_P(MultipartUploadDataPipeRequestTest, MAYBE_Retries) { std::string expected_body = "--boundary\r\n" "Content-Type: application/octet-stream\r\n"
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc index ff48539d4..eda98aa 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc +++ b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc
@@ -72,13 +72,13 @@ const app_list::AppListSyncableService::SyncItem* sync_item, const apps::AppUpdate& app_update) : ChromeAppListItem(profile, app_update.AppId()), - app_type_(app_update.AppType()) { + app_type_(apps::ConvertMojomAppTypToAppType(app_update.AppType())) { OnAppUpdate(app_update, /*in_constructor=*/true); if (sync_item && sync_item->item_ordinal.IsValid()) { InitFromSync(sync_item); } else { // Handle the case that the app under construction is a remote app. - if (app_type_ == apps::mojom::AppType::kRemote) { + if (app_type_ == apps::AppType::kRemote) { ash::RemoteAppsManager* remote_manager = ash::RemoteAppsManagerFactory::GetForProfile(profile); if (remote_manager->ShouldAddToFront(app_update.AppId())) @@ -97,7 +97,7 @@ } // Crostini apps and the Terminal System App start in the crostini folder. - if (app_type_ == apps::mojom::AppType::kCrostini || + if (app_type_ == apps::AppType::kCrostini || id() == crostini::kCrostiniTerminalSystemAppId) { DCHECK(folder_id().empty()); SetChromeFolderId(ash::kCrostiniFolderId); @@ -211,8 +211,7 @@ // TODO(crbug.com/826982): drop the if, and call MaybeDismissAppList // unconditionally? - if (app_type_ == apps::mojom::AppType::kArc || - app_type_ == apps::mojom::AppType::kRemote) { + if (app_type_ == apps::AppType::kArc || app_type_ == apps::AppType::kRemote) { MaybeDismissAppList(); } } @@ -231,15 +230,15 @@ void AppServiceAppItem::CallLoadIcon(bool allow_placeholder_icon) { if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { apps::AppServiceProxyFactory::GetForProfile(profile())->LoadIcon( - apps::ConvertMojomAppTypToAppType(app_type_), id(), - apps::IconType::kStandard, + app_type_, id(), apps::IconType::kStandard, ash::SharedAppListConfig::instance().default_grid_icon_dimension(), allow_placeholder_icon, base::BindOnce(&AppServiceAppItem::OnLoadIcon, weak_ptr_factory_.GetWeakPtr())); } else { apps::AppServiceProxyFactory::GetForProfile(profile())->LoadIcon( - app_type_, id(), apps::mojom::IconType::kStandard, + apps::ConvertAppTypeToMojomAppType(app_type_), id(), + apps::mojom::IconType::kStandard, ash::SharedAppListConfig::instance().default_grid_icon_dimension(), allow_placeholder_icon, apps::MojomIconValueToIconValueCallback(base::BindOnce(
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_item.h b/chrome/browser/ui/app_list/app_service/app_service_app_item.h index b8c28c04..b384f9ff 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_app_item.h +++ b/chrome/browser/ui/app_list/app_service/app_service_app_item.h
@@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" #include "chrome/browser/ui/app_list/chrome_app_list_item.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/app_update.h" #include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/types.mojom-forward.h" @@ -49,7 +50,7 @@ void CallLoadIcon(bool allow_placeholder_icon); void OnLoadIcon(apps::IconValuePtr icon_value); - const apps::mojom::AppType app_type_; + const apps::AppType app_type_; bool is_platform_app_ = false; std::unique_ptr<app_list::AppContextMenu> context_menu_;
diff --git a/chrome/browser/ui/app_list/app_service/app_service_context_menu.cc b/chrome/browser/ui/app_list/app_service/app_service_context_menu.cc index d3006dd..ba7b5df 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_context_menu.cc +++ b/chrome/browser/ui/app_list/app_service/app_service_context_menu.cc
@@ -133,11 +133,11 @@ proxy_->AppRegistryCache().ForOneApp( app_id, [this](const apps::AppUpdate& update) { app_type_ = apps_util::IsInstalled(update.Readiness()) - ? update.AppType() - : apps::mojom::AppType::kUnknown; + ? apps::ConvertMojomAppTypToAppType(update.AppType()) + : apps::AppType::kUnknown; }); - if (app_type_ == apps::mojom::AppType::kStandaloneBrowserChromeApp) { + if (app_type_ == apps::AppType::kStandaloneBrowserChromeApp) { standalone_browser_extension_menu_ = std::make_unique<StandaloneBrowserExtensionAppContextMenu>( app_id, StandaloneBrowserExtensionAppContextMenu::Source::kAppList); @@ -147,14 +147,14 @@ AppServiceContextMenu::~AppServiceContextMenu() = default; void AppServiceContextMenu::GetMenuModel(GetMenuModelCallback callback) { - if (app_type_ == apps::mojom::AppType::kUnknown) { + if (app_type_ == apps::AppType::kUnknown) { std::move(callback).Run(nullptr); return; } // StandaloneBrowserExtension handles its own context menus. Forward to that // class. - if (app_type_ == apps::mojom::AppType::kStandaloneBrowserChromeApp) { + if (app_type_ == apps::AppType::kStandaloneBrowserChromeApp) { standalone_browser_extension_menu_->GetMenuModel(std::move(callback)); return; } @@ -210,7 +210,7 @@ case ash::APP_CONTEXT_MENU_NEW_INCOGNITO_WINDOW: { const bool is_incognito = command_id == ash::APP_CONTEXT_MENU_NEW_INCOGNITO_WINDOW; - if (app_type_ == apps::mojom::AppType::kStandaloneBrowser) { + if (app_type_ == apps::AppType::kStandaloneBrowser) { crosapi::BrowserManager::Get()->NewWindow( is_incognito, /*should_trigger_session_restore=*/false); } else { @@ -250,7 +250,7 @@ default: if (command_id >= ash::USE_LAUNCH_TYPE_COMMAND_START && command_id < ash::USE_LAUNCH_TYPE_COMMAND_END) { - if (app_type_ == apps::mojom::AppType::kWeb && + if (app_type_ == apps::AppType::kWeb && command_id == ash::USE_LAUNCH_TYPE_TABBED_WINDOW) { proxy_->SetWindowMode(app_id(), apps::mojom::WindowMode::kTabbedWindow); @@ -286,7 +286,7 @@ } switch (app_type_) { - case apps::mojom::AppType::kWeb: + case apps::AppType::kWeb: if (command_id >= ash::USE_LAUNCH_TYPE_COMMAND_START && command_id < ash::USE_LAUNCH_TYPE_COMMAND_END) { auto user_window_mode = apps::mojom::WindowMode::kUnknown; @@ -300,7 +300,7 @@ } return AppContextMenu::IsCommandIdChecked(command_id); - case apps::mojom::AppType::kChromeApp: + case apps::AppType::kChromeApp: if (command_id >= ash::USE_LAUNCH_TYPE_COMMAND_START && command_id < ash::USE_LAUNCH_TYPE_COMMAND_END) { return static_cast<int>( @@ -313,15 +313,15 @@ } return AppContextMenu::IsCommandIdChecked(command_id); - case apps::mojom::AppType::kArc: + case apps::AppType::kArc: [[fallthrough]]; - case apps::mojom::AppType::kCrostini: + case apps::AppType::kCrostini: [[fallthrough]]; - case apps::mojom::AppType::kBuiltIn: + case apps::AppType::kBuiltIn: [[fallthrough]]; - case apps::mojom::AppType::kPluginVm: + case apps::AppType::kPluginVm: [[fallthrough]]; - case apps::mojom::AppType::kBorealis: + case apps::AppType::kBorealis: [[fallthrough]]; default: return AppContextMenu::IsCommandIdChecked(command_id); @@ -357,7 +357,7 @@ // The special rule to ensure that FilesManager's first menu item is "New // window". const bool build_extension_menu_before_default = - (app_type_ == apps::mojom::AppType::kChromeApp && + (app_type_ == apps::AppType::kChromeApp && app_id() == extension_misc::kFilesManagerAppId); if (build_extension_menu_before_default) @@ -366,8 +366,8 @@ // Create default items for non-Remote apps. if (app_id() != extension_misc::kChromeAppId && app_id() != extension_misc::kLacrosAppId && - app_type_ != apps::mojom::AppType::kUnknown && - app_type_ != apps::mojom::AppType::kRemote) { + app_type_ != apps::AppType::kUnknown && + app_type_ != apps::AppType::kRemote) { app_list::AppContextMenu::BuildMenu(menu_model.get()); } @@ -433,7 +433,7 @@ } void AppServiceContextMenu::ShowAppInfo() { - if (app_type_ == apps::mojom::AppType::kArc) { + if (app_type_ == apps::AppType::kArc) { chrome::ShowAppManagementPage( profile(), app_id(), AppManagementEntryPoint::kAppListContextMenuAppInfoArc); @@ -445,7 +445,7 @@ void AppServiceContextMenu::SetLaunchType(int command_id) { switch (app_type_) { - case apps::mojom::AppType::kWeb: { + case apps::AppType::kWeb: { // Web apps can only toggle between kWindow and kBrowser. apps::mojom::WindowMode user_window_mode = ConvertUseLaunchTypeCommandToWindowMode(command_id); @@ -453,7 +453,7 @@ proxy_->SetWindowMode(app_id(), user_window_mode); return; } - case apps::mojom::AppType::kChromeApp: { + case apps::AppType::kChromeApp: { // Hosted apps can only toggle between LAUNCH_TYPE_WINDOW and // LAUNCH_TYPE_REGULAR. extensions::LaunchType launch_type = @@ -464,15 +464,15 @@ controller()->SetExtensionLaunchType(profile(), app_id(), launch_type); return; } - case apps::mojom::AppType::kArc: + case apps::AppType::kArc: [[fallthrough]]; - case apps::mojom::AppType::kCrostini: + case apps::AppType::kCrostini: [[fallthrough]]; - case apps::mojom::AppType::kBuiltIn: + case apps::AppType::kBuiltIn: [[fallthrough]]; - case apps::mojom::AppType::kPluginVm: + case apps::AppType::kPluginVm: [[fallthrough]]; - case apps::mojom::AppType::kBorealis: + case apps::AppType::kBorealis: [[fallthrough]]; default: return;
diff --git a/chrome/browser/ui/app_list/app_service/app_service_context_menu.h b/chrome/browser/ui/app_list/app_service/app_service_context_menu.h index 80c0819..ea40169 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_context_menu.h +++ b/chrome/browser/ui/app_list/app_service/app_service_context_menu.h
@@ -13,6 +13,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" #include "chrome/browser/apps/app_service/app_shortcut_item.h" #include "chrome/browser/ui/app_list/app_context_menu.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/mojom/types.mojom.h" class AppContextMenuDelegate; @@ -55,7 +56,7 @@ void ExecutePublisherContextMenuCommand(int command_id); - apps::mojom::AppType app_type_ = apps::mojom::AppType::kUnknown; + apps::AppType app_type_ = apps::AppType::kUnknown; // The SimpleMenuModel used to hold the submenu items. std::unique_ptr<ui::SimpleMenuModel> submenu_;
diff --git a/chrome/browser/ui/app_list/search/files/drive_search_browsertest.cc b/chrome/browser/ui/app_list/search/files/drive_search_browsertest.cc index ed094f8..840183a5 100644 --- a/chrome/browser/ui/app_list/search/files/drive_search_browsertest.cc +++ b/chrome/browser/ui/app_list/search/files/drive_search_browsertest.cc
@@ -85,4 +85,30 @@ EXPECT_EQ(base::UTF16ToASCII(results[0]->title()), "my_folder"); } +// Test that files are ordered based on modification time. +IN_PROC_BROWSER_TEST_F(AppListDriveSearchBrowserTest, DriveFileResultOrdering) { + base::ScopedAllowBlockingForTesting allow_blocking; + + drive::DriveIntegrationService* drive_service = + drive::DriveIntegrationServiceFactory::FindForProfile(GetProfile()); + ASSERT_TRUE(drive_service->IsMounted()); + base::FilePath mount_path = drive_service->GetMountPointPath(); + + base::FilePath older = mount_path.Append("ranking_older.gdoc"); + base::FilePath newer = mount_path.Append("ranking_newer.gdoc"); + base::Time now = base::Time::Now(); + base::Time then = now - base::Seconds(1); + ASSERT_TRUE(base::WriteFile(older, "content")); + ASSERT_TRUE(base::WriteFile(newer, "content")); + ASSERT_TRUE(base::TouchFile(older, then, then)); + ASSERT_TRUE(base::TouchFile(newer, now, now)); + + SearchAndWaitForProviders("ranking", {ResultType::kDriveSearch}); + + const auto results = PublishedResultsForProvider(ResultType::kDriveSearch); + ASSERT_EQ(results.size(), 2u); + EXPECT_EQ(base::UTF16ToASCII(results[0]->title()), "ranking_newer"); + EXPECT_EQ(base::UTF16ToASCII(results[1]->title()), "ranking_older"); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/files/drive_search_provider.cc b/chrome/browser/ui/app_list/search/files/drive_search_provider.cc index 3848e92..4c87a713 100644 --- a/chrome/browser/ui/app_list/search/files/drive_search_provider.cc +++ b/chrome/browser/ui/app_list/search/files/drive_search_provider.cc
@@ -70,12 +70,10 @@ last_query_ = query; last_tokenized_query_.emplace(query, TokenizedString::Mode::kWords); - // New scores will be assigned for sorting purposes so use the default - // SortField. The SortDirection does nothing in this case. drive_service_->SearchDriveByFileName( base::UTF16ToUTF8(query), kMaxResults, - drivefs::mojom::QueryParameters::SortField::kNone, - drivefs::mojom::QueryParameters::SortDirection::kAscending, + drivefs::mojom::QueryParameters::SortField::kLastModified, + drivefs::mojom::QueryParameters::SortDirection::kDescending, drivefs::mojom::QueryParameters::QuerySource::kLocalOnly, base::BindOnce(&DriveSearchProvider::SetSearchResults, weak_factory_.GetWeakPtr())); @@ -92,15 +90,20 @@ } SearchProvider::Results results; - for (const auto& item : items) { + for (size_t i = 0; i < items.size(); ++i) { + const auto& item = items[i]; + // Results are returned in descending order of modification time. Set the + // relevance in (0,1] based on that. + double relevance = 1.0 - static_cast<double>(i) / items.size(); if (item->metadata->type == drivefs::mojom::FileMetadata::Type::kDirectory) { const auto type = item->metadata->shared ? FileResult::Type::kSharedDirectory : FileResult::Type::kDirectory; - results.emplace_back(MakeResult(item->path, type)); + results.emplace_back(MakeResult(item->path, relevance, type)); } else { - results.emplace_back(MakeResult(item->path, FileResult::Type::kFile)); + results.emplace_back( + MakeResult(item->path, relevance, FileResult::Type::kFile)); } } @@ -112,6 +115,7 @@ std::unique_ptr<FileResult> DriveSearchProvider::MakeResult( const base::FilePath& path, + double relevance, FileResult::Type type) { // Strip leading separators so that the path can be reparented. // TODO(crbug.com/1154513): Remove this step once the drive backend returns @@ -127,8 +131,6 @@ const base::FilePath& reparented_path = drive_service_->GetMountPointPath().Append(relative_path.value()); - const double relevance = - FileResult::CalculateRelevance(last_tokenized_query_, reparented_path); return std::make_unique<FileResult>( kDriveSearchSchema, reparented_path, ash::AppListSearchResultType::kDriveSearch,
diff --git a/chrome/browser/ui/app_list/search/files/drive_search_provider.h b/chrome/browser/ui/app_list/search/files/drive_search_provider.h index 9ca6bb52..364629a6 100644 --- a/chrome/browser/ui/app_list/search/files/drive_search_provider.h +++ b/chrome/browser/ui/app_list/search/files/drive_search_provider.h
@@ -42,6 +42,7 @@ void SetSearchResults(drive::FileError error, std::vector<drivefs::mojom::QueryItemPtr> paths); std::unique_ptr<FileResult> MakeResult(const base::FilePath& path, + double relevance, FileResult::Type type); base::TimeTicks query_start_time_;
diff --git a/chrome/browser/ui/app_list/search/omnibox_provider.cc b/chrome/browser/ui/app_list/search/omnibox_provider.cc index d2a147c..60cd255 100644 --- a/chrome/browser/ui/app_list/search/omnibox_provider.cc +++ b/chrome/browser/ui/app_list/search/omnibox_provider.cc
@@ -92,9 +92,11 @@ } void OmniboxProvider::StartZeroState() { - // TODO(crbug.com/1258415): Remove zero-state once productivity launcher - // launched. - Start(std::u16string()); + // Do not perform zero-state queries in the productivity launcher, because + // Omnibox is not shown in zero-state. + if (!app_list_features::IsCategoricalSearchEnabled()) { + Start(std::u16string()); + } } ash::AppListSearchResultType OmniboxProvider::ResultType() const {
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.cc index a592639..605f534 100644 --- a/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.cc +++ b/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.cc
@@ -92,7 +92,7 @@ // For Crostini app_id with the prefix "crostini:", set app_type as Unknown // to skip the ArcAppShelfId valid. App type can't be set as Crostini, // because the pin item should not be added for it. - app_type_ = apps::mojom::AppType::kUnknown; + app_type_ = apps::AppType::kUnknown; return; } @@ -100,9 +100,10 @@ const arc::ArcAppShelfId arc_shelf_id = arc::ArcAppShelfId::FromString(item->id.app_id); DCHECK(arc_shelf_id.valid()); - app_type_ = apps::AppServiceProxyFactory::GetForProfile(controller->profile()) - ->AppRegistryCache() - .GetAppType(arc_shelf_id.app_id()); + app_type_ = apps::ConvertMojomAppTypToAppType( + apps::AppServiceProxyFactory::GetForProfile(controller->profile()) + ->AppRegistryCache() + .GetAppType(arc_shelf_id.app_id())); } AppServiceShelfContextMenu::~AppServiceShelfContextMenu() = default; @@ -130,9 +131,9 @@ break; case ash::MENU_NEW_WINDOW: - if (app_type_ == apps::mojom::AppType::kCrostini) { + if (app_type_ == apps::AppType::kCrostini) { ShelfContextMenu::ExecuteCommand(ash::MENU_OPEN_NEW, event_flags); - } else if (app_type_ == apps::mojom::AppType::kStandaloneBrowser) { + } else if (app_type_ == apps::AppType::kStandaloneBrowser) { crosapi::BrowserManager::Get()->NewWindow( /*incongnito=*/false, /*should_trigger_session_restore=*/false); } else { @@ -145,7 +146,7 @@ break; case ash::MENU_NEW_INCOGNITO_WINDOW: - if (app_type_ == apps::mojom::AppType::kStandaloneBrowser) { + if (app_type_ == apps::AppType::kStandaloneBrowser) { crosapi::BrowserManager::Get()->NewWindow( /*incognito=*/true, /*should_trigger_session_restore=*/false); } else { @@ -223,8 +224,8 @@ bool AppServiceShelfContextMenu::IsCommandIdChecked(int command_id) const { switch (app_type_) { - case apps::mojom::AppType::kWeb: - case apps::mojom::AppType::kSystemWeb: { + case apps::AppType::kWeb: + case apps::AppType::kSystemWeb: { if ((command_id >= ash::LAUNCH_TYPE_PINNED_TAB && command_id <= ash::LAUNCH_TYPE_WINDOW) || command_id == ash::LAUNCH_TYPE_TABBED_WINDOW) { @@ -241,7 +242,7 @@ } return ShelfContextMenu::IsCommandIdChecked(command_id); } - case apps::mojom::AppType::kChromeApp: + case apps::AppType::kChromeApp: if (command_id >= ash::LAUNCH_TYPE_PINNED_TAB && command_id <= ash::LAUNCH_TYPE_WINDOW) { return GetExtensionLaunchType() == @@ -252,15 +253,15 @@ return (extension_menu_items_ && extension_menu_items_->IsCommandIdChecked(command_id)); } - case apps::mojom::AppType::kArc: + case apps::AppType::kArc: [[fallthrough]]; - case apps::mojom::AppType::kCrostini: + case apps::AppType::kCrostini: [[fallthrough]]; - case apps::mojom::AppType::kBuiltIn: + case apps::AppType::kBuiltIn: [[fallthrough]]; - case apps::mojom::AppType::kPluginVm: + case apps::AppType::kPluginVm: [[fallthrough]]; - case apps::mojom::AppType::kBorealis: + case apps::AppType::kBorealis: [[fallthrough]]; default: return ShelfContextMenu::IsCommandIdChecked(command_id); @@ -295,7 +296,7 @@ // The special rule to ensure that FilesManager's first menu item is "New // window". const bool build_extension_menu_before_pin = - (app_type_ == apps::mojom::AppType::kChromeApp && + (app_type_ == apps::AppType::kChromeApp && item().id.app_id == extension_misc::kFilesManagerAppId); if (build_extension_menu_before_pin) @@ -335,15 +336,15 @@ } } - if (app_type_ == apps::mojom::AppType::kArc) { + if (app_type_ == apps::AppType::kArc) { BuildArcAppShortcutsMenu(std::move(menu_items), std::move(menu_model), std::move(callback), shortcut_index); return; } - if (app_type_ == apps::mojom::AppType::kWeb || - app_type_ == apps::mojom::AppType::kSystemWeb || - app_type_ == apps::mojom::AppType::kCrostini) { + if (app_type_ == apps::AppType::kWeb || + app_type_ == apps::AppType::kSystemWeb || + app_type_ == apps::AppType::kCrostini) { BuildAppShortcutsMenu(std::move(menu_items), std::move(menu_model), std::move(callback), shortcut_index); return; @@ -451,7 +452,7 @@ } void AppServiceShelfContextMenu::ShowAppInfo() { - if (app_type_ == apps::mojom::AppType::kArc) { + if (app_type_ == apps::AppType::kArc) { chrome::ShowAppManagementPage( controller()->profile(), item().id.app_id, AppManagementEntryPoint::kShelfContextMenuAppInfoArc); @@ -468,8 +469,8 @@ void AppServiceShelfContextMenu::SetLaunchType(int command_id) { switch (app_type_) { - case apps::mojom::AppType::kWeb: - case apps::mojom::AppType::kSystemWeb: { + case apps::AppType::kWeb: + case apps::AppType::kSystemWeb: { // Web apps can only toggle between kWindow, kTabbed and kBrowser. apps::mojom::WindowMode user_window_mode = ConvertLaunchTypeCommandToWindowMode(command_id); @@ -479,18 +480,18 @@ } return; } - case apps::mojom::AppType::kChromeApp: + case apps::AppType::kChromeApp: SetExtensionLaunchType(command_id); return; - case apps::mojom::AppType::kArc: + case apps::AppType::kArc: [[fallthrough]]; - case apps::mojom::AppType::kCrostini: + case apps::AppType::kCrostini: [[fallthrough]]; - case apps::mojom::AppType::kBuiltIn: + case apps::AppType::kBuiltIn: [[fallthrough]]; - case apps::mojom::AppType::kPluginVm: + case apps::AppType::kPluginVm: [[fallthrough]]; - case apps::mojom::AppType::kBorealis: + case apps::AppType::kBorealis: [[fallthrough]]; default: return; @@ -542,7 +543,7 @@ bool AppServiceShelfContextMenu::ShouldAddPinMenu() { switch (app_type_) { - case apps::mojom::AppType::kArc: { + case apps::AppType::kArc: { const arc::ArcAppShelfId& arc_shelf_id = arc::ArcAppShelfId::FromString(item().id.app_id); DCHECK(arc_shelf_id.valid()); @@ -555,8 +556,8 @@ return true; return false; } - case apps::mojom::AppType::kPluginVm: - case apps::mojom::AppType::kBuiltIn: { + case apps::AppType::kPluginVm: + case apps::AppType::kBuiltIn: { bool show_in_launcher = false; apps::AppServiceProxyFactory::GetForProfile(controller()->profile()) ->AppRegistryCache() @@ -567,24 +568,25 @@ }); return show_in_launcher; } - case apps::mojom::AppType::kCrostini: - case apps::mojom::AppType::kBorealis: - case apps::mojom::AppType::kChromeApp: - case apps::mojom::AppType::kWeb: - case apps::mojom::AppType::kSystemWeb: - case apps::mojom::AppType::kStandaloneBrowserChromeApp: + case apps::AppType::kCrostini: + case apps::AppType::kBorealis: + case apps::AppType::kChromeApp: + case apps::AppType::kWeb: + case apps::AppType::kSystemWeb: + case apps::AppType::kStandaloneBrowserChromeApp: return true; - case apps::mojom::AppType::kStandaloneBrowser: + case apps::AppType::kStandaloneBrowser: // Lacros behaves like the Chrome browser icon and cannot be unpinned. return false; - case apps::mojom::AppType::kUnknown: + case apps::AppType::kUnknown: // Type kUnknown is used for "unregistered" Crostini apps, which do not // have a .desktop file and can only be closed, not pinned. return false; - case apps::mojom::AppType::kMacOs: - case apps::mojom::AppType::kRemote: - case apps::mojom::AppType::kExtension: - NOTREACHED() << "Type " << app_type_ << " should not appear in shelf."; + case apps::AppType::kMacOs: + case apps::AppType::kRemote: + case apps::AppType::kExtension: + NOTREACHED() << "Type " << (int)app_type_ + << " should not appear in shelf."; return false; } }
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.h b/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.h index 60b6735..c2e4ba3 100644 --- a/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.h +++ b/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/apps/app_service/app_shortcut_item.h" #include "chrome/browser/ui/ash/shelf/shelf_context_menu.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "extensions/common/constants.h" @@ -78,7 +79,7 @@ void ExecutePublisherContextMenuCommand(int command_id); - apps::mojom::AppType app_type_; + apps::AppType app_type_; // The SimpleMenuModel used to hold the submenu items. std::unique_ptr<ui::SimpleMenuModel> submenu_;
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc index 8ff4157..545ae90 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/ash/file_manager/prefs_migration_uma.h" #include "chrome/browser/ash/login/demo_mode/demo_session.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/extensions/extension_keeplist_ash.h" #include "chrome/browser/prefs/pref_service_syncable_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/sync_service_factory.h" @@ -222,7 +223,8 @@ for (const auto& policy_dict_entry : policy_apps->GetList()) { const std::string* policy_entry = policy_dict_entry.is_dict() - ? policy_dict_entry.FindStringKey(ChromeShelfPrefs::kPinnedAppsPrefAppIDKey) + ? policy_dict_entry.FindStringKey( + ChromeShelfPrefs::kPinnedAppsPrefAppIDKey) : nullptr; if (!policy_entry) { @@ -656,7 +658,7 @@ } bool ChromeShelfPrefs::IsAshKeepListApp(const std::string& app_id) { - return apps::ExtensionAppRunsInAsh(app_id); + return extensions::ExtensionAppRunsInAsh(app_id); } std::string ChromeShelfPrefs::GetShelfId(const std::string& sync_id) { @@ -670,7 +672,7 @@ // If this app is on the ash keep list, immediately return it. Even if there's // a lacros chrome app that matches this id, we still want to use the ash // version. - if (apps::ExtensionAppRunsInAsh(sync_id)) + if (extensions::ExtensionAppRunsInAsh(sync_id)) return sync_id; std::string transformed_app_id = kLacrosChromeAppPrefix + sync_id;
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index 7cdef5f1..0fd3649 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc
@@ -734,15 +734,17 @@ if (params->disposition == WindowOpenDisposition::SWITCH_TO_TAB) { // Close orphaned NTP (and the like) with no history when the user // switches away from them. - if (params->source_contents->GetController().CanGoBack() || - (params->source_contents->GetLastCommittedURL().spec() != - chrome::kChromeUINewTabURL && - params->source_contents->GetLastCommittedURL().spec() != - url::kAboutBlankURL)) { - // Blur location bar before state save in ActivateTabAt() below. - params->source_contents->Focus(); - } else { - should_close_this_tab = true; + if (params->source_contents) { + if (params->source_contents->GetController().CanGoBack() || + (params->source_contents->GetLastCommittedURL().spec() != + chrome::kChromeUINewTabURL && + params->source_contents->GetLastCommittedURL().spec() != + url::kAboutBlankURL)) { + // Blur location bar before state save in ActivateTabAt() below. + params->source_contents->Focus(); + } else { + should_close_this_tab = true; + } } } params->browser->tab_strip_model()->ActivateTabAt(singleton_index,
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_interactive_browsertest.cc index 37a96f2..39d0d5a 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_interactive_browsertest.cc
@@ -75,8 +75,8 @@ }; // https://crbug.com/1087875: Flaky on Linux and Mac. -// TODO(crbug.com/1278361): Flaky on lacros. -#if defined(OS_MAC) || defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +// TODO(crbug.com/1278361): Flaky on Chrome OS. +#if defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS) #define MAYBE_NotifyFullscreenAcquired DISABLED_NotifyFullscreenAcquired #else #define MAYBE_NotifyFullscreenAcquired NotifyFullscreenAcquired
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc index a31c010..47731cb2 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
@@ -1177,9 +1177,17 @@ helper_.CheckLaunchIconNotShown(); } +// TODO(crbug.com/1286616): Flaky on macOS. +#if defined(OS_MAC) +#define MAYBE_WebAppIntegration_InstCrtShctWindowedSiteC_InListWinSiteC_NavSiteC_InstIconNotShown_LaunchIconShown \ + DISABLED_WebAppIntegration_InstCrtShctWindowedSiteC_InListWinSiteC_NavSiteC_InstIconNotShown_LaunchIconShown +#else +#define MAYBE_WebAppIntegration_InstCrtShctWindowedSiteC_InListWinSiteC_NavSiteC_InstIconNotShown_LaunchIconShown \ + WebAppIntegration_InstCrtShctWindowedSiteC_InListWinSiteC_NavSiteC_InstIconNotShown_LaunchIconShown +#endif IN_PROC_BROWSER_TEST_F( WebAppIntegrationBrowserTest, - WebAppIntegration_InstCrtShctWindowedSiteC_InListWinSiteC_NavSiteC_InstIconNotShown_LaunchIconShown) { + MAYBE_WebAppIntegration_InstCrtShctWindowedSiteC_InListWinSiteC_NavSiteC_InstIconNotShown_LaunchIconShown) { // Test contents are generated by script. Please do not modify! // See `chrome/test/webapps/README.md` for more info. // Sheriffs: Disabling this test is supported. @@ -1332,9 +1340,17 @@ helper_.CheckWindowDisplayMinimal(); } +// TODO(crbug.com/1286616): Flaky on macOS. +#if defined(OS_MAC) +#define MAYBE_WebAppIntegration_InstOmniboxSiteB_NavSiteB_LaunchIconShown \ + DISABLED_WebAppIntegration_InstOmniboxSiteB_NavSiteB_LaunchIconShown +#else +#define MAYBE_WebAppIntegration_InstOmniboxSiteB_NavSiteB_LaunchIconShown \ + WebAppIntegration_InstOmniboxSiteB_NavSiteB_LaunchIconShown +#endif IN_PROC_BROWSER_TEST_F( WebAppIntegrationBrowserTest, - WebAppIntegration_InstOmniboxSiteB_NavSiteB_LaunchIconShown) { + MAYBE_WebAppIntegration_InstOmniboxSiteB_NavSiteB_LaunchIconShown) { // Test contents are generated by script. Please do not modify! // See `chrome/test/webapps/README.md` for more info. // Sheriffs: Disabling this test is supported. @@ -1406,9 +1422,17 @@ helper_.CheckWindowDisplayMinimal(); } +// TODO(crbug.com/1286616): Flaky on macOS. +#if defined(OS_MAC) +#define MAYBE_WebAppIntegration_InstMenuOptionSiteB_NavSiteB_LaunchIconShown \ + DISABLED_WebAppIntegration_InstMenuOptionSiteB_NavSiteB_LaunchIconShown +#else +#define MAYBE_WebAppIntegration_InstMenuOptionSiteB_NavSiteB_LaunchIconShown \ + WebAppIntegration_InstMenuOptionSiteB_NavSiteB_LaunchIconShown +#endif IN_PROC_BROWSER_TEST_F( WebAppIntegrationBrowserTest, - WebAppIntegration_InstMenuOptionSiteB_NavSiteB_LaunchIconShown) { + MAYBE_WebAppIntegration_InstMenuOptionSiteB_NavSiteB_LaunchIconShown) { // Test contents are generated by script. Please do not modify! // See `chrome/test/webapps/README.md` for more info. // Sheriffs: Disabling this test is supported.
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index 3af50a1..43b5affb1 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -72,6 +72,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/services/app_service/public/mojom/types.mojom-shared.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "components/sessions/core/tab_restore_service.h" #include "components/webapps/browser/installable/installable_metrics.h" @@ -80,6 +81,7 @@ #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" +#include "extensions/common/constants.h" #include "net/base/filename_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -1374,6 +1376,7 @@ web_app_info->title = u"A Shortcut App"; const AppId app_id = InstallWebApp(std::move(web_app_info)); + base::HistogramTester tester; NavigateToURLAndWait(browser(), app_url); content::WebContents* tab_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -1392,6 +1395,12 @@ DisplayMode::kStandalone); EXPECT_EQ(provider->registrar().GetAppEffectiveDisplayMode(app_id), DisplayMode::kMinimalUi); + EXPECT_FALSE(provider->registrar().GetAppLastLaunchTime(app_id).is_null()); + tester.ExpectUniqueSample( + "Extensions.BookmarkAppLaunchContainer", + apps::mojom::LaunchContainer::kLaunchContainerWindow, 1); + tester.ExpectUniqueSample("Extensions.BookmarkAppLaunchSource", + extensions::AppLaunchSource::kSourceReparenting, 1); } // Tests that the manifest name of the current installable site is used in the
diff --git a/chrome/browser/ui/web_applications/web_app_launch_process.cc b/chrome/browser/ui/web_applications/web_app_launch_process.cc index 744f7b6f..1b5b78c 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_process.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_process.cc
@@ -119,7 +119,9 @@ MaybeEnqueueWebLaunchParams(launch_url, is_file_handling, web_contents, navigate_result.did_navigate); - RecordMetrics(launch_url, web_contents); + RecordMetrics(params_.app_id, params_.container, + apps::GetAppLaunchSource(params_.launch_source), launch_url, + web_contents); return web_contents; } @@ -355,31 +357,4 @@ } } -void WebAppLaunchProcess::RecordMetrics(const GURL& launch_url, - content::WebContents* web_contents) { - // TODO(crbug.com/1014328): Populate WebApp metrics instead of Extensions. - if (params_.container == apps::mojom::LaunchContainer::kLaunchContainerTab) { - UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", - extensions::LAUNCH_TYPE_REGULAR, 100); - } else if (params_.container == - apps::mojom::LaunchContainer::kLaunchContainerWindow) { - RecordAppWindowLaunch(&profile_, params_.app_id); - } - UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkAppLaunchSource", - apps::GetAppLaunchSource(params_.launch_source)); - UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkAppLaunchContainer", - params_.container); - - // Record the launch time in the site engagement service. A recent web - // app launch will provide an engagement boost to the origin. - site_engagement::SiteEngagementService::Get(&profile_) - ->SetLastShortcutLaunchTime(web_contents, launch_url); - provider_.sync_bridge().SetAppLastLaunchTime(params_.app_id, - base::Time::Now()); - // Refresh the app banner added to homescreen event. The user may have - // cleared their browsing data since installing the app, which removes the - // event and will potentially permit a banner to be shown for the site. - RecordAppBanner(web_contents, launch_url); -} - } // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_launch_process.h b/chrome/browser/ui/web_applications/web_app_launch_process.h index 23953c4..ade53e3 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_process.h +++ b/chrome/browser/ui/web_applications/web_app_launch_process.h
@@ -67,8 +67,6 @@ bool is_file_handling, content::WebContents* web_contents, bool is_navigating); - void RecordMetrics(const GURL& launch_url, - content::WebContents* web_contents); Profile& profile_; WebAppProvider& provider_;
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.cc b/chrome/browser/ui/web_applications/web_app_launch_utils.cc index 80ffba6d..9d1c2af7 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_utils.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
@@ -32,13 +32,16 @@ #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "chrome/browser/web_applications/web_app_tab_helper.h" #include "chrome/common/chrome_features.h" #include "components/omnibox/browser/location_bar_model.h" +#include "components/site_engagement/content/site_engagement_service.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" +#include "extensions/common/constants.h" #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" #include "url/gurl.h" @@ -165,6 +168,11 @@ PrunePreScopeNavigationHistory(*app_scope, contents); } + auto launch_url = contents->GetLastCommittedURL(); + RecordMetrics(app_id, apps::mojom::LaunchContainer::kLaunchContainerWindow, + extensions::AppLaunchSource::kSourceReparenting, launch_url, + contents); + if (registrar.IsTabbedWindowModeEnabled(app_id)) { for (Browser* browser : *BrowserList::GetInstance()) { if (AppBrowserController::IsForWebApp(browser, app_id)) @@ -337,4 +345,35 @@ UMA_HISTOGRAM_ENUMERATION("Launch.WebAppDisplayMode", display); } +void RecordMetrics(const AppId& app_id, + apps::mojom::LaunchContainer container, + extensions::AppLaunchSource launch_source, + const GURL& launch_url, + content::WebContents* web_contents) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + // TODO(crbug.com/1014328): Populate WebApp metrics instead of Extensions. + if (container == apps::mojom::LaunchContainer::kLaunchContainerTab) { + UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", + extensions::LAUNCH_TYPE_REGULAR, 100); + } else if (container == + apps::mojom::LaunchContainer::kLaunchContainerWindow) { + RecordAppWindowLaunch(profile, app_id); + } + UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkAppLaunchSource", + launch_source); + UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkAppLaunchContainer", container); + + // Record the launch time in the site engagement service. A recent web + // app launch will provide an engagement boost to the origin. + site_engagement::SiteEngagementService::Get(profile) + ->SetLastShortcutLaunchTime(web_contents, launch_url); + WebAppProvider::GetForWebApps(profile)->sync_bridge().SetAppLastLaunchTime( + app_id, base::Time::Now()); + // Refresh the app banner added to homescreen event. The user may have + // cleared their browsing data since installing the app, which removes the + // event and will potentially permit a banner to be shown for the site. + RecordAppBanner(web_contents, launch_url); +} + } // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.h b/chrome/browser/ui/web_applications/web_app_launch_utils.h index 072de26d..067bed7 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_utils.h +++ b/chrome/browser/ui/web_applications/web_app_launch_utils.h
@@ -9,6 +9,7 @@ #include <string> #include "chrome/browser/web_applications/web_app_id.h" +#include "extensions/common/constants.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/rect.h" @@ -74,6 +75,12 @@ void RecordAppWindowLaunch(Profile* profile, const std::string& app_id); +void RecordMetrics(const AppId& app_id, + apps::mojom::LaunchContainer container, + extensions::AppLaunchSource launch_source, + const GURL& launch_url, + content::WebContents* web_contents); + } // namespace web_app #endif // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_UTILS_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc index ce65688..3d05897 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
@@ -772,6 +772,10 @@ html_source->AddBoolean("areDictationLocalePrefsAllowed", AreDictationLocalePrefsAllowed()); + html_source->AddBoolean( + "isDictationCommandsFeatureEnabled", + ::features::IsExperimentalAccessibilityDictationCommandsEnabled()); + ::settings::AddCaptionSubpageStrings(html_source); }
diff --git a/chrome/browser/web_applications/app_service/web_apps_publisher_host_browsertest.cc b/chrome/browser/web_applications/app_service/web_apps_publisher_host_browsertest.cc index ad4bc80a..f2d2064 100644 --- a/chrome/browser/web_applications/app_service/web_apps_publisher_host_browsertest.cc +++ b/chrome/browser/web_applications/app_service/web_apps_publisher_host_browsertest.cc
@@ -155,12 +155,14 @@ embedded_test_server()->GetURL("/banners/manifest_test_page.html")); mock_app_publisher.Wait(); - // OnWebAppInstalled() and OnWebAppInstalledWithOsHooks() lead to updates. - EXPECT_EQ(mock_app_publisher.get_deltas().size(), 4U); - EXPECT_EQ(mock_app_publisher.get_deltas().back()->app_id, app_id); - EXPECT_EQ(mock_app_publisher.get_deltas().back()->readiness, + // OnWebAppInstalled(), OnWebAppInstalledWithOsHooks() and + // OnWebAppLastLaunchTimeChanged() lead to updates. + const auto& app_deltas = mock_app_publisher.get_deltas(); + EXPECT_EQ(app_deltas.size(), 5U); + EXPECT_EQ(app_deltas[app_deltas.size() - 2]->app_id, app_id); + EXPECT_EQ(app_deltas[app_deltas.size() - 2]->readiness, apps::mojom::Readiness::kReady); - EXPECT_EQ(mock_app_publisher.get_deltas().back()->icon_key->icon_effects, + EXPECT_EQ(app_deltas[app_deltas.size() - 2]->icon_key->icon_effects, IconEffects::kRoundCorners | IconEffects::kCrOsStandardIcon); {
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 6669820..49c8972 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1641923982-b421bd00007351f3d3d347fadbedd0d211eadc8c.profdata +chrome-linux-main-1641967191-1ea8dc629e0d4a1b00e280201af3c405581ba281.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 6f16506..ef4007df 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1641923982-2abdb6ca3337708a0d5c9e656a9973060620435c.profdata +chrome-mac-main-1641967191-75479048b6e19d32c44ae387dc488978f31aa240.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 246acbaa..d76729e 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1641934172-6d2a8f926ae50b5d54a7c3db91c1a2f86b151807.profdata +chrome-win32-main-1641956375-6c067d4877898f938d5e3e15d74214dfc895d0cc.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index f27f8bbe..723272f 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1641934172-034527ed13da2733050871a9ff6ab3c9f05b3e2c.profdata +chrome-win64-main-1641967191-f51a8c7594830305ce4e57fc76a6be89f28bfbd9.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 8c8188e..ed285c3 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -77,8 +77,6 @@ #if !defined(OS_ANDROID) // App Service related flags. See components/services/app_service/README.md. -const base::Feature kAppServiceExternalProtocol{ - "AppServiceExternalProtocol", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kAppServiceLoadIconWithoutMojom{ "AppServiceLoadIconWithoutMojom", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kAppServiceExtension{"AppServiceExtension",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index fdab413..b08e1a7 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -75,8 +75,6 @@ #if !defined(OS_ANDROID) COMPONENT_EXPORT(CHROME_FEATURES) -extern const base::Feature kAppServiceExternalProtocol; -COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kAppServiceLoadIconWithoutMojom; COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kAppServiceExtension;
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 508f4ca..fded91c 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc
@@ -34,6 +34,7 @@ const char kIdentityApiUiAppId[] = "ahjaciijnoiaklcomgnblndopackapon"; const char kTextEditorAppId[] = "mmfbcljfglbokpmkimbfghdkjmjhdgbg"; const char kInAppPaymentsSupportAppId[] = "nmmhkkegccagdldgiimedpiccmgmieda"; +const char kKeyboardExtensionId[] = "mppnpdlheglhdfmldimlhpnegondlapf"; const char* const kBuiltInFirstPartyExtensionIds[] = { kCalculatorAppId, @@ -75,6 +76,9 @@ #if defined(OS_CHROMEOS) const char kAssessmentAssistantExtensionId[] = "gndmhdcefbhlchkhipcnnbkcmicncehk"; +const char kGnubbyAppId[] = "beknehfpfkghjoafdifaflglpjkojoco"; +const char kGnubbyV3ExtensionId[] = "lfboplenmmjcmpbkeemecobbadnmpfhi"; +const char kGCSEExtensionId[] = "cfmgaohenjcikllcgjpepfadgbflcjof"; #endif #if BUILDFLAG(IS_CHROMEOS_ASH) const char kAccessibilityCommonExtensionId[] = @@ -115,7 +119,13 @@ const char kGoogleSpeechSynthesisExtensionId[] = "gjjabgpgjpampikjhjpfhneeoapjbjaf"; const char kWallpaperManagerId[] = "obklkkbkpaoaejdabbfldmcfplpdgolj"; +const char kHelpAppExtensionId[] = "honijodknafkokifofgiaalefdiedpko"; +const char kEchoExtensionId[] = "kddnkjkcjddckihglkfcickdhbmaodcn"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION) +// The extension id of the Hangout Service extnsion. +const char kHangoutServiceExtensionId[] = "nkeimhogjdpnpccoofpliimaahmaaome"; +#endif const char kAppStateNotInstalled[] = "not_installed"; const char kAppStateInstalled[] = "installed";
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index 81e5b43..fff878bd 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h
@@ -9,6 +9,7 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "chrome/common/buildflags.h" #include "url/gurl.h" namespace extension_urls { @@ -67,6 +68,9 @@ // The extension id of the in-app payments support application. extern const char kInAppPaymentsSupportAppId[]; +// The extension id of virtual keyboard extension. +extern const char kKeyboardExtensionId[]; + // A list of all the first party extension IDs, last entry is null. extern const char* const kBuiltInFirstPartyExtensionIds[]; @@ -159,6 +163,12 @@ #if defined(OS_CHROMEOS) // The extension id of the Assessment Assistant extension. extern const char kAssessmentAssistantExtensionId[]; +// The extension id of the Gnubby chrome app. +extern const char kGnubbyAppId[]; +// The extension id of the new v3 Gnubby extension. +extern const char kGnubbyV3ExtensionId[]; +// The extension id of the GCSE. +extern const char kGCSEExtensionId[]; #endif #if BUILDFLAG(IS_CHROMEOS_ASH) // The extension id of the Accessibility Common extension. @@ -219,6 +229,13 @@ extern const char kEspeakSpeechSynthesisExtensionId[]; // The extension id of the wallpaper manager application. extern const char kWallpaperManagerId[]; +// The extension id of official HelpApp extension. +extern const char kHelpAppExtensionId[]; +extern const char kEchoExtensionId[]; +#endif +#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION) +// The extension id of the Hangout Service extnsion. +extern const char kHangoutServiceExtensionId[]; #endif // What causes an extension to be installed? Used in histograms, so don't
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index fbe1e3a..709ab90 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -5034,8 +5034,6 @@ if (!is_android) { sources += [ - "../browser/apps/app_discovery_service/remote_url_search/remote_url_client_unittest.cc", - "../browser/apps/app_discovery_service/remote_url_search/remote_url_index_unittest.cc", "../browser/browsing_data/chrome_browsing_data_lifetime_manager_unittest.cc", "../browser/component_updater/soda_component_installer_unittest.cc", "../browser/component_updater/soda_language_pack_component_installer_unittest.cc", @@ -6385,7 +6383,6 @@ if (!is_android) { sources += [ - "../browser/apps/app_discovery_service/app_discovery_service_unittest.cc", "../browser/apps/app_service/app_icon/app_icon_factory_unittest.cc", "../browser/apps/app_service/app_service_proxy_unittest.cc", "../browser/apps/app_service/app_service_test.cc", @@ -6547,6 +6544,10 @@ "../browser/ui/window_sizer/window_sizer_unittest.cc", ] sources += [ + "../browser/apps/app_discovery_service/app_discovery_service_unittest.cc", + "../browser/apps/app_discovery_service/recommended_arc_app_fetcher_unittest.cc", + "../browser/apps/app_discovery_service/remote_url_search/remote_url_client_unittest.cc", + "../browser/apps/app_discovery_service/remote_url_search/remote_url_index_unittest.cc", "../browser/apps/app_service/file_utils_unittest.cc", "../browser/apps/app_service/intent_util_unittest.cc", "../browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc",
diff --git a/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_bar.html b/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_bar.html index 2d86018f..d962720 100644 --- a/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_bar.html +++ b/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_bar.html
@@ -2,11 +2,11 @@ <meta http-equiv="Accept-CH" content="dpr=(https://bar.com/),sec-ch-dpr=(https://bar.com/),device-memory=(https://bar.com/),sec-ch-device-memory=(https://bar.com/),viewport-width=(https://bar.com/),sec-ch-viewport-width=(https://bar.com/),rtt=(https://bar.com/),downlink=(https://bar.com/),ect=(https://bar.com/),sec-ch-ua-arch=(https://bar.com/),sec-ch-ua-platform-version=(https://bar.com/),sec-ch-ua-model=(https://bar.com/),sec-ch-ua-full-version=(https://bar.com/),sec-ch-prefers-color-scheme=(https://bar.com/),sec-ch-ua-bitness=(https://bar.com/),sec-ch-viewport-height=(https://bar.com/),sec-ch-ua-full-version-list=(https://bar.com/)"> <link rel="icon" href="data:;base64,="> <body> - <img src="non-existing-image.jpg"></img> + <img src="test_img.jpg"></img> <img src="https://foo.com/non-existing-image.jpg"></img> <iframe src="https://foo.com/non-existing-iframe.html"></iframe> <script type="text/javascript"> - document.body.innerHTML += '<img src="non-existing-image2.jpg"></img>'; + document.body.innerHTML += '<img src="test_img.jpg?foo"></img>'; document.body.innerHTML += '<img src="https://bar.com/non-existing-image.jpg"></img>'; document.body.innerHTML += '<iframe src="https://bar.com/non-existing-iframe.html"></iframe>'; </script>
diff --git a/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_foo.html b/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_foo.html index e1e62c2e..92b57fc2 100644 --- a/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_foo.html +++ b/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_foo.html
@@ -2,11 +2,11 @@ <meta http-equiv="Accept-CH" content="dpr=(https://foo.com/),sec-ch-dpr=(https://foo.com/),device-memory=(https://foo.com/),sec-ch-device-memory=(https://foo.com/),viewport-width=(https://foo.com/),sec-ch-viewport-width=(https://foo.com/),rtt=(https://foo.com/),downlink=(https://foo.com/),ect=(https://foo.com/),sec-ch-ua-arch=(https://foo.com/),sec-ch-ua-platform-version=(https://foo.com/),sec-ch-ua-model=(https://foo.com/),sec-ch-ua-full-version=(https://foo.com/),sec-ch-prefers-color-scheme=(https://foo.com/),sec-ch-ua-bitness=(https://foo.com/),sec-ch-viewport-height=(https://foo.com/),sec-ch-ua-full-version-list=(https://foo.com/)"> <link rel="icon" href="data:;base64,="> <body> - <img src="non-existing-image.jpg"></img> + <img src="test_img.jpg"></img> <img src="https://foo.com/non-existing-image.jpg"></img> <iframe src="https://foo.com/non-existing-iframe.html"></iframe> <script type="text/javascript"> - document.body.innerHTML += '<img src="non-existing-image2.jpg"></img>'; + document.body.innerHTML += '<img src="test_img.jpg?foo"></img>'; document.body.innerHTML += '<img src="https://bar.com/non-existing-image.jpg"></img>'; document.body.innerHTML += '<iframe src="https://bar.com/non-existing-iframe.html"></iframe>'; </script>
diff --git a/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_merge.html b/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_merge.html index 2d86018f..d962720 100644 --- a/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_merge.html +++ b/chrome/test/data/client_hints/http_equiv_accept_ch_delegation_merge.html
@@ -2,11 +2,11 @@ <meta http-equiv="Accept-CH" content="dpr=(https://bar.com/),sec-ch-dpr=(https://bar.com/),device-memory=(https://bar.com/),sec-ch-device-memory=(https://bar.com/),viewport-width=(https://bar.com/),sec-ch-viewport-width=(https://bar.com/),rtt=(https://bar.com/),downlink=(https://bar.com/),ect=(https://bar.com/),sec-ch-ua-arch=(https://bar.com/),sec-ch-ua-platform-version=(https://bar.com/),sec-ch-ua-model=(https://bar.com/),sec-ch-ua-full-version=(https://bar.com/),sec-ch-prefers-color-scheme=(https://bar.com/),sec-ch-ua-bitness=(https://bar.com/),sec-ch-viewport-height=(https://bar.com/),sec-ch-ua-full-version-list=(https://bar.com/)"> <link rel="icon" href="data:;base64,="> <body> - <img src="non-existing-image.jpg"></img> + <img src="test_img.jpg"></img> <img src="https://foo.com/non-existing-image.jpg"></img> <iframe src="https://foo.com/non-existing-iframe.html"></iframe> <script type="text/javascript"> - document.body.innerHTML += '<img src="non-existing-image2.jpg"></img>'; + document.body.innerHTML += '<img src="test_img.jpg?foo"></img>'; document.body.innerHTML += '<img src="https://bar.com/non-existing-image.jpg"></img>'; document.body.innerHTML += '<iframe src="https://bar.com/non-existing-iframe.html"></iframe>'; </script>
diff --git a/chrome/test/data/client_hints/meta_name_accept_ch_delegation_bar.html b/chrome/test/data/client_hints/meta_name_accept_ch_delegation_bar.html index ffad773..9886b9c0 100644 --- a/chrome/test/data/client_hints/meta_name_accept_ch_delegation_bar.html +++ b/chrome/test/data/client_hints/meta_name_accept_ch_delegation_bar.html
@@ -2,11 +2,11 @@ <meta name="Accept-CH" content="dpr=(https://bar.com/),sec-ch-dpr=(https://bar.com/),device-memory=(https://bar.com/),sec-ch-device-memory=(https://bar.com/),viewport-width=(https://bar.com/),sec-ch-viewport-width=(https://bar.com/),rtt=(https://bar.com/),downlink=(https://bar.com/),ect=(https://bar.com/),sec-ch-ua-arch=(https://bar.com/),sec-ch-ua-platform-version=(https://bar.com/),sec-ch-ua-model=(https://bar.com/),sec-ch-ua-full-version=(https://bar.com/),sec-ch-prefers-color-scheme=(https://bar.com/),sec-ch-ua-bitness=(https://bar.com/),sec-ch-viewport-height=(https://bar.com/),sec-ch-ua-full-version-list=(https://bar.com/)"> <link rel="icon" href="data:;base64,="> <body> - <img src="non-existing-image.jpg"></img> + <img src="test_img.jpg"></img> <img src="https://foo.com/non-existing-image.jpg"></img> <iframe src="https://foo.com/non-existing-iframe.html"></iframe> <script type="text/javascript"> - document.body.innerHTML += '<img src="non-existing-image2.jpg"></img>'; + document.body.innerHTML += '<img src="test_img.jpg?foo"></img>'; document.body.innerHTML += '<img src="https://bar.com/non-existing-image.jpg"></img>'; document.body.innerHTML += '<iframe src="https://bar.com/non-existing-iframe.html"></iframe>'; </script>
diff --git a/chrome/test/data/client_hints/meta_name_accept_ch_delegation_foo.html b/chrome/test/data/client_hints/meta_name_accept_ch_delegation_foo.html index 943df4a..dc5ef5d 100644 --- a/chrome/test/data/client_hints/meta_name_accept_ch_delegation_foo.html +++ b/chrome/test/data/client_hints/meta_name_accept_ch_delegation_foo.html
@@ -2,11 +2,11 @@ <meta name="Accept-CH" content="dpr=(https://foo.com/),sec-ch-dpr=(https://foo.com/),device-memory=(https://foo.com/),sec-ch-device-memory=(https://foo.com/),viewport-width=(https://foo.com/),sec-ch-viewport-width=(https://foo.com/),rtt=(https://foo.com/),downlink=(https://foo.com/),ect=(https://foo.com/),sec-ch-ua-arch=(https://foo.com/),sec-ch-ua-platform-version=(https://foo.com/),sec-ch-ua-model=(https://foo.com/),sec-ch-ua-full-version=(https://foo.com/),sec-ch-prefers-color-scheme=(https://foo.com/),sec-ch-ua-bitness=(https://foo.com/),sec-ch-viewport-height=(https://foo.com/),sec-ch-ua-full-version-list=(https://foo.com/)"> <link rel="icon" href="data:;base64,="> <body> - <img src="non-existing-image.jpg"></img> + <img src="test_img.jpg"></img> <img src="https://foo.com/non-existing-image.jpg"></img> <iframe src="https://foo.com/non-existing-iframe.html"></iframe> <script type="text/javascript"> - document.body.innerHTML += '<img src="non-existing-image2.jpg"></img>'; + document.body.innerHTML += '<img src="test_img.jpg?foo"></img>'; document.body.innerHTML += '<img src="https://bar.com/non-existing-image.jpg"></img>'; document.body.innerHTML += '<iframe src="https://bar.com/non-existing-iframe.html"></iframe>'; </script>
diff --git a/chrome/test/data/client_hints/meta_name_accept_ch_delegation_merge.html b/chrome/test/data/client_hints/meta_name_accept_ch_delegation_merge.html index ffad773..9886b9c0 100644 --- a/chrome/test/data/client_hints/meta_name_accept_ch_delegation_merge.html +++ b/chrome/test/data/client_hints/meta_name_accept_ch_delegation_merge.html
@@ -2,11 +2,11 @@ <meta name="Accept-CH" content="dpr=(https://bar.com/),sec-ch-dpr=(https://bar.com/),device-memory=(https://bar.com/),sec-ch-device-memory=(https://bar.com/),viewport-width=(https://bar.com/),sec-ch-viewport-width=(https://bar.com/),rtt=(https://bar.com/),downlink=(https://bar.com/),ect=(https://bar.com/),sec-ch-ua-arch=(https://bar.com/),sec-ch-ua-platform-version=(https://bar.com/),sec-ch-ua-model=(https://bar.com/),sec-ch-ua-full-version=(https://bar.com/),sec-ch-prefers-color-scheme=(https://bar.com/),sec-ch-ua-bitness=(https://bar.com/),sec-ch-viewport-height=(https://bar.com/),sec-ch-ua-full-version-list=(https://bar.com/)"> <link rel="icon" href="data:;base64,="> <body> - <img src="non-existing-image.jpg"></img> + <img src="test_img.jpg"></img> <img src="https://foo.com/non-existing-image.jpg"></img> <iframe src="https://foo.com/non-existing-iframe.html"></iframe> <script type="text/javascript"> - document.body.innerHTML += '<img src="non-existing-image2.jpg"></img>'; + document.body.innerHTML += '<img src="test_img.jpg?foo"></img>'; document.body.innerHTML += '<img src="https://bar.com/non-existing-image.jpg"></img>'; document.body.innerHTML += '<iframe src="https://bar.com/non-existing-iframe.html"></iframe>'; </script>
diff --git a/chrome/test/data/client_hints/test_img.jpg b/chrome/test/data/client_hints/test_img.jpg new file mode 100644 index 0000000..3679a331 --- /dev/null +++ b/chrome/test/data/client_hints/test_img.jpg Binary files differ
diff --git a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_dialog_test.js b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_dialog_test.js index 17cd176d..aed7d1c2 100644 --- a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_dialog_test.js +++ b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_dialog_test.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {DialogState, FirmwareUpdateDialogElement} from 'chrome://accessory-update/firmware_update_dialog.js'; +import {FirmwareUpdateDialogElement} from 'chrome://accessory-update/firmware_update_dialog.js'; import {FirmwareUpdate, UpdatePriority} from 'chrome://accessory-update/firmware_update_types.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js index 0b8b49b8..d316713 100644 --- a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js +++ b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js
@@ -8,8 +8,7 @@ import {FakeUpdateController} from 'chrome://accessory-update/fake_update_controller.js'; import {FakeUpdateProvider} from 'chrome://accessory-update/fake_update_provider.js'; import {FirmwareUpdateAppElement} from 'chrome://accessory-update/firmware_update_app.js'; -import {DialogState} from 'chrome://accessory-update/firmware_update_dialog.js'; -import {FirmwareUpdate, UpdateProviderInterface} from 'chrome://accessory-update/firmware_update_types.js'; +import {FirmwareUpdate, UpdateProviderInterface, UpdateState} from 'chrome://accessory-update/firmware_update_types.js'; import {getUpdateProvider, setUpdateControllerForTesting, setUpdateProviderForTesting} from 'chrome://accessory-update/mojo_interface_provider.js'; import {mojoString16ToString} from 'chrome://accessory-update/mojo_utils.js'; import {UpdateCardElement} from 'chrome://accessory-update/update_card.js'; @@ -69,9 +68,10 @@ dialogElement.querySelector('#nextButton')); } - /** @return {!DialogState} */ - function getDialogState() { - return page.shadowRoot.querySelector('firmware-update-dialog').dialogState; + /** @return {!UpdateState} */ + function getUpdateState() { + return page.shadowRoot.querySelector('firmware-update-dialog') + .installationProgress.state; } /** @return {!FirmwareUpdate} */ @@ -117,7 +117,7 @@ // Process |OnStateChanged| and |OnProgressChanged| calls. await flushTasks(); await flushTasks(); - assertEquals(DialogState.UPDATING, getDialogState()); + assertEquals(UpdateState.kUpdating, getUpdateState()); const fakeFirmwareUpdate = getFirmwareUpdateFromDialog(); assertEquals( `Updating ${mojoString16ToString(fakeFirmwareUpdate.deviceName)}`, @@ -125,7 +125,7 @@ // Allow firmware update to complete. await controller.getUpdateCompletedPromiseForTesting(); await flushTasks(); - assertEquals(DialogState.UPDATE_DONE, getDialogState()); + assertEquals(UpdateState.kSuccess, getUpdateState()); assertTrue(getUpdateDialog().open); assertEquals( `Your ${
diff --git a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js index 5452035..968542d9 100644 --- a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js
@@ -266,8 +266,9 @@ // page. assertTrue(!!getSpinnerPage()); assertFalse(!!getDeviceSelectionPage()); - await flushTasks(); - await waitAfterNextRender(bluetoothPairingUi); + + // Wait for DevicePairingHandler.PairDevice() to be called. + await bluetoothConfig.getLastCreatedPairingHandler().waitForPairDevice(); // Once we begin pairing we should still be in the spinner page. assertTrue(!!getSpinnerPage()); @@ -510,150 +511,148 @@ await displayPinOrPasskey(PairingAuthType.DISPLAY_PASSKEY); }); - // TODO(b/213943745) Fix flaky test. - // test('Pairing a new device cancels old pairing', async function() { - // await init(); - // let finishedPromise = eventToPromise('finished', bluetoothPairingUi); - // const device = createDefaultBluetoothDevice( - // /*id=*/ '1234321', - // /*publicName=*/ 'BeatsX', - // /*connectionState=*/ - // chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, - // /*opt_nickname=*/ 'device 1', - // /*opt_audioCapability=*/ - // mojom.AudioOutputCapability.kCapableOfAudioOutput, - // /*opt_deviceType=*/ mojom.DeviceType.kMouse); + test('Pairing a new device cancels old pairing', async function() { + await init(); + let finishedPromise = eventToPromise('finished', bluetoothPairingUi); + const device = createDefaultBluetoothDevice( + /*id=*/ '1234321', + /*publicName=*/ 'BeatsX', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, + /*opt_nickname=*/ 'device 1', + /*opt_audioCapability=*/ + mojom.AudioOutputCapability.kCapableOfAudioOutput, + /*opt_deviceType=*/ mojom.DeviceType.kMouse); - // const device1 = createDefaultBluetoothDevice( - // /*id=*/ '12345654321', - // /*publicName=*/ 'Head phones', - // /*connectionState=*/ - // chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, - // /*opt_nickname=*/ 'device 2', - // /*opt_audioCapability=*/ - // mojom.AudioOutputCapability.kCapableOfAudioOutput, - // /*opt_deviceType=*/ mojom.DeviceType.kMouse); + const device1 = createDefaultBluetoothDevice( + /*id=*/ '12345654321', + /*publicName=*/ 'Head phones', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, + /*opt_nickname=*/ 'device 2', + /*opt_audioCapability=*/ + mojom.AudioOutputCapability.kCapableOfAudioOutput, + /*opt_deviceType=*/ mojom.DeviceType.kMouse); - // const device2 = createDefaultBluetoothDevice( - // /*id=*/ '123454321', - // /*publicName=*/ 'Speakers', - // /*connectionState=*/ - // chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, - // /*opt_nickname=*/ 'device 3', - // /*opt_audioCapability=*/ - // mojom.AudioOutputCapability.kCapableOfAudioOutput, - // /*opt_deviceType=*/ mojom.DeviceType.kMouse); + const device2 = createDefaultBluetoothDevice( + /*id=*/ '123454321', + /*publicName=*/ 'Speakers', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, + /*opt_nickname=*/ 'device 3', + /*opt_audioCapability=*/ + mojom.AudioOutputCapability.kCapableOfAudioOutput, + /*opt_deviceType=*/ mojom.DeviceType.kMouse); - // bluetoothConfig.appendToDiscoveredDeviceList( - // [device.deviceProperties, device1.deviceProperties]); - // await flushTasks(); - // let deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); + bluetoothConfig.appendToDiscoveredDeviceList( + [device.deviceProperties, device1.deviceProperties]); + await flushTasks(); + let deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); - // // Try pairing to first device. - // await selectDevice(device.deviceProperties); - // await waitAfterNextRender(bluetoothPairingUi); + // Try pairing to first device. + let pairDevicePromise = deviceHandler.waitForPairDevice(); + await selectDevice(device.deviceProperties); - // // Try pairing to second device, before first device has completed - // pairing. await selectDevice(device1.deviceProperties); await - // waitAfterNextRender(bluetoothPairingUi); + // Wait for DevicePairingHandler.PairDevice() to be called. + await pairDevicePromise; + assertEquals(deviceHandler.getPairDeviceCalledCount(), 1); - // // Try pairing to third device, before first device has completed - // pairing. await selectDevice(device2.deviceProperties); await - // waitAfterNextRender(bluetoothPairingUi); + // Try pairing to second device, before first device has completed pairing. + await selectDevice(device1.deviceProperties); + await waitAfterNextRender(bluetoothPairingUi); - // // Simulate device pairing cancellation. - // deviceHandler.completePairDevice(/*success=*/ false); - // await waitAfterNextRender(bluetoothPairingUi); + // Try pairing to third device, before first device has completed pairing. + await selectDevice(device2.deviceProperties); + await waitAfterNextRender(bluetoothPairingUi); - // assertEquals(deviceHandler.getPairDeviceCalledCount(), 2); + // Simulate device pairing cancellation. + pairDevicePromise = deviceHandler.waitForPairDevice(); + deviceHandler.completePairDevice(/*success=*/ false); - // // Complete second device pairing. - // deviceHandler.completePairDevice(/*success=*/ true); - // await finishedPromise; - // }); + // Wait for DevicePairingHandler.PairDevice() to be called. + await pairDevicePromise; + assertEquals(deviceHandler.getPairDeviceCalledCount(), 2); - // TODO(b/213943745) Fix flaky test. - // test('Pair with a specific device by address, success', async function() { - // await pairByDeviceAddress(/*address=*/ '123456'); + // Complete second device pairing. + deviceHandler.completePairDevice(/*success=*/ true); + await finishedPromise; + }); - // let finishedPromise = eventToPromise('finished', bluetoothPairingUi); - // const deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); - // deviceHandler.completePairDevice(/*success=*/ true); - // await finishedPromise; - // }); + test('Pair with a specific device by address, success', async function() { + await pairByDeviceAddress(/*address=*/ '123456'); - // TODO(b/210128630) Fix flaky test. Closure compiler complains about using - // test.skip() here, see - // https://ci.chromium.org/ui/p/chromium/builders/try/linux-chromeos-rel/1058566/overview. - // test( - // 'Pair with a specific device by address, failure', async function() { - // const deviceId1 = '123456'; - // await pairByDeviceAddress(/*address=*/ deviceId1); + let finishedPromise = eventToPromise('finished', bluetoothPairingUi); + const deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); + deviceHandler.completePairDevice(/*success=*/ true); + await finishedPromise; + }); - // const deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); - // deviceHandler.completePairDevice(/*success=*/ false); + test('Pair with a specific device by address, failure', async function() { + const deviceId1 = '123456'; + await pairByDeviceAddress(/*address=*/ deviceId1); - // // Wait for the callback to finish (flushTasks() doesn't wait long - // // enough here). - // await waitAfterNextRender(bluetoothPairingUi); + const deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); + deviceHandler.completePairDevice(/*success=*/ false); + await waitAfterNextRender(bluetoothPairingUi); - // // On failure, the device selection page should be shown. - // assertTrue(!!getDeviceSelectionPage()); - // assertEquals(getDeviceSelectionPage().failedPairingDeviceId, - // deviceId1); + // On failure, the device selection page should be shown. + assertTrue(!!getDeviceSelectionPage()); + assertEquals(getDeviceSelectionPage().failedPairingDeviceId, deviceId1); - // // There should no longer be a device-specific address to pair to. - // assertFalse(!!bluetoothPairingUi.pairingDeviceAddress); + // There should no longer be a device-specific address to pair to. + assertFalse(!!bluetoothPairingUi.pairingDeviceAddress); - // // Verify we can pair with another device. - // const device2 = createDefaultBluetoothDevice( - // /*id=*/ '34567', - // /*publicName=*/ 'BeatsX', - // /*connectionState=*/ - // chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, - // /*opt_nickname=*/ 'device1', - // /*opt_audioCapability=*/ - // mojom.AudioOutputCapability.kCapableOfAudioOutput, - // /*opt_deviceType=*/ mojom.DeviceType.kMouse); - // bluetoothConfig.appendToDiscoveredDeviceList( - // [device2.deviceProperties]); - // await flushTasks(); + // Verify we can pair with another device. + const device2 = createDefaultBluetoothDevice( + /*id=*/ '34567', + /*publicName=*/ 'BeatsX', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, + /*opt_nickname=*/ 'device1', + /*opt_audioCapability=*/ + mojom.AudioOutputCapability.kCapableOfAudioOutput, + /*opt_deviceType=*/ mojom.DeviceType.kMouse); + bluetoothConfig.appendToDiscoveredDeviceList([device2.deviceProperties]); + await flushTasks(); - // let finishedPromise = eventToPromise('finished', bluetoothPairingUi); - // await selectDevice(device2.deviceProperties); + let finishedPromise = eventToPromise('finished', bluetoothPairingUi); + await selectDevice(device2.deviceProperties); - // deviceHandler.completePairDevice(/*success=*/ true); - // await finishedPromise; - // }); + deviceHandler.completePairDevice(/*success=*/ true); + await finishedPromise; + }); - // TODO(b/213943745) Fix flaky test. - // test('Pair with a specific device by address with auth', async function() { - // await pairByDeviceAddress(/*address=*/ '123456'); + test('Pair with a specific device by address with auth', async function() { + await pairByDeviceAddress(/*address=*/ '123456'); - // const pairingCode = '123457'; - // let deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); - // deviceHandler.requireAuthentication( - // PairingAuthType.CONFIRM_PASSKEY, pairingCode); - // await flushTasks(); + const pairingCode = '123457'; + let deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); + deviceHandler.requireAuthentication( + PairingAuthType.CONFIRM_PASSKEY, pairingCode); + await flushTasks(); - // // Confirmation code page should be shown. - // assertTrue(!!getConfirmCodePage()); - // assertEquals(getConfirmCodePage().code, pairingCode); + // Confirmation code page should be shown. + assertTrue(!!getConfirmCodePage()); + assertEquals(getConfirmCodePage().code, pairingCode); - // // Simulate pressing 'Confirm'. - // let event = new CustomEvent('confirm-code'); - // getConfirmCodePage().dispatchEvent(event); - // await waitAfterNextRender(bluetoothPairingUi); + // Simulate pressing 'Confirm'. + let event = new CustomEvent('confirm-code'); + let finishRequestConfirmPasskeyPromise = + deviceHandler.waitForFinishRequestConfirmPasskey_(); + getConfirmCodePage().dispatchEvent(event); - // // Spinner should be shown. - // assertTrue(!!getSpinnerPage()); - // assertTrue(deviceHandler.getConfirmPasskeyResult()); + // Wait for confirm passkey result to propagate to device handler. + await finishRequestConfirmPasskeyPromise; - // // Finishing the pairing with success should fire the |finished| event. - // let finishedPromise = eventToPromise('finished', bluetoothPairingUi); - // deviceHandler.completePairDevice(/*success=*/ true); - // await finishedPromise; - // }); + // Spinner should be shown. + assertTrue(!!getSpinnerPage()); + assertTrue(deviceHandler.getConfirmPasskeyResult()); + + // Finishing the pairing with success should fire the |finished| event. + let finishedPromise = eventToPromise('finished', bluetoothPairingUi); + deviceHandler.completePairDevice(/*success=*/ true); + await finishedPromise; + }); test( 'Cancel pairing with a specific device by address with auth', @@ -777,102 +776,109 @@ assertEquals(2, attemptFocusLastSelectedItemCallCount); }); - // TODO(b/213943745) Fix flaky test. - // test('Disable Bluetooth during pairing', async function() { - // await init(); - // assertTrue(!!getDeviceSelectionPage()); - // assertTrue(getDeviceSelectionPage().isBluetoothEnabled); + test('Disable Bluetooth during pairing', async function() { + await init(); + assertTrue(!!getDeviceSelectionPage()); + assertTrue(getDeviceSelectionPage().isBluetoothEnabled); - // const deviceId = '123456'; - // const device = createDefaultBluetoothDevice( - // deviceId, - // /*publicName=*/ 'BeatsX', - // /*connectionState=*/ - // chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, - // /*opt_nickname=*/ 'device1', - // /*opt_audioCapability=*/ - // mojom.AudioOutputCapability.kCapableOfAudioOutput, - // /*opt_deviceType=*/ mojom.DeviceType.kMouse); - // bluetoothConfig.appendToDiscoveredDeviceList([device.deviceProperties]); - // await flushTasks(); + const deviceId = '123456'; + const device = createDefaultBluetoothDevice( + deviceId, + /*publicName=*/ 'BeatsX', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, + /*opt_nickname=*/ 'device1', + /*opt_audioCapability=*/ + mojom.AudioOutputCapability.kCapableOfAudioOutput, + /*opt_deviceType=*/ mojom.DeviceType.kMouse); + bluetoothConfig.appendToDiscoveredDeviceList([device.deviceProperties]); + await flushTasks(); - // // Disable Bluetooth. - // bluetoothConfig.setSystemState( - // chromeos.bluetoothConfig.mojom.BluetoothSystemState.kDisabled); - // await flushTasks(); + // Disable Bluetooth. + bluetoothConfig.setSystemState( + chromeos.bluetoothConfig.mojom.BluetoothSystemState.kDisabled); + await flushTasks(); - // // This should propagate to the device selection page. - // assertFalse(getDeviceSelectionPage().isBluetoothEnabled); + // This should propagate to the device selection page. + assertFalse(getDeviceSelectionPage().isBluetoothEnabled); - // // Re-enable and select the device. - // bluetoothConfig.setSystemState( - // chromeos.bluetoothConfig.mojom.BluetoothSystemState.kEnabled); - // await flushTasks(); - // await waitAfterNextRender(bluetoothPairingUi); + // Re-enable and select the device. + let onBluetoothDiscoveryStartedPromise = + bluetoothPairingUi.waitForOnBluetoothDiscoveryStartedForTest(); + bluetoothConfig.setSystemState( + chromeos.bluetoothConfig.mojom.BluetoothSystemState.kEnabled); - // assertTrue(getDeviceSelectionPage().isBluetoothEnabled); - // await selectDevice(device.deviceProperties); - // await flushTasks(); + // Wait for |devicePairingHandler_| to be set in + // onBluetoothDiscoveryStarted(). + await onBluetoothDiscoveryStartedPromise; - // const pairingCode = '123456'; - // let deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); - // deviceHandler.requireAuthentication( - // PairingAuthType.CONFIRM_PASSKEY, pairingCode); - // await flushTasks(); + assertTrue(getDeviceSelectionPage().isBluetoothEnabled); + await selectDevice(device.deviceProperties); + await flushTasks(); - // // Confirmation code page should be shown. - // assertTrue(!!getConfirmCodePage()); - // assertEquals(getConfirmCodePage().code, pairingCode); + const pairingCode = '123456'; + let deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); + deviceHandler.requireAuthentication( + PairingAuthType.CONFIRM_PASSKEY, pairingCode); + await flushTasks(); - // // Disable Bluetooth. - // bluetoothConfig.setSystemState( - // chromeos.bluetoothConfig.mojom.BluetoothSystemState.kDisabled); - // await flushTasks(); + // Confirmation code page should be shown. + assertTrue(!!getConfirmCodePage()); + assertEquals(getConfirmCodePage().code, pairingCode); - // // We should be back to the device selection page again. - // assertFalse(!!getConfirmCodePage()); - // assertTrue(!!getDeviceSelectionPage()); - // assertFalse(getDeviceSelectionPage().isBluetoothEnabled); + // Disable Bluetooth. + bluetoothConfig.setSystemState( + chromeos.bluetoothConfig.mojom.BluetoothSystemState.kDisabled); + await flushTasks(); - // // Re-enable. - // bluetoothConfig.setSystemState( - // chromeos.bluetoothConfig.mojom.BluetoothSystemState.kEnabled); - // await flushTasks(); - // await waitAfterNextRender(bluetoothPairingUi); + // We should be back to the device selection page again. + assertFalse(!!getConfirmCodePage()); + assertTrue(!!getDeviceSelectionPage()); + assertFalse(getDeviceSelectionPage().isBluetoothEnabled); - // assertTrue(getDeviceSelectionPage().isBluetoothEnabled); + // Re-enable. + onBluetoothDiscoveryStartedPromise = + bluetoothPairingUi.waitForOnBluetoothDiscoveryStartedForTest(); + bluetoothConfig.setSystemState( + chromeos.bluetoothConfig.mojom.BluetoothSystemState.kEnabled); - // // Error text shouldn't be showing because this pairing failed due to - // // Bluetooth disabling. - // assertEquals(getDeviceSelectionPage().failedPairingDeviceId, ''); + // Wait for |devicePairingHandler_| to be set in + // onBluetoothDiscoveryStarted(). + await onBluetoothDiscoveryStartedPromise; - // // Select the device. - // await selectDevice(device.deviceProperties); - // await flushTasks(); + assertTrue(getDeviceSelectionPage().isBluetoothEnabled); - // // Simulate pairing failing. - // deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); - // deviceHandler.completePairDevice(/*success=*/ false); - // await flushTasks(); - // await waitAfterNextRender(bluetoothPairingUi); + // Error text shouldn't be showing because this pairing failed due to + // Bluetooth disabling. + assertEquals(getDeviceSelectionPage().failedPairingDeviceId, ''); - // // Error text should be showing. - // assertTrue(!!getDeviceSelectionPage()); - // assertEquals(getDeviceSelectionPage().failedPairingDeviceId, deviceId); + // Select the device. + await selectDevice(device.deviceProperties); + await flushTasks(); - // // Disable and re-enable. - // bluetoothConfig.setSystemState( - // chromeos.bluetoothConfig.mojom.BluetoothSystemState.kDisabled); - // await flushTasks(); + // Simulate pairing failing. + deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); + deviceHandler.completePairDevice(/*success=*/ false); + await flushTasks(); + await waitAfterNextRender(bluetoothPairingUi); - // assertFalse(getDeviceSelectionPage().isBluetoothEnabled); - // bluetoothConfig.setSystemState( - // chromeos.bluetoothConfig.mojom.BluetoothSystemState.kEnabled); - // await flushTasks(); + // Error text should be showing. + assertTrue(!!getDeviceSelectionPage()); + assertEquals(getDeviceSelectionPage().failedPairingDeviceId, deviceId); - // assertTrue(getDeviceSelectionPage().isBluetoothEnabled); + // Disable and re-enable. + bluetoothConfig.setSystemState( + chromeos.bluetoothConfig.mojom.BluetoothSystemState.kDisabled); + await flushTasks(); - // // Error text should no longer be showing. - // assertEquals(getDeviceSelectionPage().failedPairingDeviceId, ''); - // }); + assertFalse(getDeviceSelectionPage().isBluetoothEnabled); + bluetoothConfig.setSystemState( + chromeos.bluetoothConfig.mojom.BluetoothSystemState.kEnabled); + await flushTasks(); + + assertTrue(getDeviceSelectionPage().isBluetoothEnabled); + + // Error text should no longer be showing. + assertEquals(getDeviceSelectionPage().failedPairingDeviceId, ''); + }); });
diff --git a/chrome/test/data/webui/cr_components/chromeos/bluetooth/fake_device_pairing_handler.js b/chrome/test/data/webui/cr_components/chromeos/bluetooth/fake_device_pairing_handler.js index 1ac090a..177966fa 100644 --- a/chrome/test/data/webui/cr_components/chromeos/bluetooth/fake_device_pairing_handler.js +++ b/chrome/test/data/webui/cr_components/chromeos/bluetooth/fake_device_pairing_handler.js
@@ -46,6 +46,12 @@ /** @private {?chromeos.bluetoothConfig.mojom.KeyEnteredHandlerRemote} */ this.lastKeyEnteredHandlerRemote_ = null; + + /** @private {?function()} */ + this.waitForPairDeviceCallback_ = null; + + /** @private {?function()} */ + this.finishRequestConfirmPasskeyCallback_ = null; } /** @override */ @@ -56,10 +62,26 @@ this.pairDeviceCallback_ = resolve; this.pairDeviceRejectCallback_ = reject; }); + + if (this.waitForPairDeviceCallback_) { + this.waitForPairDeviceCallback_(); + } + return promise; } /** + * Returns a promise that will be resolved the next time + * pairDevice() is called. + * @return {Promise} + */ + waitForPairDevice() { + return new Promise((resolve) => { + this.waitForPairDeviceCallback_ = resolve; + }); + } + + /** * Second step in pair device operation. This method should be called * after pairDevice(). Pass in a |PairingAuthType| to simulate each * pairing request made to |DevicePairingDelegate|. @@ -68,6 +90,7 @@ * passkey/PIN authentication. */ requireAuthentication(authType, opt_pairingCode) { + assert(this.devicePairingDelegate_, 'devicePairingDelegate_ was not set.'); switch (authType) { case PairingAuthType.REQUEST_PIN_CODE: this.devicePairingDelegate_.requestPinCode() @@ -106,6 +129,17 @@ } /** + * Returns a promise that will be resolved the next time + * finishRequestConfirmPasskey_() is called. + * @return {Promise} + */ + waitForFinishRequestConfirmPasskey_() { + return new Promise((resolve) => { + this.finishRequestConfirmPasskeyCallback_ = resolve; + }); + } + + /** * @return {!chromeos.bluetoothConfig.mojom.KeyEnteredHandlerPendingReceiver} * @private */ @@ -136,6 +170,10 @@ */ finishRequestConfirmPasskey_(confirmed) { this.confirmPasskeyResult_ = confirmed; + + if (this.finishRequestConfirmPasskeyCallback_) { + this.finishRequestConfirmPasskeyCallback_(); + } } /**
diff --git a/chrome/test/data/webui/new_tab_page/BUILD.gn b/chrome/test/data/webui/new_tab_page/BUILD.gn index 8a5fc00..19d1b9d 100644 --- a/chrome/test/data/webui/new_tab_page/BUILD.gn +++ b/chrome/test/data/webui/new_tab_page/BUILD.gn
@@ -26,6 +26,9 @@ "js_module_root=" + rebase_path( "$root_gen_dir/mojom-webui/chrome/browser/new_tab_page/modules/drive", root_build_dir), + "js_module_root=" + rebase_path( + "$root_gen_dir/mojom-webui/chrome/browser/new_tab_page/modules/task_module", + root_build_dir), ] deps = [ ":metrics_utils_test",
diff --git a/chrome/test/data/webui/new_tab_page/modules/recipes_v2/BUILD.gn b/chrome/test/data/webui/new_tab_page/modules/recipes_v2/BUILD.gn index dc68bc5..cbab02e9 100644 --- a/chrome/test/data/webui/new_tab_page/modules/recipes_v2/BUILD.gn +++ b/chrome/test/data/webui/new_tab_page/modules/recipes_v2/BUILD.gn
@@ -7,6 +7,7 @@ js_library("module_test") { deps = [ "../..:test_support", + "//chrome/browser/new_tab_page/modules/task_module:mojo_bindings_webui_js", "//chrome/browser/resources/new_tab_page", "//chrome/test/data/webui:chai_assert", "//chrome/test/data/webui:test_browser_proxy",
diff --git a/chrome/test/data/webui/new_tab_page/modules/recipes_v2/module_test.js b/chrome/test/data/webui/new_tab_page/modules/recipes_v2/module_test.js index 8c8416c..17431fb 100644 --- a/chrome/test/data/webui/new_tab_page/modules/recipes_v2/module_test.js +++ b/chrome/test/data/webui/new_tab_page/modules/recipes_v2/module_test.js
@@ -3,6 +3,7 @@ // found in the LICENSE file. import {$$, recipeTasksV2Descriptor, TaskModuleHandlerProxy} from 'chrome://new-tab-page/new_tab_page.js'; +import {TaskModuleHandlerRemote} from 'chrome://new-tab-page/task_module.mojom-webui.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {assertEquals, assertTrue} from 'chrome://test/chai_assert.js'; import {installMock} from 'chrome://test/new_tab_page/test_support.js'; @@ -15,9 +16,8 @@ setup(() => { document.body.innerHTML = ''; - handler = installMock( - taskModule.mojom.TaskModuleHandlerRemote, - TaskModuleHandlerProxy.setHandler); + handler = + installMock(TaskModuleHandlerRemote, TaskModuleHandlerProxy.setHandler); }); test('module appears on render with recipes', async () => {
diff --git a/chrome/test/data/webui/new_tab_page/modules/task_module/BUILD.gn b/chrome/test/data/webui/new_tab_page/modules/task_module/BUILD.gn index 238a27e0..1b40c89 100644 --- a/chrome/test/data/webui/new_tab_page/modules/task_module/BUILD.gn +++ b/chrome/test/data/webui/new_tab_page/modules/task_module/BUILD.gn
@@ -7,6 +7,7 @@ js_library("module_test") { deps = [ "../..:test_support", + "//chrome/browser/new_tab_page/modules/task_module:mojo_bindings_webui_js", "//chrome/browser/resources/new_tab_page", "//chrome/test/data/webui:chai_assert", "//chrome/test/data/webui:test_browser_proxy",
diff --git a/chrome/test/data/webui/new_tab_page/modules/task_module/module_test.js b/chrome/test/data/webui/new_tab_page/modules/task_module/module_test.js index e017d9a..e11b4e2a 100644 --- a/chrome/test/data/webui/new_tab_page/modules/task_module/module_test.js +++ b/chrome/test/data/webui/new_tab_page/modules/task_module/module_test.js
@@ -3,6 +3,7 @@ // found in the LICENSE file. import {$$, shoppingTasksDescriptor, TaskModuleHandlerProxy} from 'chrome://new-tab-page/new_tab_page.js'; +import {TaskModuleHandlerRemote, TaskModuleType} from 'chrome://new-tab-page/task_module.mojom-webui.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {assertDeepEquals, assertEquals, assertTrue} from 'chrome://test/chai_assert.js'; import {installMock} from 'chrome://test/new_tab_page/test_support.js'; @@ -16,9 +17,8 @@ setup(() => { document.body.innerHTML = ''; - handler = installMock( - taskModule.mojom.TaskModuleHandlerRemote, - TaskModuleHandlerProxy.setHandler); + handler = + installMock(TaskModuleHandlerRemote, TaskModuleHandlerProxy.setHandler); }); test('creates no module if no task', async () => { @@ -194,7 +194,7 @@ // Assert. assertEquals('Hello world hidden', toastMessage); assertDeepEquals( - [taskModule.mojom.TaskModuleType.kShopping, 'Hello world'], + [TaskModuleType.kShopping, 'Hello world'], await handler.whenCalled('dismissTask')); // Act. @@ -202,7 +202,7 @@ // Assert. assertDeepEquals( - [taskModule.mojom.TaskModuleType.kShopping, 'Hello world'], + [TaskModuleType.kShopping, 'Hello world'], await handler.whenCalled('restoreTask')); });
diff --git a/chromecast/media/cma/decoder/cast_audio_decoder.cc b/chromecast/media/cma/decoder/cast_audio_decoder.cc index 57dfc51..ed9e7b7 100644 --- a/chromecast/media/cma/decoder/cast_audio_decoder.cc +++ b/chromecast/media/cma/decoder/cast_audio_decoder.cc
@@ -157,7 +157,7 @@ weak_this_, timestamp)); } - void OnInitialized(::media::Status status) { + void OnInitialized(::media::DecoderStatus status) { DCHECK(!initialized_); initialized_ = true; if (status.is_ok()) { @@ -185,7 +185,7 @@ } void OnDecodeStatus(base::TimeDelta buffer_timestamp, - ::media::Status status) { + ::media::DecoderStatus status) { DCHECK(pending_decode_callback_); Status result_status = kDecodeOk;
diff --git a/chromeos/crosapi/mojom/app_service_types.mojom b/chromeos/crosapi/mojom/app_service_types.mojom index 8a2e535..9080345 100644 --- a/chromeos/crosapi/mojom/app_service_types.mojom +++ b/chromeos/crosapi/mojom/app_service_types.mojom
@@ -88,7 +88,6 @@ [MinVersion=12] // kTrue if the app is able to handle intents and should be shown in intent // surfaces. - // TODO(https://crbug.com/1285186): Consider using a more accurate name. OptionalBool handles_intents@26; };
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action.cc b/components/autofill_assistant/browser/actions/collect_user_data_action.cc index 8b4783c0..4378dbb 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action.cc +++ b/components/autofill_assistant/browser/actions/collect_user_data_action.cc
@@ -1315,6 +1315,10 @@ credit_card->set_record_type(autofill::CreditCard::MASKED_SERVER_CARD); AddProtoDataToAutofillDataModel(payment_data.card_values(), proto_data.locale(), credit_card.get()); + if (!payment_data.last_four_digits().empty()) { + credit_card->SetNumber( + base::UTF8ToUTF16(payment_data.last_four_digits())); + } if (!payment_data.network().empty()) { credit_card->SetNetworkForMaskedCard(payment_data.network()); }
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc b/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc index 57444bd..ddc0f65e 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc
@@ -2500,7 +2500,16 @@ Pair(field_formatter::Key(57), "08/2050"), Pair(field_formatter::Key(58), "Visa"), Pair(field_formatter::Key(-2), "visa"), - Pair(field_formatter::Key(-5), "Visa")})); + Pair(field_formatter::Key(-5), "Visa"), + Pair(field_formatter::Key(-4), "1111")})); + // Used for card summary in UI. + EXPECT_EQ(user_data_.available_payment_instruments_[0] + ->card->NetworkForDisplay(), + u"Visa"); + EXPECT_EQ(user_data_.available_payment_instruments_[0] + ->card->LastFourDigits(), + u"1111"); + auto address_mappings = field_formatter::CreateAutofillMappings( *user_data_.available_payment_instruments_[0]->billing_address, "en-US"); @@ -2530,6 +2539,7 @@ AddCompleteCardEntriesToMap("John Doe", payment_instrument->mutable_card_values()); payment_instrument->set_network("visaCC"); + payment_instrument->set_last_four_digits("1111"); AddCompleteAddressEntriesToMap("John Doe", payment_instrument->mutable_address_values());
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index c7e0792..3a3bdd34 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -2359,6 +2359,8 @@ map<int32, AutofillEntryProto> card_values = 2; // The network of the card. optional string network = 5; + // The last 4 digits of the card. + optional string last_four_digits = 6; // The values for the billing address, where the key is one of // autofill::ServerFieldType. map<int32, AutofillEntryProto> address_values = 3;
diff --git a/components/privacy_sandbox/DEPS b/components/privacy_sandbox/DEPS index f8d4746..6df7f02 100644 --- a/components/privacy_sandbox/DEPS +++ b/components/privacy_sandbox/DEPS
@@ -2,6 +2,7 @@ "+components/content_settings/core", "+components/keyed_service/core", "+components/pref_registry", + "+net/base", "+net/cookies/site_for_cookies.h", "+content/public/test", "+components/prefs",
diff --git a/components/privacy_sandbox/privacy_sandbox_prefs.cc b/components/privacy_sandbox/privacy_sandbox_prefs.cc index f6094c3d..75a339ff 100644 --- a/components/privacy_sandbox/privacy_sandbox_prefs.cc +++ b/components/privacy_sandbox/privacy_sandbox_prefs.cc
@@ -25,6 +25,9 @@ extern const char kPrivacySandboxFlocEnabled[] = "privacy_sandbox.floc_enabled"; +extern const char kPrivacySandboxFledgeJoinBlocked[] = + "privacy_sandbox.fledge_join_blocked"; + } // namespace prefs namespace privacy_sandbox { @@ -44,6 +47,7 @@ registry->RegisterBooleanPref( prefs::kPrivacySandboxFlocEnabled, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterDictionaryPref(prefs::kPrivacySandboxFledgeJoinBlocked); } } // namespace privacy_sandbox
diff --git a/components/privacy_sandbox/privacy_sandbox_prefs.h b/components/privacy_sandbox/privacy_sandbox_prefs.h index 22f6bf7..c8cf7def 100644 --- a/components/privacy_sandbox/privacy_sandbox_prefs.h +++ b/components/privacy_sandbox/privacy_sandbox_prefs.h
@@ -35,6 +35,11 @@ // kPrivacySandboxApisEnabled preference be enabled to take effect. extern const char kPrivacySandboxFlocEnabled[]; +// Dictionary of entries representing top frame origins on which the profile +// cannot be joined to an interest group. Keys are the blocked origins, and +// values are the time the setting was applied. +extern const char kPrivacySandboxFledgeJoinBlocked[]; + } // namespace prefs namespace privacy_sandbox {
diff --git a/components/privacy_sandbox/privacy_sandbox_settings.cc b/components/privacy_sandbox/privacy_sandbox_settings.cc index 2cce9ad..e1fcb53 100644 --- a/components/privacy_sandbox/privacy_sandbox_settings.cc +++ b/components/privacy_sandbox/privacy_sandbox_settings.cc
@@ -4,12 +4,15 @@ #include "components/privacy_sandbox/privacy_sandbox_settings.h" +#include "base/json/values_util.h" #include "base/time/time.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/pref_names.h" #include "components/prefs/pref_service.h" +#include "components/prefs/scoped_user_pref_update.h" #include "components/privacy_sandbox/privacy_sandbox_prefs.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/cookies/site_for_cookies.h" #include "url/gurl.h" #include "url/origin.h" @@ -138,6 +141,84 @@ conversion_origin, cookie_settings); } +void PrivacySandboxSettings::SetFledgeJoiningAllowed( + const std::string& top_frame_etld_plus1, + bool allowed) { + DictionaryPrefUpdate scoped_pref_update( + pref_service_, prefs::kPrivacySandboxFledgeJoinBlocked); + auto* pref_data = scoped_pref_update.Get(); + DCHECK(pref_data); + DCHECK(pref_data->is_dict()); + + // Ensure that the provided etld_plus1 actually is an etld+1. + auto effective_top_frame_etld_plus1 = + net::registry_controlled_domains::GetDomainAndRegistry( + top_frame_etld_plus1, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + DCHECK(effective_top_frame_etld_plus1 == top_frame_etld_plus1); + + // Ignore attempts to configure an empty etld+1. + if (effective_top_frame_etld_plus1.length() == 0) { + NOTREACHED() << "Cannot control FLEDGE joining for empty eTLD+1"; + return; + } + + if (allowed) { + // Existence of the key implies blocking, so simply removing the key is + // sufficient. If the key wasn't already present, the following is a no-op. + pref_data->RemoveKey(effective_top_frame_etld_plus1); + } else { + // Overriding the creation date for keys which already exist is acceptable. + // Time range based deletions are typically started from the current time, + // and so this will be more aggressively removed. This decreases the chance + // a potentially sensitive website remains in preferences. + pref_data->SetKey(effective_top_frame_etld_plus1, + base::TimeToValue(base::Time::Now())); + } +} + +void PrivacySandboxSettings::ClearFledgeJoiningAllowedSettings( + base::Time start_time, + base::Time end_time) { + DictionaryPrefUpdate scoped_pref_update( + pref_service_, prefs::kPrivacySandboxFledgeJoinBlocked); + auto* pref_data = scoped_pref_update.Get(); + DCHECK(pref_data); + DCHECK(pref_data->is_dict()); + + // Shortcut for maximum time range deletion + if (start_time == base::Time() && end_time == base::Time::Max()) { + pref_data->DictClear(); + return; + } + + std::vector<std::string> keys_to_remove; + for (auto entry : pref_data->DictItems()) { + absl::optional<base::Time> created_time = base::ValueToTime(entry.second); + if (created_time.has_value() && start_time <= created_time && + created_time <= end_time) { + keys_to_remove.push_back(entry.first); + } + } + + for (const auto& key : keys_to_remove) + pref_data->RemoveKey(key); +} + +bool PrivacySandboxSettings::IsFledgeJoiningAllowed( + const url::Origin& top_frame_origin) const { + DictionaryPrefUpdate scoped_pref_update( + pref_service_, prefs::kPrivacySandboxFledgeJoinBlocked); + auto* pref_data = scoped_pref_update.Get(); + DCHECK(pref_data); + DCHECK(pref_data->is_dict()); + auto top_frame_etld_plus1 = + net::registry_controlled_domains::GetDomainAndRegistry( + top_frame_origin, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + return !pref_data->FindKey(top_frame_etld_plus1); +} + bool PrivacySandboxSettings::IsFledgeAllowed( const url::Origin& top_frame_origin, const GURL& auction_party) {
diff --git a/components/privacy_sandbox/privacy_sandbox_settings.h b/components/privacy_sandbox/privacy_sandbox_settings.h index efc48b2..c06be5c 100644 --- a/components/privacy_sandbox/privacy_sandbox_settings.h +++ b/components/privacy_sandbox/privacy_sandbox_settings.h
@@ -83,6 +83,23 @@ const url::Origin& conversion_origin, const url::Origin& reporting_origin) const; + // Sets the ability for |top_frame_etld_plus1| to join the profile to interest + // groups to |allowed|. This information is stored in preferences, and is made + // available to the API via IsFledgeJoiningAllowed(). |top_frame_etld_plus1| + // is DCHECK confirmed to be a non-empty, properly formed eTLD+1. + void SetFledgeJoiningAllowed(const std::string& top_frame_etld_plus1, + bool allowed); + + // Clears any FLEDGE joining block settings with creation times between + // |start_time| and |end_time|. + void ClearFledgeJoiningAllowedSettings(base::Time start_time, + base::Time end_time); + + // Determines whether the user may be joined to FLEDGE interest groups on, or + // by, |top_frame_origin|. This is an additional check that must be + // combined with the more generic IsFledgeAllowed(). + bool IsFledgeJoiningAllowed(const url::Origin& top_frame_origin) const; + // Determine whether |auction_party| can register an interest group, or sell / // buy in an auction, on |top_frame_origin|. bool IsFledgeAllowed(const url::Origin& top_frame_origin,
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_unittest.cc b/components/privacy_sandbox/privacy_sandbox_settings_unittest.cc index 50fe8ac..bcaad04 100644 --- a/components/privacy_sandbox/privacy_sandbox_settings_unittest.cc +++ b/components/privacy_sandbox/privacy_sandbox_settings_unittest.cc
@@ -58,6 +58,10 @@ return privacy_sandbox_settings_.get(); } + content::BrowserTaskEnvironment* task_environment() { + return &browser_task_environment_; + } + private: content::BrowserTaskEnvironment browser_task_environment_; sync_preferences::TestingPrefServiceSyncable prefs_; @@ -531,6 +535,94 @@ privacy_sandbox_settings()->FlocDataAccessibleSince()); } +TEST_F(PrivacySandboxSettingsTest, FledgeJoiningAllowed) { + // Whether or not a site can join a user to an interest group is independent + // of any other profile state. + privacy_sandbox_test_util::SetupTestState( + prefs(), host_content_settings_map(), + /*privacy_sandbox_enabled=*/false, + /*block_third_party_cookies=*/true, + /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK, + /*user_cookie_exceptions=*/ + {{"https://example.com", "*", ContentSetting::CONTENT_SETTING_BLOCK}}, + /*managed_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK, + /*managed_cookie_exceptions=*/ + {{"https://example.com", "*", ContentSetting::CONTENT_SETTING_BLOCK}}); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://example.com")))); + + // Settings should match at the eTLD + 1 level. + privacy_sandbox_settings()->SetFledgeJoiningAllowed("example.com", false); + + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://subsite.example.com")))); + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("http://example.com")))); + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://example.com:888")))); + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://example.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://example.com.au")))); + + privacy_sandbox_settings()->SetFledgeJoiningAllowed("example.com", true); + + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://example.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://subsite.example.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("http://example.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://example.com:888")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://example.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://example.com.au")))); +} + +TEST_F(PrivacySandboxSettingsTest, FledgeJoinSettingTimeRangeDeletion) { + // Confirm that time range deletions work appropriately for FLEDGE join + // settings. + privacy_sandbox_settings()->SetFledgeJoiningAllowed("first.com", false); + task_environment()->AdvanceClock(base::Hours(1)); + + const base::Time kSecondSettingTime = base::Time::Now(); + privacy_sandbox_settings()->SetFledgeJoiningAllowed("second.com", false); + + task_environment()->AdvanceClock(base::Hours(1)); + privacy_sandbox_settings()->SetFledgeJoiningAllowed("third.com", false); + + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://first.com")))); + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://second.com")))); + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://third.com")))); + + // Construct a deletion which only targets the second setting. + privacy_sandbox_settings()->ClearFledgeJoiningAllowedSettings( + kSecondSettingTime - base::Seconds(1), + kSecondSettingTime + base::Seconds(1)); + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://first.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://second.com")))); + EXPECT_FALSE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://third.com")))); + + // Perform a maximmal time range deletion, which should remove the two + // remaining settings. + privacy_sandbox_settings()->ClearFledgeJoiningAllowedSettings( + base::Time(), base::Time::Max()); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://first.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://second.com")))); + EXPECT_TRUE(privacy_sandbox_settings()->IsFledgeJoiningAllowed( + url::Origin::Create(GURL("https://third.com")))); +} + class PrivacySandboxSettingsTestCookiesClearOnExitTurnedOff : public PrivacySandboxSettingsTest { public:
diff --git a/components/services/app_service/public/cpp/app_types.cc b/components/services/app_service/public/cpp/app_types.cc index c330230..62513837 100644 --- a/components/services/app_service/public/cpp/app_types.cc +++ b/components/services/app_service/public/cpp/app_types.cc
@@ -65,6 +65,39 @@ } } +mojom::AppType ConvertAppTypeToMojomAppType(AppType app_type) { + switch (app_type) { + case AppType::kUnknown: + return apps::mojom::AppType::kUnknown; + case AppType::kArc: + return apps::mojom::AppType::kArc; + case AppType::kBuiltIn: + return apps::mojom::AppType::kBuiltIn; + case AppType::kCrostini: + return apps::mojom::AppType::kCrostini; + case AppType::kChromeApp: + return apps::mojom::AppType::kChromeApp; + case AppType::kWeb: + return apps::mojom::AppType::kWeb; + case AppType::kMacOs: + return apps::mojom::AppType::kMacOs; + case AppType::kPluginVm: + return apps::mojom::AppType::kPluginVm; + case AppType::kStandaloneBrowser: + return apps::mojom::AppType::kStandaloneBrowser; + case AppType::kRemote: + return apps::mojom::AppType::kRemote; + case AppType::kBorealis: + return apps::mojom::AppType::kBorealis; + case AppType::kSystemWeb: + return apps::mojom::AppType::kSystemWeb; + case AppType::kStandaloneBrowserChromeApp: + return apps::mojom::AppType::kStandaloneBrowserChromeApp; + case AppType::kExtension: + return apps::mojom::AppType::kExtension; + } +} + Readiness ConvertMojomReadinessToReadiness( apps::mojom::Readiness mojom_readiness) { switch (mojom_readiness) {
diff --git a/components/services/app_service/public/cpp/app_types.h b/components/services/app_service/public/cpp/app_types.h index c77d76a..de9ea26 100644 --- a/components/services/app_service/public/cpp/app_types.h +++ b/components/services/app_service/public/cpp/app_types.h
@@ -138,6 +138,9 @@ AppType ConvertMojomAppTypToAppType(apps::mojom::AppType mojom_app_type); COMPONENT_EXPORT(APP_TYPES) +mojom::AppType ConvertAppTypeToMojomAppType(AppType mojom_app_type); + +COMPONENT_EXPORT(APP_TYPES) Readiness ConvertMojomReadinessToReadiness( apps::mojom::Readiness mojom_readiness);
diff --git a/components/translate/core/browser/translate_manager_unittest.cc b/components/translate/core/browser/translate_manager_unittest.cc index b285f28..fea1ccb 100644 --- a/components/translate/core/browser/translate_manager_unittest.cc +++ b/components/translate/core/browser/translate_manager_unittest.cc
@@ -684,15 +684,15 @@ base::HistogramTester histogram_tester; prefs_.SetBoolean(prefs::kOfferTranslateEnabled, true); - translate_manager_->GetLanguageState()->LanguageDetermined("zu", true); + translate_manager_->GetLanguageState()->LanguageDetermined("en", true); network_notifier_.SimulateOnline(); - translate_manager_->InitiateTranslation("zu"); + translate_manager_->InitiateTranslation("en"); EXPECT_THAT(histogram_tester.GetAllSamples(kInitiationStatusName), ElementsAre(Bucket(metrics::INITIATION_STATUS_SHOW_INFOBAR, 1), Bucket(metrics::INITIATION_STATUS_SHOW_ICON, 1))); - translate_manager_->TranslatePage("zu", "hi", false); + translate_manager_->TranslatePage("en", "hi", false); // Accept languages should now contain "hi" because the user chose to // translate to it once. @@ -1137,7 +1137,7 @@ TEST_F(TranslateManagerTest, PredefinedTargetLanguage) { PrepareTranslateManager(); manager_->set_application_locale("en"); - ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("zu")); + ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) .WillByDefault(Return(true)); @@ -1152,19 +1152,19 @@ "ru", translate_manager_->GetLanguageState()->GetPredefinedTargetLanguage()); - translate_manager_->GetLanguageState()->LanguageDetermined("zu", true); + translate_manager_->GetLanguageState()->LanguageDetermined("en", true); EXPECT_CALL( mock_translate_client_, - ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, "zu", "ru", + ShowTranslateUI(translate::TRANSLATE_STEP_BEFORE_TRANSLATE, "en", "ru", TranslateErrors::NONE, /*triggered_from_menu=*/false)) .WillOnce(Return(true)); base::HistogramTester histogram_tester; - translate_manager_->InitiateTranslation("zu"); + translate_manager_->InitiateTranslation("en"); EXPECT_THAT( histogram_tester.GetAllSamples(kInitiationStatusName), - ::testing::Contains(Bucket( + ElementsAre(Bucket( metrics::INITIATION_STATUS_SHOW_UI_PREDEFINED_TARGET_LANGUAGE, 1))); }
diff --git a/components/translate/core/browser/translate_prefs_unittest.cc b/components/translate/core/browser/translate_prefs_unittest.cc index b845330..eed9b5f 100644 --- a/components/translate/core/browser/translate_prefs_unittest.cc +++ b/components/translate/core/browser/translate_prefs_unittest.cc
@@ -1138,12 +1138,10 @@ EXPECT_FALSE(translate_prefs_->CanTranslateLanguage( &translate_accept_languages, "en")); - if (!TranslatePrefs::IsDetailedLanguageSettingsEnabled()) { - // Blocked languages that are not in accept languages are not blocked. - translate_prefs_->BlockLanguage("de"); - EXPECT_TRUE(translate_prefs_->CanTranslateLanguage( - &translate_accept_languages, "de")); - } + // Blocked languages that are not in accept languages are not blocked. + translate_prefs_->BlockLanguage("de"); + EXPECT_TRUE(translate_prefs_->CanTranslateLanguage( + &translate_accept_languages, "de")); // When the detailed language settings are enabled blocked languages not in // accept languages can be translated.
diff --git a/content/app/content_main.cc b/content/app/content_main.cc index 33e0970..302d32d9 100644 --- a/content/app/content_main.cc +++ b/content/app/content_main.cc
@@ -358,7 +358,7 @@ // Note #2: some platforms can directly allocated shared memory in a // sandboxed process. The defines below must be in sync with the // implementation of mojo::NodeController::CreateSharedBuffer(). -#if !defined(OS_MAC) && !defined(OS_NACL_SFI) && !defined(OS_FUCHSIA) +#if !defined(OS_MAC) && !defined(OS_NACL) && !defined(OS_FUCHSIA) if (sandbox::policy::IsUnsandboxedSandboxType( sandbox::policy::SandboxTypeFromCommandLine( *base::CommandLine::ForCurrentProcess()))) { @@ -375,7 +375,7 @@ // allocate shared memory. mojo::SharedMemoryUtils::InstallBaseHooks(); } -#endif // !defined(OS_MAC) && !defined(OS_NACL_SFI) && !defined(OS_FUCHSIA) +#endif // !defined(OS_MAC) && !defined(OS_NACL) && !defined(OS_FUCHSIA) #if defined(OS_WIN) // Route stdio to parent console (if any) or create one.
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc index 9d61258..2b36a75 100644 --- a/content/browser/accessibility/browser_accessibility_android.cc +++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -1060,10 +1060,6 @@ } std::u16string BrowserAccessibilityAndroid::GetRoleDescription() const { - // If an element has an aria-roledescription set, use that value by default. - if (HasStringAttribute(ax::mojom::StringAttribute::kRoleDescription)) - return GetString16Attribute(ax::mojom::StringAttribute::kRoleDescription); - content::ContentClient* content_client = content::GetContentClient(); // As a special case, if we have a heading level return a string like
diff --git a/content/browser/interest_group/ad_auction_service_impl.cc b/content/browser/interest_group/ad_auction_service_impl.cc index 99b5dda..fd46537f 100644 --- a/content/browser/interest_group/ad_auction_service_impl.cc +++ b/content/browser/interest_group/ad_auction_service_impl.cc
@@ -336,47 +336,6 @@ auctions_.insert(std::move(auction)); } -namespace { -class FencedFrameURLMappingObserver - : public FencedFrameURLMapping::MappingResultObserver { - public: - FencedFrameURLMappingObserver() = default; - ~FencedFrameURLMappingObserver() override = default; - - void OnFencedFrameURLMappingComplete( - absl::optional<GURL> mapped_url, - absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> - pending_ad_components_map) override { - mapped_url_ = mapped_url; - called_ = true; - } - - bool called_; - absl::optional<GURL> mapped_url_; -}; - -} // namespace - -void AdAuctionServiceImpl::DeprecatedGetURLFromURN( - const GURL& urn_url, - DeprecatedGetURLFromURNCallback callback) { - if (!FencedFrameURLMapping::IsValidUrnUuidURL(urn_url)) { - std::move(callback).Run(absl::nullopt); - return; - } - FencedFrameURLMappingObserver obs; - content::FencedFrameURLMapping& mapping = - static_cast<RenderFrameHostImpl*>(render_frame_host()) - ->GetPage() - .fenced_frame_urls_map(); - // FLEDGE URN URLs should already be mapped, so the observer will be called - // synchronously. - mapping.ConvertFencedFrameURNToURL(urn_url, &obs); - if (!obs.called_) - mapping.RemoveObserverForURN(urn_url, &obs); - std::move(callback).Run(std::move(obs.mapped_url_)); -} - void AdAuctionServiceImpl::CreateAdRequest( blink::mojom::AdRequestConfigPtr config, CreateAdRequestCallback callback) {
diff --git a/content/browser/interest_group/ad_auction_service_impl.h b/content/browser/interest_group/ad_auction_service_impl.h index 72c7d5b..772c57c 100644 --- a/content/browser/interest_group/ad_auction_service_impl.h +++ b/content/browser/interest_group/ad_auction_service_impl.h
@@ -47,9 +47,6 @@ void UpdateAdInterestGroups() override; void RunAdAuction(blink::mojom::AuctionAdConfigPtr config, RunAdAuctionCallback callback) override; - void DeprecatedGetURLFromURN( - const GURL& urn_url, - DeprecatedGetURLFromURNCallback callback) override; void CreateAdRequest(blink::mojom::AdRequestConfigPtr config, CreateAdRequestCallback callback) override; void FinalizeAd(const std::string& ads_guid,
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index 220d49e5..646ca63 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -707,23 +707,10 @@ static_cast<RenderFrameHostImpl*>(adapter.render_frame_host()) ->GetPage() .fenced_frame_urls_map(); + absl::optional<FencedFrameURLMapping::PendingAdComponentsMap> ignored; fenced_frame_urls_map.ConvertFencedFrameURNToURL(urn_url, observer); } - absl::optional<GURL> ConvertFencedFrameURNToURLInJS( - const GURL& urn_url, - const absl::optional<ToRenderFrameHost> execution_target = - absl::nullopt) { - ToRenderFrameHost adapter(execution_target ? *execution_target : shell()); - EvalJsResult result = EvalJs(adapter, JsReplace(R"( - navigator.deprecatedURNToURL($1) - )", - urn_url)); - if (!result.error.empty() || result.value.is_none()) - return absl::nullopt; - return GURL(result.ExtractString()); - } - WebContentsImpl* web_contents() const { return static_cast<WebContentsImpl*>(shell()->web_contents()); } @@ -3642,10 +3629,8 @@ TestFencedFrameURLMappingResultObserver observer; ConvertFencedFrameURNToURL(*maybe_url, &observer); EXPECT_TRUE(observer.mapped_url()); - absl::optional<GURL> decoded_URL = observer.mapped_url(); - EXPECT_EQ(decoded_URL, ConvertFencedFrameURNToURLInJS(*maybe_url)); NavigateIframeAndCheckURL(web_contents(), *maybe_url, - decoded_URL.value_or(GURL())); + *observer.mapped_url()); return *observer.mapped_url(); } return absl::nullopt; @@ -4701,12 +4686,6 @@ } } -// navigator.deprecatedURNToURL returns null for an invalid URN. -IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, InvalidURN) { - GURL invalid_urn("urn:uuid:c36973b5-e5d9-de59-e4c4-364f137b3c7a"); - EXPECT_EQ(absl::nullopt, ConvertFencedFrameURNToURLInJS(invalid_urn)); -} - } // namespace } // namespace content
diff --git a/content/browser/locks/lock_manager_browsertest.cc b/content/browser/locks/lock_manager_browsertest.cc index 622efeb..eac1a325 100644 --- a/content/browser/locks/lock_manager_browsertest.cc +++ b/content/browser/locks/lock_manager_browsertest.cc
@@ -228,8 +228,8 @@ // Verify that content::FeatureObserver is notified that a frame stopped holding // locks when it is navigated away. -// TODO(crbug.com/1286329): Flakes on Linux. -#if defined(OS_LINUX) +// TODO(crbug.com/1286329): Flakes on Linux and Chrome OS. +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #define MAYBE_ObserverNavigate DISABLED_ObserverNavigate #else #define MAYBE_ObserverNavigate ObserverNavigate
diff --git a/content/browser/renderer_host/page_lifecycle_state_manager.cc b/content/browser/renderer_host/page_lifecycle_state_manager.cc index 909e722..c5ce4922 100644 --- a/content/browser/renderer_host/page_lifecycle_state_manager.cc +++ b/content/browser/renderer_host/page_lifecycle_state_manager.cc
@@ -255,6 +255,8 @@ if (acknowledged_state->should_dispatch_pageshow_for_debugging) { blink::RecordUMAEventPageShowPersisted( blink::EventPageShowPersisted::kYesInBrowserAck); + // We have received the ack, no need to track info for failures. + persisted_pageshow_timestamp_bug_1234634_.reset(); } last_acknowledged_state_ = std::move(acknowledged_state);
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc index 0f768fd..e9c5ced 100644 --- a/content/browser/webui/shared_resources_data_source.cc +++ b/content/browser/webui/shared_resources_data_source.cc
@@ -8,8 +8,6 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" -#include "content/browser/resources/media/grit/media_internals_resources.h" -#include "content/browser/resources/media/grit/media_internals_resources_map.h" #include "content/grit/content_resources.h" #include "content/grit/content_resources_map.h" #include "content/public/common/url_constants.h" @@ -114,8 +112,6 @@ AddResources(GetContentResourceIds(), kContentResources, kContentResourcesSize, source); source->AddResourcePaths( - base::make_span(kMediaInternalsResources, kMediaInternalsResourcesSize)); - source->AddResourcePaths( base::make_span(kWebuiResources, kWebuiResourcesSize)); source->AddResourcePaths( base::make_span(kWebuiGeneratedResources, kWebuiGeneratedResourcesSize));
diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc index ce0aa886..bc350e9 100644 --- a/content/renderer/pepper/video_decoder_shim.cc +++ b/content/renderer/pepper/video_decoder_shim.cc
@@ -119,9 +119,9 @@ void Stop(); private: - void OnInitDone(media::Status status); + void OnInitDone(media::DecoderStatus status); void DoDecode(); - void OnDecodeComplete(media::Status status); + void OnDecodeComplete(media::DecoderStatus status); void OnOutputComplete(scoped_refptr<media::VideoFrame> frame); void OnResetComplete(); @@ -182,7 +182,7 @@ weak_ptr_factory_.GetWeakPtr()), base::NullCallback()); #else - OnInitDone(media::StatusCode::kDecoderFailedInitialization); + OnInitDone(media::DecoderStatus::Codes::kUnsupportedCodec); #endif // BUILDFLAG(ENABLE_LIBVPX) || BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) } @@ -227,7 +227,7 @@ // This instance is deleted once we exit this scope. } -void VideoDecoderShim::DecoderImpl::OnInitDone(media::Status status) { +void VideoDecoderShim::DecoderImpl::OnInitDone(media::DecoderStatus status) { if (!status.is_ok()) { main_task_runner_->PostTask( FROM_HERE, @@ -253,14 +253,15 @@ pending_decodes_.pop(); } -void VideoDecoderShim::DecoderImpl::OnDecodeComplete(media::Status status) { +void VideoDecoderShim::DecoderImpl::OnDecodeComplete( + media::DecoderStatus status) { DCHECK(awaiting_decoder_); awaiting_decoder_ = false; int32_t result; switch (status.code()) { - case media::StatusCode::kOk: - case media::StatusCode::kAborted: + case media::DecoderStatus::Codes::kOk: + case media::DecoderStatus::Codes::kAborted: result = PP_OK; break; default:
diff --git a/content/test/data/accessibility/aria/aria-region-expected-android-external.txt b/content/test/data/accessibility/aria/aria-region-expected-android-external.txt index 2c083bc..cbf1880 100644 --- a/content/test/data/accessibility/aria/aria-region-expected-android-external.txt +++ b/content/test/data/accessibility/aria/aria-region-expected-android-external.txt
@@ -5,4 +5,4 @@ ++View text:"Named ARIA region#2 gets the region role." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="region", roleDescription="region"] ++++TextView text:"Named ARIA region#2 gets the region role." viewIdResName:"region-name" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"] ++View text:"Named region" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="region", roleDescription="region"] -++View text:"An aria-rolescription works on a nameless role=region." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="region", roleDescription="Regioneque region"] \ No newline at end of file +++View text:"An aria-rolescription works on a nameless role=region." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="region", roleDescription="region"] \ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-region-expected-android.txt b/content/test/data/accessibility/aria/aria-region-expected-android.txt index b9fe622..74b5fde 100644 --- a/content/test/data/accessibility/aria/aria-region-expected-android.txt +++ b/content/test/data/accessibility/aria/aria-region-expected-android.txt
@@ -5,4 +5,4 @@ ++android.view.View role_description='region' name='Named ARIA region#2 gets the region role.' ++++android.widget.TextView name='Named ARIA region#2 gets the region role.' ++android.view.View role_description='region' name='Named region' -++android.view.View role_description='Regioneque region' name='An aria-rolescription works on a nameless role=region.' \ No newline at end of file +++android.view.View role_description='region' name='An aria-rolescription works on a nameless role=region.' \ No newline at end of file
diff --git a/content/test/data/accessibility/aria/aria-roledescription-expected-android-external.txt b/content/test/data/accessibility/aria/aria-roledescription-expected-android-external.txt index 8db1948..fc1ef7e9 100644 --- a/content/test/data/accessibility/aria/aria-roledescription-expected-android-external.txt +++ b/content/test/data/accessibility/aria/aria-roledescription-expected-android-external.txt
@@ -1,7 +1,7 @@ WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea"] ++Button text:"Native button" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="button", clickableScore="300", roleDescription="button"] ++Button text:"ARIA button" clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="button", roleDescription="button"] -++Button text:"Clicky button" clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="button", roleDescription="Clicky"] +++Button text:"Clicky button" clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="button", roleDescription="button"] ++TextView text:"foo" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"] ++TextView text:"bar" focusable actions:[FOCUS, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"] -++TextView text:"baz" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="paragraph", roleDescription="Texty"] \ No newline at end of file +++TextView text:"baz" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="paragraph"] \ No newline at end of file
diff --git a/content/test/data/accessibility/html/svg-symbol-with-role-expected-android-external.txt b/content/test/data/accessibility/html/svg-symbol-with-role-expected-android-external.txt index 959ced7..0bb22b2 100644 --- a/content/test/data/accessibility/html/svg-symbol-with-role-expected-android-external.txt +++ b/content/test/data/accessibility/html/svg-symbol-with-role-expected-android-external.txt
@@ -1,5 +1,5 @@ WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea", hasImage="true"] ++View actions:[AX_FOCUS] bundle:[chromeRole="genericContainer", hasImage="true"] ++++Image actions:[AX_FOCUS] bundle:[chromeRole="svgRoot", hasImage="true", roleDescription="graphic"] -++++++Button text:"Click me!" viewIdResName:"myRect" clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="button", roleDescription="fancy button"] -++++++Button text:"Click me!" viewIdResName:"myRect" clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="button", roleDescription="fancy button"] \ No newline at end of file +++++++Button text:"Click me!" viewIdResName:"myRect" clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="button", roleDescription="button"] +++++++Button text:"Click me!" viewIdResName:"myRect" clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="button", roleDescription="button"] \ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index a2443284..e3e5ac8 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -561,7 +561,8 @@ crbug.com/angleproject/6430 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] deqp/functional/gles3/texturespecification/basic_copyteximage2d.html [ Failure ] crbug.com/angleproject/6430 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html [ Failure ] # Post Python 3 conversion: crbug.com/1266604 -crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/ogles/GL/* [ RetryOnFailure ] +# conformance/ogles/GL/* are too flaky to be retried. +crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/ogles/GL/* [ Failure ] crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ] crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] deqp/functional/gles3/clipping.html [ Failure ] crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] deqp/functional/gles3/fborender/shared_colorbuffer_00.html [ Failure ]
diff --git a/extensions/browser/api/app_runtime/app_runtime_api.cc b/extensions/browser/api/app_runtime/app_runtime_api.cc index 62031cb..3087cbd 100644 --- a/extensions/browser/api/app_runtime/app_runtime_api.cc +++ b/extensions/browser/api/app_runtime/app_runtime_api.cc
@@ -114,17 +114,19 @@ ASSERT_ENUM_EQUAL(kSourceArc, SOURCE_ARC); ASSERT_ENUM_EQUAL(kSourceIntentUrl, SOURCE_INTENT_URL); - // We don't allow extensions to launch an app specifying RunOnOSLogin - // or ProtocolHandler as the source. In this case we map it to - // SOURCE_CHROME_INTERNAL. + // We don't allow extensions to launch an app specifying RunOnOSLogin, + // ProtocolHandler or Reparenting as the source. In this case we map + // it to SOURCE_CHROME_INTERNAL. if (source == extensions::AppLaunchSource::kSourceRunOnOsLogin || - source == extensions::AppLaunchSource::kSourceProtocolHandler) + source == extensions::AppLaunchSource::kSourceProtocolHandler || + source == extensions::AppLaunchSource::kSourceReparenting) source = extensions::AppLaunchSource::kSourceChromeInternal; - // The +2 accounts for kSourceRunOnOsLogin and kSourceProtocolHandler not - // having a corresponding entry in app_runtime::LaunchSource. + // The +3 accounts for kSourceRunOnOsLogin, kSourceProtocolHandler and + // kSourceReparenting not having a corresponding entry in + // app_runtime::LaunchSource. static_assert(static_cast<int>(extensions::AppLaunchSource::kMaxValue) == - app_runtime::LaunchSource::LAUNCH_SOURCE_LAST + 2, + app_runtime::LaunchSource::LAUNCH_SOURCE_LAST + 3, ""); return static_cast<app_runtime::LaunchSource>(source);
diff --git a/extensions/browser/api/networking_private/networking_private_api.cc b/extensions/browser/api/networking_private/networking_private_api.cc index 57156a8..762a0fa9 100644 --- a/extensions/browser/api/networking_private/networking_private_api.cc +++ b/extensions/browser/api/networking_private/networking_private_api.cc
@@ -11,6 +11,7 @@ #include "base/callback_helpers.h" #include "base/cxx17_backports.h" #include "base/strings/string_util.h" +#include "base/values.h" #include "build/chromeos_buildflags.h" #include "components/onc/onc_constants.h" #include "extensions/browser/api/extensions_api_client.h" @@ -223,11 +224,10 @@ return did_respond() ? AlreadyResponded() : RespondLater(); } -void NetworkingPrivateGetStateFunction::Success( - std::unique_ptr<base::DictionaryValue> result) { - FilterProperties(result.get(), PropertiesType::GET, extension(), +void NetworkingPrivateGetStateFunction::Success(base::Value result) { + FilterProperties(&result, PropertiesType::GET, extension(), source_context_type(), source_url()); - Respond(OneArgument(base::Value::FromUniquePtrValue(std::move(result)))); + Respond(OneArgument(std::move(result))); } void NetworkingPrivateGetStateFunction::Failure(const std::string& error) { @@ -247,11 +247,11 @@ private_api::SetProperties::Params::Create(args()); EXTENSION_FUNCTION_VALIDATE(params); - std::unique_ptr<base::DictionaryValue> properties_dict( - params->properties.ToValue()); + base::Value properties_dict( + std::move(*params->properties.ToValue().release())); std::vector<std::string> not_allowed_properties = - FilterProperties(properties_dict.get(), PropertiesType::SET, extension(), + FilterProperties(&properties_dict, PropertiesType::SET, extension(), source_context_type(), source_url()); if (!not_allowed_properties.empty()) return RespondNow(Error(InvalidPropertiesError(not_allowed_properties))); @@ -296,11 +296,11 @@ return RespondNow(Error(networking_private::kErrorAccessToSharedConfig)); } - std::unique_ptr<base::DictionaryValue> properties_dict( - params->properties.ToValue()); + base::Value properties_dict( + std::move(*params->properties.ToValue().release())); std::vector<std::string> not_allowed_properties = - FilterProperties(properties_dict.get(), PropertiesType::SET, extension(), + FilterProperties(&properties_dict, PropertiesType::SET, extension(), source_context_type(), source_url()); if (!not_allowed_properties.empty()) return RespondNow(Error(InvalidPropertiesError(not_allowed_properties))); @@ -841,13 +841,11 @@ ExtensionFunction::ResponseAction NetworkingPrivateGetGlobalPolicyFunction::Run() { - std::unique_ptr<base::DictionaryValue> policy_dict( - GetDelegate(browser_context())->GetGlobalPolicy()); - DCHECK(policy_dict); + base::Value policy_dict(GetDelegate(browser_context())->GetGlobalPolicy()); // private_api::GlobalPolicy is a subset of the global policy dictionary // (by definition), so use the api setter/getter to generate the subset. std::unique_ptr<private_api::GlobalPolicy> policy( - private_api::GlobalPolicy::FromValue(*policy_dict)); + private_api::GlobalPolicy::FromValue(policy_dict)); DCHECK(policy); return RespondNow( ArgumentList(private_api::GetGlobalPolicy::Results::Create(*policy))); @@ -866,11 +864,9 @@ return RespondNow(Error(kPrivateOnlyError)); } - std::unique_ptr<base::DictionaryValue> certificate_lists( + base::Value certificate_lists( GetDelegate(browser_context())->GetCertificateLists()); - DCHECK(certificate_lists); - return RespondNow(OneArgument( - base::Value::FromUniquePtrValue(std::move(certificate_lists)))); + return RespondNow(OneArgument(std::move(certificate_lists))); } } // namespace extensions
diff --git a/extensions/browser/api/networking_private/networking_private_api.h b/extensions/browser/api/networking_private/networking_private_api.h index e44c016..4e78a50e 100644 --- a/extensions/browser/api/networking_private/networking_private_api.h +++ b/extensions/browser/api/networking_private/networking_private_api.h
@@ -31,7 +31,7 @@ // Implements the chrome.networkingPrivate.getProperties method. class NetworkingPrivateGetPropertiesFunction : public ExtensionFunction { public: - NetworkingPrivateGetPropertiesFunction() {} + NetworkingPrivateGetPropertiesFunction() = default; NetworkingPrivateGetPropertiesFunction( const NetworkingPrivateGetPropertiesFunction&) = delete; @@ -55,7 +55,7 @@ // Implements the chrome.networkingPrivate.getManagedProperties method. class NetworkingPrivateGetManagedPropertiesFunction : public ExtensionFunction { public: - NetworkingPrivateGetManagedPropertiesFunction() {} + NetworkingPrivateGetManagedPropertiesFunction() = default; NetworkingPrivateGetManagedPropertiesFunction( const NetworkingPrivateGetManagedPropertiesFunction&) = delete; @@ -79,7 +79,7 @@ // Implements the chrome.networkingPrivate.getState method. class NetworkingPrivateGetStateFunction : public ExtensionFunction { public: - NetworkingPrivateGetStateFunction() {} + NetworkingPrivateGetStateFunction() = default; NetworkingPrivateGetStateFunction(const NetworkingPrivateGetStateFunction&) = delete; @@ -96,14 +96,14 @@ ResponseAction Run() override; private: - void Success(std::unique_ptr<base::DictionaryValue> result); + void Success(base::Value result); void Failure(const std::string& error); }; // Implements the chrome.networkingPrivate.setProperties method. class NetworkingPrivateSetPropertiesFunction : public ExtensionFunction { public: - NetworkingPrivateSetPropertiesFunction() {} + NetworkingPrivateSetPropertiesFunction() = default; NetworkingPrivateSetPropertiesFunction( const NetworkingPrivateSetPropertiesFunction&) = delete; @@ -127,7 +127,7 @@ // Implements the chrome.networkingPrivate.createNetwork method. class NetworkingPrivateCreateNetworkFunction : public ExtensionFunction { public: - NetworkingPrivateCreateNetworkFunction() {} + NetworkingPrivateCreateNetworkFunction() = default; NetworkingPrivateCreateNetworkFunction( const NetworkingPrivateCreateNetworkFunction&) = delete; @@ -151,7 +151,7 @@ // Implements the chrome.networkingPrivate.createNetwork method. class NetworkingPrivateForgetNetworkFunction : public ExtensionFunction { public: - NetworkingPrivateForgetNetworkFunction() {} + NetworkingPrivateForgetNetworkFunction() = default; NetworkingPrivateForgetNetworkFunction( const NetworkingPrivateForgetNetworkFunction&) = delete; @@ -175,7 +175,7 @@ // Implements the chrome.networkingPrivate.getNetworks method. class NetworkingPrivateGetNetworksFunction : public ExtensionFunction { public: - NetworkingPrivateGetNetworksFunction() {} + NetworkingPrivateGetNetworksFunction() = default; NetworkingPrivateGetNetworksFunction( const NetworkingPrivateGetNetworksFunction&) = delete; @@ -199,7 +199,7 @@ // Implements the chrome.networkingPrivate.getVisibleNetworks method. class NetworkingPrivateGetVisibleNetworksFunction : public ExtensionFunction { public: - NetworkingPrivateGetVisibleNetworksFunction() {} + NetworkingPrivateGetVisibleNetworksFunction() = default; NetworkingPrivateGetVisibleNetworksFunction( const NetworkingPrivateGetVisibleNetworksFunction&) = delete; @@ -224,7 +224,7 @@ class NetworkingPrivateGetEnabledNetworkTypesFunction : public ExtensionFunction { public: - NetworkingPrivateGetEnabledNetworkTypesFunction() {} + NetworkingPrivateGetEnabledNetworkTypesFunction() = default; NetworkingPrivateGetEnabledNetworkTypesFunction( const NetworkingPrivateGetEnabledNetworkTypesFunction&) = delete; @@ -244,7 +244,7 @@ // Implements the chrome.networkingPrivate.getDeviceStates method. class NetworkingPrivateGetDeviceStatesFunction : public ExtensionFunction { public: - NetworkingPrivateGetDeviceStatesFunction() {} + NetworkingPrivateGetDeviceStatesFunction() = default; NetworkingPrivateGetDeviceStatesFunction( const NetworkingPrivateGetDeviceStatesFunction&) = delete; @@ -264,7 +264,7 @@ // Implements the chrome.networkingPrivate.enableNetworkType method. class NetworkingPrivateEnableNetworkTypeFunction : public ExtensionFunction { public: - NetworkingPrivateEnableNetworkTypeFunction() {} + NetworkingPrivateEnableNetworkTypeFunction() = default; NetworkingPrivateEnableNetworkTypeFunction( const NetworkingPrivateEnableNetworkTypeFunction&) = delete; @@ -284,7 +284,7 @@ // Implements the chrome.networkingPrivate.disableNetworkType method. class NetworkingPrivateDisableNetworkTypeFunction : public ExtensionFunction { public: - NetworkingPrivateDisableNetworkTypeFunction() {} + NetworkingPrivateDisableNetworkTypeFunction() = default; NetworkingPrivateDisableNetworkTypeFunction( const NetworkingPrivateDisableNetworkTypeFunction&) = delete; @@ -304,7 +304,7 @@ // Implements the chrome.networkingPrivate.requestNetworkScan method. class NetworkingPrivateRequestNetworkScanFunction : public ExtensionFunction { public: - NetworkingPrivateRequestNetworkScanFunction() {} + NetworkingPrivateRequestNetworkScanFunction() = default; NetworkingPrivateRequestNetworkScanFunction( const NetworkingPrivateRequestNetworkScanFunction&) = delete; @@ -324,7 +324,7 @@ // Implements the chrome.networkingPrivate.startConnect method. class NetworkingPrivateStartConnectFunction : public ExtensionFunction { public: - NetworkingPrivateStartConnectFunction() {} + NetworkingPrivateStartConnectFunction() = default; NetworkingPrivateStartConnectFunction( const NetworkingPrivateStartConnectFunction&) = delete; @@ -348,7 +348,7 @@ // Implements the chrome.networkingPrivate.startDisconnect method. class NetworkingPrivateStartDisconnectFunction : public ExtensionFunction { public: - NetworkingPrivateStartDisconnectFunction() {} + NetworkingPrivateStartDisconnectFunction() = default; NetworkingPrivateStartDisconnectFunction( const NetworkingPrivateStartDisconnectFunction&) = delete; @@ -372,7 +372,7 @@ // Implements the chrome.networkingPrivate.startActivate method. class NetworkingPrivateStartActivateFunction : public ExtensionFunction { public: - NetworkingPrivateStartActivateFunction() {} + NetworkingPrivateStartActivateFunction() = default; NetworkingPrivateStartActivateFunction( const NetworkingPrivateStartActivateFunction&) = delete; @@ -396,7 +396,7 @@ class NetworkingPrivateGetCaptivePortalStatusFunction : public ExtensionFunction { public: - NetworkingPrivateGetCaptivePortalStatusFunction() {} + NetworkingPrivateGetCaptivePortalStatusFunction() = default; NetworkingPrivateGetCaptivePortalStatusFunction( const NetworkingPrivateGetCaptivePortalStatusFunction&) = delete; @@ -419,7 +419,7 @@ class NetworkingPrivateUnlockCellularSimFunction : public ExtensionFunction { public: - NetworkingPrivateUnlockCellularSimFunction() {} + NetworkingPrivateUnlockCellularSimFunction() = default; NetworkingPrivateUnlockCellularSimFunction( const NetworkingPrivateUnlockCellularSimFunction&) = delete; @@ -442,7 +442,7 @@ class NetworkingPrivateSetCellularSimStateFunction : public ExtensionFunction { public: - NetworkingPrivateSetCellularSimStateFunction() {} + NetworkingPrivateSetCellularSimStateFunction() = default; NetworkingPrivateSetCellularSimStateFunction( const NetworkingPrivateSetCellularSimStateFunction&) = delete; @@ -466,7 +466,7 @@ class NetworkingPrivateSelectCellularMobileNetworkFunction : public ExtensionFunction { public: - NetworkingPrivateSelectCellularMobileNetworkFunction() {} + NetworkingPrivateSelectCellularMobileNetworkFunction() = default; NetworkingPrivateSelectCellularMobileNetworkFunction( const NetworkingPrivateSelectCellularMobileNetworkFunction&) = delete; @@ -489,7 +489,7 @@ class NetworkingPrivateGetGlobalPolicyFunction : public ExtensionFunction { public: - NetworkingPrivateGetGlobalPolicyFunction() {} + NetworkingPrivateGetGlobalPolicyFunction() = default; NetworkingPrivateGetGlobalPolicyFunction( const NetworkingPrivateGetGlobalPolicyFunction&) = delete; @@ -508,7 +508,7 @@ class NetworkingPrivateGetCertificateListsFunction : public ExtensionFunction { public: - NetworkingPrivateGetCertificateListsFunction() {} + NetworkingPrivateGetCertificateListsFunction() = default; NetworkingPrivateGetCertificateListsFunction( const NetworkingPrivateGetCertificateListsFunction&) = delete;
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos.cc b/extensions/browser/api/networking_private/networking_private_chromeos.cc index e3e36be..daf8dc3d 100644 --- a/extensions/browser/api/networking_private/networking_private_chromeos.cc +++ b/extensions/browser/api/networking_private/networking_private_chromeos.cc
@@ -339,16 +339,16 @@ return; } - std::unique_ptr<base::DictionaryValue> network_properties = - chromeos::network_util::TranslateNetworkStateToONC(network_state); - AppendThirdPartyProviderName(network_properties.get()); + base::Value network_properties = base::Value::FromUniquePtrValue( + chromeos::network_util::TranslateNetworkStateToONC(network_state)); + AppendThirdPartyProviderName(&network_properties); std::move(success_callback).Run(std::move(network_properties)); } void NetworkingPrivateChromeOS::SetProperties( const std::string& guid, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, bool allow_set_shared_config, VoidCallback success_callback, FailureCallback failure_callback) { @@ -383,7 +383,8 @@ NET_LOG(USER) << "networkingPrivate.setProperties for: " << NetworkId(network); GetManagedConfigurationHandler()->SetProperties( - network->path(), *properties, std::move(success_callback), + network->path(), static_cast<base::DictionaryValue&>(properties), + std::move(success_callback), base::BindOnce(&NetworkHandlerFailureCallback, std::move(failure_callback))); } @@ -397,7 +398,7 @@ void NetworkingPrivateChromeOS::CreateNetwork( bool shared, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, StringCallback success_callback, FailureCallback failure_callback) { std::string user_id_hash, error; @@ -409,10 +410,10 @@ } const std::string guid = - GetStringFromDictionary(*properties, ::onc::network_config::kGUID); + GetStringFromDictionary(properties, ::onc::network_config::kGUID); NET_LOG(USER) << "networkingPrivate.CreateNetwork. GUID=" << guid; GetManagedConfigurationHandler()->CreateConfiguration( - user_id_hash, *properties, + user_id_hash, static_cast<base::DictionaryValue&>(properties), base::BindOnce(&NetworkHandlerCreateCallback, std::move(success_callback)), base::BindOnce(&NetworkHandlerFailureCallback, @@ -721,19 +722,17 @@ return device_state_list; } -std::unique_ptr<base::DictionaryValue> -NetworkingPrivateChromeOS::GetGlobalPolicy() { - auto result = std::make_unique<base::DictionaryValue>(); +base::Value NetworkingPrivateChromeOS::GetGlobalPolicy() { + base::Value result(base::Value::Type::DICTIONARY); const base::DictionaryValue* global_network_config = GetManagedConfigurationHandler()->GetGlobalConfigFromPolicy( std::string() /* no username hash, device policy */); if (global_network_config) - result->MergeDictionary(global_network_config); + result.MergeDictionary(global_network_config); return result; } -std::unique_ptr<base::DictionaryValue> -NetworkingPrivateChromeOS::GetCertificateLists() { +base::Value NetworkingPrivateChromeOS::GetCertificateLists() { private_api::CertificateLists result; const std::vector<NetworkCertificateHandler::Certificate>& server_cas = NetworkHandler::Get() @@ -750,7 +749,7 @@ for (const auto& cert : user_certs) result.user_certificates.push_back(GetCertDictionary(cert)); - return result.ToValue(); + return base::Value::FromUniquePtrValue(result.ToValue()); } bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string& type) {
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos.h b/extensions/browser/api/networking_private/networking_private_chromeos.h index 52a2c1bb..3ebb677 100644 --- a/extensions/browser/api/networking_private/networking_private_chromeos.h +++ b/extensions/browser/api/networking_private/networking_private_chromeos.h
@@ -41,12 +41,12 @@ DictionaryCallback success_callback, FailureCallback failure_callback) override; void SetProperties(const std::string& guid, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, bool allow_set_shared_config, VoidCallback success_callback, FailureCallback failure_callback) override; void CreateNetwork(bool shared, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, StringCallback success_callback, FailureCallback failure_callback) override; void ForgetNetwork(const std::string& guid, @@ -89,8 +89,8 @@ FailureCallback failure_callback) override; base::Value GetEnabledNetworkTypes() override; std::unique_ptr<DeviceStateList> GetDeviceStateList() override; - std::unique_ptr<base::DictionaryValue> GetGlobalPolicy() override; - std::unique_ptr<base::DictionaryValue> GetCertificateLists() override; + base::Value GetGlobalPolicy() override; + base::Value GetCertificateLists() override; bool EnableNetworkType(const std::string& type) override; bool DisableNetworkType(const std::string& type) override; bool RequestScan(const std::string& type) override;
diff --git a/extensions/browser/api/networking_private/networking_private_delegate.h b/extensions/browser/api/networking_private/networking_private_delegate.h index 30ce0a5..3d605d7 100644 --- a/extensions/browser/api/networking_private/networking_private_delegate.h +++ b/extensions/browser/api/networking_private/networking_private_delegate.h
@@ -24,8 +24,7 @@ // networking_private.idl for descriptions of the expected inputs and results. class NetworkingPrivateDelegate : public KeyedService { public: - using DictionaryCallback = - base::OnceCallback<void(std::unique_ptr<base::DictionaryValue>)>; + using DictionaryCallback = base::OnceCallback<void(base::Value)>; using VoidCallback = base::OnceCallback<void()>; using BoolCallback = base::OnceCallback<void(bool)>; using StringCallback = base::OnceCallback<void(const std::string&)>; @@ -78,12 +77,12 @@ DictionaryCallback success_callback, FailureCallback failure_callback) = 0; virtual void SetProperties(const std::string& guid, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, bool allow_set_shared_config, VoidCallback success_callback, FailureCallback failure_callback) = 0; virtual void CreateNetwork(bool shared, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, StringCallback success_callback, FailureCallback failure_callback) = 0; virtual void ForgetNetwork(const std::string& guid, @@ -138,10 +137,10 @@ // dictionary is expected to be a superset of the networkingPrivate // GlobalPolicy dictionary. Any properties not in GlobalPolicy will be // ignored. - virtual std::unique_ptr<base::DictionaryValue> GetGlobalPolicy() = 0; + virtual base::Value GetGlobalPolicy() = 0; // Returns a dictionary of certificate lists. - virtual std::unique_ptr<base::DictionaryValue> GetCertificateLists() = 0; + virtual base::Value GetCertificateLists() = 0; // Returns true if the ONC network type |type| is enabled. virtual bool EnableNetworkType(const std::string& type) = 0;
diff --git a/extensions/browser/api/networking_private/networking_private_linux.cc b/extensions/browser/api/networking_private/networking_private_linux.cc index 80e65de..8a90826d 100644 --- a/extensions/browser/api/networking_private/networking_private_linux.cc +++ b/extensions/browser/api/networking_private/networking_private_linux.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <memory> #include <string> #include <utility> @@ -15,6 +16,7 @@ #include "base/memory/scoped_refptr.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" +#include "base/values.h" #include "components/onc/onc_constants.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -85,7 +87,7 @@ auto network_list = std::make_unique<base::ListValue>(); for (const auto& network : network_map) { - network_list->Append(network.second->CreateDeepCopy()); + network_list->Append(network.second.Clone()); } return network_list; @@ -125,21 +127,21 @@ // from the |dbus_thread_|. void GetCachedNetworkPropertiesCallback( std::unique_ptr<std::string> error, - std::unique_ptr<base::DictionaryValue> properties, + std::unique_ptr<base::Value> properties, NetworkingPrivateDelegate::DictionaryCallback success_callback, NetworkingPrivateDelegate::FailureCallback failure_callback) { if (!error->empty()) { std::move(failure_callback).Run(*error); return; } - std::move(success_callback).Run(std::move(properties)); + std::move(success_callback).Run(std::move(*properties)); } // Fires the appropriate callback when the network properties are returned // from the |dbus_thread_|. void GetCachedNetworkPropertiesResultCallback( std::unique_ptr<std::string> error, - std::unique_ptr<base::DictionaryValue> properties, + std::unique_ptr<base::Value> properties, NetworkingPrivateDelegate::PropertiesCallback callback) { if (!error->empty()) { LOG(ERROR) << "GetCachedNetworkProperties failed: " << *error; @@ -193,7 +195,7 @@ LOG(ERROR) << "Platform does not support NetworkManager over DBUS"; } - network_map_.reset(new NetworkMap()); + network_map_ = std::make_unique<NetworkMap>(); } bool NetworkingPrivateLinux::CheckNetworkManagerSupported() { @@ -210,17 +212,16 @@ } std::unique_ptr<std::string> error(new std::string); - std::unique_ptr<base::DictionaryValue> network_properties( - new base::DictionaryValue); + auto network_properties = + std::make_unique<base::Value>(base::Value::Type::DICTIONARY); // Runs GetCachedNetworkProperties on |dbus_thread|. std::string* error_ptr = error.get(); - base::DictionaryValue* network_prop_ptr = network_properties.get(); dbus_thread_.task_runner()->PostTaskAndReply( FROM_HERE, base::BindOnce(&NetworkingPrivateLinux::GetCachedNetworkProperties, base::Unretained(this), guid, - base::Unretained(network_prop_ptr), + base::Unretained(network_properties.get()), base::Unretained(error_ptr)), base::BindOnce(&GetCachedNetworkPropertiesResultCallback, std::move(error), std::move(network_properties), @@ -243,27 +244,25 @@ } std::unique_ptr<std::string> error(new std::string); - std::unique_ptr<base::DictionaryValue> network_properties( - new base::DictionaryValue); + auto network_properties = + std::make_unique<base::Value>(base::Value::Type::DICTIONARY); // Runs GetCachedNetworkProperties on |dbus_thread|. std::string* error_ptr = error.get(); - base::DictionaryValue* network_prop_ptr = network_properties.get(); dbus_thread_.task_runner()->PostTaskAndReply( FROM_HERE, base::BindOnce(&NetworkingPrivateLinux::GetCachedNetworkProperties, base::Unretained(this), guid, - base::Unretained(network_prop_ptr), + base::Unretained(network_properties.get()), base::Unretained(error_ptr)), base::BindOnce(&GetCachedNetworkPropertiesCallback, std::move(error), std::move(network_properties), std::move(success_callback), std::move(failure_callback))); } -void NetworkingPrivateLinux::GetCachedNetworkProperties( - const std::string& guid, - base::DictionaryValue* properties, - std::string* error) { +void NetworkingPrivateLinux::GetCachedNetworkProperties(const std::string& guid, + base::Value* properties, + std::string* error) { AssertOnDBusThread(); std::string ssid; @@ -279,28 +278,21 @@ return; } - // Make a copy of the properties out of the cached map. - std::unique_ptr<base::DictionaryValue> temp_properties( - network_iter->second->DeepCopy()); - - // Swap the new copy into the dictionary that is shared with the reply. - properties->Swap(temp_properties.get()); + *properties = network_iter->second.Clone(); } -void NetworkingPrivateLinux::SetProperties( - const std::string& guid, - std::unique_ptr<base::DictionaryValue> properties, - bool allow_set_shared_config, - VoidCallback success_callback, - FailureCallback failure_callback) { +void NetworkingPrivateLinux::SetProperties(const std::string& guid, + base::Value properties, + bool allow_set_shared_config, + VoidCallback success_callback, + FailureCallback failure_callback) { ReportNotSupported("SetProperties", std::move(failure_callback)); } -void NetworkingPrivateLinux::CreateNetwork( - bool shared, - std::unique_ptr<base::DictionaryValue> properties, - StringCallback success_callback, - FailureCallback failure_callback) { +void NetworkingPrivateLinux::CreateNetwork(bool shared, + base::Value properties, + StringCallback success_callback, + FailureCallback failure_callback) { ReportNotSupported("CreateNetwork", std::move(failure_callback)); } @@ -510,9 +502,8 @@ return; } - std::string connection_state; - network_iter->second->GetString(kAccessPointInfoConnectionState, - &connection_state); + std::string connection_state = + *network_iter->second.FindStringPath(kAccessPointInfoConnectionState); if (connection_state == ::onc::connection_state::kNotConnected) { // Already disconnected so nothing to do. return; @@ -627,14 +618,12 @@ return device_state_list; } -std::unique_ptr<base::DictionaryValue> -NetworkingPrivateLinux::GetGlobalPolicy() { - return std::make_unique<base::DictionaryValue>(); +base::Value NetworkingPrivateLinux::GetGlobalPolicy() { + return {}; } -std::unique_ptr<base::DictionaryValue> -NetworkingPrivateLinux ::GetCertificateLists() { - return std::make_unique<base::DictionaryValue>(); +base::Value NetworkingPrivateLinux ::GetCertificateLists() { + return {}; } bool NetworkingPrivateLinux::EnableNetworkType(const std::string& type) { @@ -681,7 +670,7 @@ } void NetworkingPrivateLinux::SendNetworkListChangedEvent( - const base::ListValue& network_list) { + const base::Value& network_list) { GuidList guidsForEventCallback; for (const auto& network : network_list.GetList()) { @@ -801,7 +790,7 @@ bool NetworkingPrivateLinux::GetAccessPointInfo( const dbus::ObjectPath& access_point_path, - const std::unique_ptr<base::DictionaryValue>& access_point_info) { + base::Value* access_point_info) { AssertOnDBusThread(); dbus::ObjectProxy* access_point_proxy = dbus_->GetObjectProxy( networking_private::kNetworkManagerNamespace, access_point_path); @@ -835,7 +824,7 @@ std::string ssidUTF8(ssid_bytes, ssid_bytes + ssid_length); std::u16string ssid = base::UTF8ToUTF16(ssidUTF8); - access_point_info->SetString(kAccessPointInfoName, ssid); + access_point_info->SetStringKey(kAccessPointInfoName, ssid); } // Read signal strength. @@ -855,8 +844,8 @@ return false; } - access_point_info->SetInteger(kAccessPointInfoWifiSignalStrengthDotted, - strength); + access_point_info->SetIntKey(kAccessPointInfoWifiSignalStrengthDotted, + strength); } // Read the security type. This is from the WpaFlags and RsnFlags property @@ -901,9 +890,10 @@ std::string security; MapSecurityFlagsToString(rsn_security_flags | wpa_security_flags, &security); - access_point_info->SetString(kAccessPointInfoWifiSecurityDotted, security); - access_point_info->SetString(kAccessPointInfoType, kAccessPointInfoTypeWifi); - access_point_info->SetBoolean(kAccessPointInfoConnectable, true); + access_point_info->SetStringKey(kAccessPointInfoWifiSecurityDotted, security); + access_point_info->SetStringKey(kAccessPointInfoType, + kAccessPointInfoTypeWifi); + access_point_info->SetBoolKey(kAccessPointInfoConnectable, true); return true; } @@ -939,19 +929,17 @@ } for (const auto& access_point_path : access_point_paths) { - std::unique_ptr<base::DictionaryValue> access_point( - new base::DictionaryValue); + base::Value access_point(base::Value::Type::DICTIONARY); - if (GetAccessPointInfo(access_point_path, access_point)) { + if (GetAccessPointInfo(access_point_path, &access_point)) { std::string connection_state = (access_point_path == connected_access_point) ? ::onc::connection_state::kConnected : ::onc::connection_state::kNotConnected; - access_point->SetString(kAccessPointInfoConnectionState, - connection_state); - std::string ssid; - access_point->GetString(kAccessPointInfoName, &ssid); + access_point.SetStringKey(kAccessPointInfoConnectionState, + connection_state); + std::string ssid = *access_point.FindStringPath(kAccessPointInfoName); std::string network_guid = ConstructNetworkGuid(device_path, access_point_path, ssid); @@ -960,7 +948,7 @@ // access point paths, this consolidates them. If it is already // in the map it updates the signal strength and GUID paths if this // network is stronger or the one that is connected. - AddOrUpdateAccessPoint(network_map, network_guid, access_point); + AddOrUpdateAccessPoint(network_map, network_guid, &access_point); } } @@ -970,44 +958,39 @@ void NetworkingPrivateLinux::AddOrUpdateAccessPoint( NetworkMap* network_map, const std::string& network_guid, - std::unique_ptr<base::DictionaryValue>& access_point) { - std::u16string ssid; - std::string connection_state; - int signal_strength; - - access_point->GetString(kAccessPointInfoConnectionState, &connection_state); - access_point->GetInteger(kAccessPointInfoWifiSignalStrengthDotted, - &signal_strength); - access_point->GetString(kAccessPointInfoName, &ssid); - access_point->SetString(kAccessPointInfoGuid, network_guid); + base::Value* access_point) { + std::string connection_state = + *access_point->FindStringPath(kAccessPointInfoConnectionState); + int signal_strength = + *access_point->FindIntPath(kAccessPointInfoWifiSignalStrengthDotted); + std::u16string ssid = + base::UTF8ToUTF16(*access_point->FindStringPath(kAccessPointInfoName)); + access_point->SetStringPath(kAccessPointInfoGuid, network_guid); auto existing_access_point_iter = network_map->find(ssid); if (existing_access_point_iter == network_map->end()) { // Unseen access point. Add it to the map. - network_map->insert(NetworkMap::value_type(ssid, std::move(access_point))); + network_map->insert(NetworkMap::value_type(ssid, std::move(*access_point))); } else { // Already seen access point. Update the record if this is the connected // record or if the signal strength is higher. But don't override a weaker // access point if that is the one that is connected. - int existing_signal_strength; - base::DictionaryValue* existing_access_point = - existing_access_point_iter->second.get(); - existing_access_point->GetInteger(kAccessPointInfoWifiSignalStrengthDotted, - &existing_signal_strength); + base::Value& existing_access_point = existing_access_point_iter->second; + int existing_signal_strength = *existing_access_point.FindIntPath( + kAccessPointInfoWifiSignalStrengthDotted); - std::string existing_connection_state; - existing_access_point->GetString(kAccessPointInfoConnectionState, - &existing_connection_state); + std::string existing_connection_state = + *existing_access_point.FindStringPath(kAccessPointInfoConnectionState); if ((connection_state == ::onc::connection_state::kConnected) || (!(existing_connection_state == ::onc::connection_state::kConnected) && signal_strength > existing_signal_strength)) { - existing_access_point->SetString(kAccessPointInfoConnectionState, - connection_state); - existing_access_point->SetInteger( - kAccessPointInfoWifiSignalStrengthDotted, signal_strength); - existing_access_point->SetString(kAccessPointInfoGuid, network_guid); + existing_access_point.SetStringPath(kAccessPointInfoConnectionState, + connection_state); + existing_access_point.SetIntPath(kAccessPointInfoWifiSignalStrengthDotted, + signal_strength); + existing_access_point.SetStringPath(kAccessPointInfoGuid, network_guid); } } } @@ -1187,33 +1170,33 @@ // If setting this network to connected, find the previously connected network // and disconnect that one. Also retain the guid of that network to fire a // changed event. - std::string connected_network_guid; + std::string* connected_network_guid = nullptr; if (connection_state == ::onc::connection_state::kConnected) { for (auto& network : *network_map_) { - std::string other_connection_state; - if (network.second->GetString(kAccessPointInfoConnectionState, - &other_connection_state)) { - if (other_connection_state == ::onc::connection_state::kConnected) { - network.second->GetString(kAccessPointInfoGuid, - &connected_network_guid); - network.second->SetString(kAccessPointInfoConnectionState, - ::onc::connection_state::kNotConnected); + if (std::string* other_connection_state = + network.second.FindStringPath(kAccessPointInfoConnectionState)) { + if (*other_connection_state == ::onc::connection_state::kConnected) { + connected_network_guid = + network.second.FindStringPath(kAccessPointInfoGuid); + network.second.SetStringPath(kAccessPointInfoConnectionState, + ::onc::connection_state::kNotConnected); } } } } // Set the status. - network_iter->second->SetString(kAccessPointInfoConnectionState, - connection_state); + network_iter->second.SetStringPath(kAccessPointInfoConnectionState, + connection_state); std::unique_ptr<GuidList> changed_networks(new GuidList()); changed_networks->push_back(guid); // Only add a second network if it exists and it is not the same as the // network already being added to the list. - if (!connected_network_guid.empty() && connected_network_guid != guid) { - changed_networks->push_back(connected_network_guid); + if (connected_network_guid && !connected_network_guid->empty() && + *connected_network_guid != guid) { + changed_networks->push_back(*connected_network_guid); } PostOnNetworksChangedToUIThread(std::move(changed_networks));
diff --git a/extensions/browser/api/networking_private/networking_private_linux.h b/extensions/browser/api/networking_private/networking_private_linux.h index 2fffeaf2..3d94778 100644 --- a/extensions/browser/api/networking_private/networking_private_linux.h +++ b/extensions/browser/api/networking_private/networking_private_linux.h
@@ -27,8 +27,7 @@ // Linux NetworkingPrivateDelegate implementation. class NetworkingPrivateLinux : public NetworkingPrivateDelegate { public: - using NetworkMap = - std::map<std::u16string, std::unique_ptr<base::DictionaryValue>>; + using NetworkMap = std::map<std::u16string, base::Value>; typedef std::vector<std::string> GuidList; @@ -46,12 +45,12 @@ DictionaryCallback success_callback, FailureCallback failure_callback) override; void SetProperties(const std::string& guid, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, bool allow_set_shared_config, VoidCallback success_callback, FailureCallback failure_callback) override; void CreateNetwork(bool shared, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, StringCallback success_callback, FailureCallback failure_callback) override; void ForgetNetwork(const std::string& guid, @@ -90,8 +89,8 @@ FailureCallback failure_callback) override; base::Value GetEnabledNetworkTypes() override; std::unique_ptr<DeviceStateList> GetDeviceStateList() override; - std::unique_ptr<base::DictionaryValue> GetGlobalPolicy() override; - std::unique_ptr<base::DictionaryValue> GetCertificateLists() override; + base::Value GetGlobalPolicy() override; + base::Value GetCertificateLists() override; bool EnableNetworkType(const std::string& type) override; bool DisableNetworkType(const std::string& type) override; bool RequestScan(const std::string& type) override; @@ -184,14 +183,13 @@ // Helper function for OnAccessPointsFound and OnAccessPointsFoundViaScan to // fire the OnNetworkListChangedEvent. - void SendNetworkListChangedEvent(const base::ListValue& network_list); + void SendNetworkListChangedEvent(const base::Value& network_list); // Gets a dictionary of information about the access point. // Returns false if there is an error getting information about the // supplied |access_point_path|. - bool GetAccessPointInfo( - const dbus::ObjectPath& access_point_path, - const std::unique_ptr<base::DictionaryValue>& access_point_info); + bool GetAccessPointInfo(const dbus::ObjectPath& access_point_path, + base::Value* access_point_info); // Helper function to extract a property from a device. // Returns the dbus::Response object from calling Get on the supplied @@ -203,10 +201,9 @@ // If the access_point is not already in the map it is added. Otherwise // the access point is updated (eg. with the max of the signal // strength). - void AddOrUpdateAccessPoint( - NetworkMap* network_map, - const std::string& network_guid, - std::unique_ptr<base::DictionaryValue>& access_point); + void AddOrUpdateAccessPoint(NetworkMap* network_map, + const std::string& network_guid, + base::Value* access_point); // Maps the WPA security flags to a human readable string. void MapSecurityFlagsToString(uint32_t securityFlags, std::string* security); @@ -246,7 +243,7 @@ void OnNetworksChangedEventTask(std::unique_ptr<GuidList> guid_list); void GetCachedNetworkProperties(const std::string& guid, - base::DictionaryValue* properties, + base::Value* properties, std::string* error); void OnNetworksChangedEventOnUIThread(const GuidList& network_guids);
diff --git a/extensions/browser/api/networking_private/networking_private_service_client.cc b/extensions/browser/api/networking_private/networking_private_service_client.cc index 3f5da9d5..204bfde 100644 --- a/extensions/browser/api/networking_private/networking_private_service_client.cc +++ b/extensions/browser/api/networking_private/networking_private_service_client.cc
@@ -177,7 +177,7 @@ void NetworkingPrivateServiceClient::SetProperties( const std::string& guid, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, bool allow_set_shared_config, VoidCallback success_callback, FailureCallback failure_callback) { @@ -193,7 +193,9 @@ FROM_HERE, base::BindOnce(&WiFiService::SetProperties, base::Unretained(wifi_service_.get()), guid, - std::move(properties), error), + base::DictionaryValue::From( + base::Value::ToUniquePtrValue(std::move(properties))), + error), base::BindOnce(&NetworkingPrivateServiceClient::AfterSetProperties, weak_factory_.GetWeakPtr(), service_callbacks->id, base::Owned(error))); @@ -201,7 +203,7 @@ void NetworkingPrivateServiceClient::CreateNetwork( bool shared, - std::unique_ptr<base::DictionaryValue> properties, + base::Value properties, StringCallback success_callback, FailureCallback failure_callback) { ServiceCallbacks* service_callbacks = AddServiceCallbacks(); @@ -215,7 +217,9 @@ FROM_HERE, base::BindOnce(&WiFiService::CreateNetwork, base::Unretained(wifi_service_.get()), shared, - std::move(properties), network_guid, error), + base::DictionaryValue::From( + base::Value::ToUniquePtrValue(std::move(properties))), + network_guid, error), base::BindOnce(&NetworkingPrivateServiceClient::AfterCreateNetwork, weak_factory_.GetWeakPtr(), service_callbacks->id, base::Owned(network_guid), base::Owned(error))); @@ -346,14 +350,12 @@ return device_state_list; } -std::unique_ptr<base::DictionaryValue> -NetworkingPrivateServiceClient::GetGlobalPolicy() { - return std::make_unique<base::DictionaryValue>(); +base::Value NetworkingPrivateServiceClient::GetGlobalPolicy() { + return base::Value(base::Value::Type::DICTIONARY); } -std::unique_ptr<base::DictionaryValue> -NetworkingPrivateServiceClient::GetCertificateLists() { - return std::make_unique<base::DictionaryValue>(); +base::Value NetworkingPrivateServiceClient::GetCertificateLists() { + return base::Value(base::Value::Type::DICTIONARY); } bool NetworkingPrivateServiceClient::EnableNetworkType( @@ -401,7 +403,7 @@ } else { DCHECK(!service_callbacks->get_properties_callback.is_null()); std::move(service_callbacks->get_properties_callback) - .Run(std::move(properties)); + .Run(std::move(*properties)); } RemoveServiceCallbacks(callback_id); }
diff --git a/extensions/browser/api/networking_private/networking_private_service_client.h b/extensions/browser/api/networking_private/networking_private_service_client.h index 66bf5940..90fcdfa 100644 --- a/extensions/browser/api/networking_private/networking_private_service_client.h +++ b/extensions/browser/api/networking_private/networking_private_service_client.h
@@ -57,12 +57,12 @@ DictionaryCallback success_callback, FailureCallback failure_callback) override; void SetProperties(const std::string& guid, - std::unique_ptr<base::DictionaryValue> properties_dict, + base::Value properties_dict, bool allow_set_shared_config, VoidCallback success_callback, FailureCallback failure_callback) override; void CreateNetwork(bool shared, - std::unique_ptr<base::DictionaryValue> properties_dict, + base::Value properties_dict, StringCallback success_callback, FailureCallback failure_callback) override; void ForgetNetwork(const std::string& guid, @@ -101,8 +101,8 @@ FailureCallback failure_callback) override; base::Value GetEnabledNetworkTypes() override; std::unique_ptr<DeviceStateList> GetDeviceStateList() override; - std::unique_ptr<base::DictionaryValue> GetGlobalPolicy() override; - std::unique_ptr<base::DictionaryValue> GetCertificateLists() override; + base::Value GetGlobalPolicy() override; + base::Value GetCertificateLists() override; bool EnableNetworkType(const std::string& type) override; bool DisableNetworkType(const std::string& type) override; bool RequestScan(const std::string& type) override;
diff --git a/extensions/browser/disable_reason.h b/extensions/browser/disable_reason.h index 622b56d..6b3175df 100644 --- a/extensions/browser/disable_reason.h +++ b/extensions/browser/disable_reason.h
@@ -51,8 +51,10 @@ DISABLE_REINSTALL = 1 << 19, // Disabled by Safe Browsing extension allowlist enforcement. DISABLE_NOT_ALLOWLISTED = 1 << 20, + // Disabled by Ash extension keep-list enforcement. + DISABLE_NOT_ASH_KEEPLISTED = 1 << 21, // This should always be the last value. - DISABLE_REASON_LAST = 1LL << 21, + DISABLE_REASON_LAST = 1LL << 22, }; static_assert(DISABLE_REASON_LAST - 1 <= std::numeric_limits<int>::max(),
diff --git a/extensions/common/constants.h b/extensions/common/constants.h index e664beb..29aa595 100644 --- a/extensions/common/constants.h +++ b/extensions/common/constants.h
@@ -173,10 +173,11 @@ kSourceIntentUrl = 23, // App launch triggered by a URL. kSourceRunOnOsLogin = 24, // App launched during OS login. kSourceProtocolHandler = 25, // App launch via protocol handler. + kSourceReparenting = 26, // APP launch via reparenting. // Add any new values above this one, and update kMaxValue to the highest // enumerator value. - kMaxValue = kSourceProtocolHandler, + kMaxValue = kSourceReparenting, }; // This enum is used for the launch type the user wants to use for an
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 84990aa..fe0c333 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -89ba9b634f50f974c54d114a7548d8c043870144 \ No newline at end of file +6ac8818431d10aaf0462a145cd2fefae1a0575f6 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 4ea7110..6d89c93 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -4a413dd6d650cde748ee73abc77d52bb6034e9cc \ No newline at end of file +763576587bb863e5b8d7da0a28adeb0f888b0e5e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 161ef21..5e16a612 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -6d6a744a9c94fe19a936202d6a74d48b0ffc7962 \ No newline at end of file +d87293f396192b540e6168c136fb7537a74fcf84 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index b4caaf94..02e3f903 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -ac80c785736ba77853ded9a80e60f270f167f22d \ No newline at end of file +a4baf0add99eaf58311d8ee4ffee6ca8b08b0f5b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 index 7e3b2c4..19c34e8 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -53fd39d3fb9b5f9e166485ae14a54882e2af9881 \ No newline at end of file +a812241f30d4e58f3640044604bb51f5782c7d98 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 index 911788d..bb8324e 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -c74acccb77b44199b91d20b9fc194698d6455600 \ No newline at end of file +9f097a6caba590741df3bb1ef890b39f8d828ad0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 9720c84..443867d8 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -c2b1248388325b67feed59e65a225a879baa075c \ No newline at end of file +ba2fdc7374942f92b3269e8d2217c0fd546620f4 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index ee831f6..e1852539 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -ccb3852b2f5719e96b86b7c5774f5c8b8ec45249 \ No newline at end of file +703aea367f839b9c0a752e8cbe5e9c7b3c9b7b2b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index a47ccec..c6aad7b 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -906a4084db29f7aa629d585e8f8db721cc33af8b \ No newline at end of file +b0d22bad112ceeebb5d3a1abab07dbcb32433a79 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index 996c547..a9eda4a6 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -2da0638d73f0f36a6a2e4ee3d17d8da7d6517e74 \ No newline at end of file +09954c7f2aef48cc6d5e131bcc3482b147bf996c \ No newline at end of file
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h index 0fb3c1e6..aa93dd3 100644 --- a/ipc/ipc_channel.h +++ b/ipc/ipc_channel.h
@@ -231,7 +231,7 @@ // deleted once the contents of the Message have been sent. bool Send(Message* message) override = 0; -#if !defined(OS_NACL_SFI) +#if !defined(OS_NACL) // Generates a channel ID that's non-predictable and unique. static std::string GenerateUniqueRandomChannelID(); #endif
diff --git a/ipc/ipc_channel_common.cc b/ipc/ipc_channel_common.cc index 8990eee6b..c02a071 100644 --- a/ipc/ipc_channel_common.cc +++ b/ipc/ipc_channel_common.cc
@@ -33,7 +33,7 @@ const IPC::ChannelHandle& channel_handle, Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) return Channel::Create(channel_handle, Channel::MODE_CLIENT, listener); #else DCHECK(channel_handle.is_mojo_channel_handle()); @@ -50,7 +50,7 @@ const IPC::ChannelHandle& channel_handle, Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) return Channel::Create(channel_handle, Channel::MODE_SERVER, listener); #else DCHECK(channel_handle.is_mojo_channel_handle());
diff --git a/ipc/ipc_channel_factory.cc b/ipc/ipc_channel_factory.cc index 8d7291b..d5587ae 100644 --- a/ipc/ipc_channel_factory.cc +++ b/ipc/ipc_channel_factory.cc
@@ -3,7 +3,9 @@ // found in the LICENSE file. #include "ipc/ipc_channel_factory.h" + #include "base/memory/ptr_util.h" +#include "build/build_config.h" #include "ipc/ipc_channel_mojo.h" #include "mojo/public/cpp/bindings/lib/message_quota_checker.h" @@ -26,7 +28,7 @@ PlatformChannelFactory& operator=(const PlatformChannelFactory&) = delete; std::unique_ptr<Channel> BuildChannel(Listener* listener) override { -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) return Channel::Create(handle_, mode_, listener); #else DCHECK(handle_.is_mojo_channel_handle());
diff --git a/ipc/ipc_channel_handle.h b/ipc/ipc_channel_handle.h index 58904ac..c68d784b 100644 --- a/ipc/ipc_channel_handle.h +++ b/ipc/ipc_channel_handle.h
@@ -8,15 +8,15 @@ #include "build/build_config.h" #include "mojo/public/cpp/system/message_pipe.h" -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) #include "base/file_descriptor_posix.h" -#endif // defined (OS_NACL_SFI) +#endif // defined (OS_NACL) namespace IPC { // Note that serialization for this object is defined in the ParamTraits // template specialization in ipc_message_utils.h. -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) struct ChannelHandle { ChannelHandle() {} explicit ChannelHandle(const base::FileDescriptor& s) : socket(s) {} @@ -32,7 +32,7 @@ mojo::MessagePipeHandle mojo_handle; }; -#endif // defined(OS_NACL_SFI) +#endif // defined(OS_NACL) } // namespace IPC
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc index 147793e..5d1ed41 100644 --- a/ipc/ipc_message_utils.cc +++ b/ipc/ipc_message_utils.cc
@@ -1326,7 +1326,7 @@ void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m, const param_type& p) { -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) WriteParam(m, p.socket); #else WriteParam(m, p.mojo_handle); @@ -1336,7 +1336,7 @@ bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m, base::PickleIterator* iter, param_type* r) { -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) return ReadParam(m, iter, &r->socket); #else return ReadParam(m, iter, &r->mojo_handle); @@ -1346,7 +1346,7 @@ void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p, std::string* l) { l->append("ChannelHandle("); -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) ParamTraits<base::FileDescriptor>::Log(p.socket, l); #else LogParam(p.mojo_handle, l);
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index 2c5c2e06..3a544df 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -136,8 +136,6 @@ "data_buffer.h", "data_source.cc", "data_source.h", - "decode_status.cc", - "decode_status.h", "decoder.cc", "decoder.h", "decoder_buffer.cc", @@ -146,6 +144,8 @@ "decoder_buffer_queue.h", "decoder_factory.cc", "decoder_factory.h", + "decoder_status.cc", + "decoder_status.h", "decrypt_config.cc", "decrypt_config.h", "decryptor.cc",
diff --git a/media/base/android/media_codec_loop.h b/media/base/android/media_codec_loop.h index 0928d8a..7427df5 100644 --- a/media/base/android/media_codec_loop.h +++ b/media/base/android/media_codec_loop.h
@@ -17,7 +17,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "media/base/android/media_codec_bridge.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/encryption_scheme.h" #include "media/base/media_export.h" #include "media/base/subsample_entry.h"
diff --git a/media/base/audio_decoder.h b/media/base/audio_decoder.h index 252f356..fea0a13 100644 --- a/media/base/audio_decoder.h +++ b/media/base/audio_decoder.h
@@ -9,12 +9,11 @@ #include "base/memory/ref_counted.h" #include "media/base/audio_decoder_config.h" #include "media/base/channel_layout.h" -#include "media/base/decode_status.h" #include "media/base/decoder.h" #include "media/base/decoder_buffer.h" +#include "media/base/decoder_status.h" #include "media/base/media_export.h" #include "media/base/pipeline_status.h" -#include "media/base/status.h" #include "media/base/waiting.h" namespace media { @@ -25,7 +24,7 @@ class MEDIA_EXPORT AudioDecoder : public Decoder { public: // Callback for Decoder initialization. - using InitCB = base::OnceCallback<void(Status)>; + using InitCB = base::OnceCallback<void(DecoderStatus)>; // Callback for AudioDecoder to return a decoded frame whenever it becomes // available. Only non-EOS frames should be returned via this callback. @@ -37,7 +36,7 @@ // decode was aborted, which does not necessarily indicate an error. For // example, a Reset() can trigger this. Any other status code indicates that // the decoder encountered an error, and must be reset. - using DecodeCB = base::OnceCallback<void(Status)>; + using DecodeCB = base::OnceCallback<void(DecoderStatus)>; AudioDecoder();
diff --git a/media/base/decode_status.cc b/media/base/decode_status.cc deleted file mode 100644 index b6f46f3..0000000 --- a/media/base/decode_status.cc +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/base/decode_status.h" - -#include <ostream> - -#include "base/trace_event/trace_event.h" -#include "media/base/status.h" - -namespace media { - -const char* GetDecodeStatusString(DecodeStatus status) { - switch (status) { - case DecodeStatus::OK: - return "DecodeStatus::OK"; - case DecodeStatus::ABORTED: - return "DecodeStatus::ABORTED"; - case DecodeStatus::DECODE_ERROR: - return "DecodeStatus::DECODE_ERROR"; - default: - // TODO(liberato): Temporary while converting to media::Status. This - // fn should go away. - return "DecodeStatus::UNKNOWN_ERROR"; - } - - NOTREACHED(); - return ""; -} - -// static -bool ScopedDecodeTrace::IsEnabled() { - bool enable_decode_traces = false; - TRACE_EVENT_CATEGORY_GROUP_ENABLED("media", &enable_decode_traces); - return enable_decode_traces; -} - -ScopedDecodeTrace::ScopedDecodeTrace(const char* trace_name, - bool is_key_frame, - base::TimeDelta timestamp) - : trace_name_(trace_name) { - DCHECK(trace_name_); - TRACE_EVENT_NESTABLE_ASYNC_BEGIN2("media", trace_name_, TRACE_ID_LOCAL(this), - "is_key_frame", is_key_frame, - "timestamp_us", timestamp.InMicroseconds()); -} - -ScopedDecodeTrace::ScopedDecodeTrace(const char* trace_name, - const DecoderBuffer& buffer) - : trace_name_(trace_name) { - DCHECK(trace_name_); - TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( - "media", trace_name_, TRACE_ID_LOCAL(this), "decoder_buffer", - buffer.AsHumanReadableString(/*verbose=*/true)); -} - -ScopedDecodeTrace::~ScopedDecodeTrace() { - if (!closed_) - EndTrace(DecodeStatus::ABORTED); -} - -void ScopedDecodeTrace::EndTrace(const Status& status) { - DCHECK(!closed_); - closed_ = true; - TRACE_EVENT_NESTABLE_ASYNC_END1("media", trace_name_, TRACE_ID_LOCAL(this), - "status", - GetDecodeStatusString(status.code())); -} - -} // namespace media
diff --git a/media/base/decode_status.h b/media/base/decode_status.h deleted file mode 100644 index 0f05be2..0000000 --- a/media/base/decode_status.h +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_BASE_DECODE_STATUS_H_ -#define MEDIA_BASE_DECODE_STATUS_H_ - -#include <iosfwd> - -#include "media/base/decoder_buffer.h" -#include "media/base/media_export.h" -#include "media/base/status.h" -#include "media/base/status_codes.h" - -namespace media { - -// TODO(crbug.com/1129662): This is temporary, to allow DecodeStatus::OK to -// work, while we replace DecodeStatus with actual status codes. -using DecodeStatus = StatusCode; - -MEDIA_EXPORT const char* GetDecodeStatusString(DecodeStatus status); - -// Helper class for ensuring that Decode() traces are properly unique and closed -// if the Decode is aborted via a WeakPtr invalidation. We use the |this| -// pointer of the ScopedDecodeTrace object itself as the id. Since the callback -// owns the class it's guaranteed to be unique. -class MEDIA_EXPORT ScopedDecodeTrace { - public: - // Returns true if tracing is enabled for the media category. If false, - // clients should avoid creating ScopedDecodeTrace objects. - static bool IsEnabled(); - - // Begins an asynchronous trace with the given name and properties. Providing - // the DecoderBuffer itself yields the most information in the trace. - ScopedDecodeTrace(const char* trace_name, const DecoderBuffer& buffer); - ScopedDecodeTrace(const char* trace_name, - bool is_key_frame, - base::TimeDelta timestamp); - - ScopedDecodeTrace(const ScopedDecodeTrace&) = delete; - ScopedDecodeTrace& operator=(const ScopedDecodeTrace&) = delete; - - ~ScopedDecodeTrace(); - - // Completes the Decode() trace with the given status. - void EndTrace(const Status& status); - - private: - const char* trace_name_; - bool closed_ = false; -}; - -} // namespace media - -#endif // MEDIA_BASE_DECODE_STATUS_H_
diff --git a/media/base/decoder_status.cc b/media/base/decoder_status.cc new file mode 100644 index 0000000..869b3bc --- /dev/null +++ b/media/base/decoder_status.cc
@@ -0,0 +1,85 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/decoder_status.h" + +#include <sstream> + +#include "base/trace_event/trace_event.h" +#include "media/base/status.h" + +namespace media { +namespace { + +const std::string GetDecodeStatusString(const DecoderStatus& status) { +#define STRINGIFY(V) \ + case V: \ + return #V + switch (status.code()) { + STRINGIFY(DecoderStatus::Codes::kOk); + STRINGIFY(DecoderStatus::Codes::kFailed); + STRINGIFY(DecoderStatus::Codes::kAborted); + STRINGIFY(DecoderStatus::Codes::kInvalidArgument); + STRINGIFY(DecoderStatus::Codes::kInterrupted); + STRINGIFY(DecoderStatus::Codes::kNotInitialized); + STRINGIFY(DecoderStatus::Codes::kMissingCDM); + STRINGIFY(DecoderStatus::Codes::kFailedToGetVideoFrame); + STRINGIFY(DecoderStatus::Codes::kPlatformDecodeFailure); + STRINGIFY(DecoderStatus::Codes::kMalformedBitstream); + STRINGIFY(DecoderStatus::Codes::kFailedToGetDecoderBuffer); + STRINGIFY(DecoderStatus::Codes::kDecoderStreamInErrorState); + STRINGIFY(DecoderStatus::Codes::kDecoderStreamReinitFailed); + STRINGIFY(DecoderStatus::Codes::kDecoderStreamDemuxerError); + STRINGIFY(DecoderStatus::Codes::kUnsupportedProfile); + STRINGIFY(DecoderStatus::Codes::kUnsupportedCodec); + STRINGIFY(DecoderStatus::Codes::kUnsupportedConfig); + STRINGIFY(DecoderStatus::Codes::kUnsupportedEncryptionMode); + STRINGIFY(DecoderStatus::Codes::kCantChangeCodec); + STRINGIFY(DecoderStatus::Codes::kFailedToCreateDecoder); + STRINGIFY(DecoderStatus::Codes::kKeyFrameRequired); + } +#undef STRINGIFY +} + +} // namespace + +// static +bool ScopedDecodeTrace::IsEnabled() { + bool enable_decode_traces = false; + TRACE_EVENT_CATEGORY_GROUP_ENABLED("media", &enable_decode_traces); + return enable_decode_traces; +} + +ScopedDecodeTrace::ScopedDecodeTrace(const char* trace_name, + bool is_key_frame, + base::TimeDelta timestamp) + : trace_name_(trace_name) { + DCHECK(trace_name_); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2("media", trace_name_, TRACE_ID_LOCAL(this), + "is_key_frame", is_key_frame, + "timestamp_us", timestamp.InMicroseconds()); +} + +ScopedDecodeTrace::ScopedDecodeTrace(const char* trace_name, + const DecoderBuffer& buffer) + : trace_name_(trace_name) { + DCHECK(trace_name_); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "media", trace_name_, TRACE_ID_LOCAL(this), "decoder_buffer", + buffer.AsHumanReadableString(/*verbose=*/true)); +} + +ScopedDecodeTrace::~ScopedDecodeTrace() { + if (!closed_) + EndTrace(DecoderStatus::Codes::kAborted); +} + +void ScopedDecodeTrace::EndTrace(const DecoderStatus& status) { + DCHECK(!closed_); + closed_ = true; + TRACE_EVENT_NESTABLE_ASYNC_END1("media", trace_name_, TRACE_ID_LOCAL(this), + "status", GetDecodeStatusString(status)); +} + +} // namespace media
diff --git a/media/base/decoder_status.h b/media/base/decoder_status.h new file mode 100644 index 0000000..5618777 --- /dev/null +++ b/media/base/decoder_status.h
@@ -0,0 +1,80 @@ +// Copyright 2021 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 MEDIA_BASE_DECODER_STATUS_H_ +#define MEDIA_BASE_DECODER_STATUS_H_ + +#include "media/base/decoder_buffer.h" +#include "media/base/status.h" + +namespace media { + +struct DecoderStatusTraits { + enum class Codes : StatusCodeType { + // Shared & General errors + kOk = 0, + kFailed = 1, + kAborted = 2, // TODO(*) document _why_ aborted is a thing + kInvalidArgument = 3, + kInterrupted = 4, + + // Reasons for failing to decode + kNotInitialized = 100, + kMissingCDM = 101, + kFailedToGetVideoFrame = 102, + kPlatformDecodeFailure = 103, + kMalformedBitstream = 104, + kFailedToGetDecoderBuffer = 107, + kDecoderStreamInErrorState = 108, + kDecoderStreamReinitFailed = 109, + kDecoderStreamDemuxerError = 110, + kKeyFrameRequired = 111, + + // Reasons for failing to initialize + kUnsupportedProfile = 200, + kUnsupportedCodec = 201, + kUnsupportedConfig = 202, + kUnsupportedEncryptionMode = 203, + kCantChangeCodec = 204, + kFailedToCreateDecoder = 205, + }; + static constexpr StatusGroupType Group() { return "DecoderStatusCodes"; } + static constexpr Codes DefaultEnumValue() { return Codes::kOk; } +}; + +using DecoderStatus = TypedStatus<DecoderStatusTraits>; + +// Helper class for ensuring that Decode() traces are properly unique and closed +// if the Decode is aborted via a WeakPtr invalidation. We use the |this| +// pointer of the ScopedDecodeTrace object itself as the id. Since the callback +// owns the class it's guaranteed to be unique. +class MEDIA_EXPORT ScopedDecodeTrace { + public: + // Returns true if tracing is enabled for the media category. If false, + // clients should avoid creating ScopedDecodeTrace objects. + static bool IsEnabled(); + + // Begins an asynchronous trace with the given name and properties. Providing + // the DecoderBuffer itself yields the most information in the trace. + ScopedDecodeTrace(const char* trace_name, const DecoderBuffer& buffer); + ScopedDecodeTrace(const char* trace_name, + bool is_key_frame, + base::TimeDelta timestamp); + + ScopedDecodeTrace(const ScopedDecodeTrace&) = delete; + ScopedDecodeTrace& operator=(const ScopedDecodeTrace&) = delete; + + ~ScopedDecodeTrace(); + + // Completes the Decode() trace with the given status. + void EndTrace(const DecoderStatus& status); + + private: + const char* trace_name_; + bool closed_ = false; +}; + +} // namespace media + +#endif // MEDIA_BASE_DECODER_STATUS_H_
diff --git a/media/base/ipc/media_param_traits_macros.h b/media/base/ipc/media_param_traits_macros.h index 633635de..1fb3d2d 100644 --- a/media/base/ipc/media_param_traits_macros.h +++ b/media/base/ipc/media_param_traits_macros.h
@@ -16,8 +16,8 @@ #include "media/base/channel_layout.h" #include "media/base/container_names.h" #include "media/base/content_decryption_module.h" -#include "media/base/decode_status.h" #include "media/base/decoder.h" +#include "media/base/decoder_status.h" #include "media/base/decrypt_config.h" #include "media/base/decryptor.h" #include "media/base/demuxer_stream.h"
diff --git a/media/base/status.h b/media/base/status.h index 965001b..aec1fe8 100644 --- a/media/base/status.h +++ b/media/base/status.h
@@ -224,7 +224,7 @@ } const std::string group() const { - return data_ ? data_->group : Traits::Group(); + return data_ ? data_->group : std::string(Traits::Group()); } const std::string& message() const {
diff --git a/media/base/status_codes.h b/media/base/status_codes.h index 2c9bff8..98b2434 100644 --- a/media/base/status_codes.h +++ b/media/base/status_codes.h
@@ -29,29 +29,9 @@ // General errors: 0x00 kAborted = 0x0001, kInvalidArgument = 0x0002, - kKeyFrameRequired = 0x0003, kWrappedError = 0x0004, // Decoder Errors: 0x01 - kDecoderInitializeNeverCompleted = 0x0101, - kDecoderFailedDecode = 0x0102, - kDecoderUnsupportedProfile = 0x0103, - kDecoderUnsupportedCodec = 0x0104, - kDecoderUnsupportedConfig = 0x0105, - kEncryptedContentUnsupported = 0x0106, - kClearContentUnsupported = 0x0107, - kDecoderMissingCdmForEncryptedContent = 0x0108, - kDecoderInitializationFailed = 0x0109, // Prefer this one. - kDecoderFailedInitialization = kDecoderInitializationFailed, // Do not use. - kDecoderCantChangeCodec = 0x010A, - kDecoderCreationFailed = 0x010B, // Prefer this one. - kDecoderFailedCreation = kDecoderCreationFailed, // Do not use. - kInitializationUnspecifiedFailure = 0x010C, - kDecoderVideoFrameConstructionFailed = 0x010D, - kMakeContextCurrentFailed = 0x010E, - // This is a temporary error for use only by existing code during the - // DecodeStatus => Status conversion. - kDecodeErrorDoNotUse = 0x010F, // MojoDecoder Errors: 0x04 kMojoDecoderNoWrappedDecoder = 0x0401, @@ -110,19 +90,6 @@ // proper status. kDecoderStreamDemuxerError = 0x0B02, - // DecodeStatus temporary codes. These names were chosen to match the - // DecodeStatus enum, so that un-converted code can DecodeStatus::OK/etc. - // Note that OK must result in Status::is_ok(), since converted code will - // check for it. These will be removed when the conversion is complete. - // - // DO NOT ADD NEW USES OF OK/ABORTED/DECODE_ERROR. - OK = kOk, // Everything went as planned. - // Read aborted due to Reset() during pending read. - ABORTED = kAborted, // Read aborted due to Reset() during pending read. - // Decoder returned decode error. Note: Prefixed by DECODE_ - // since ERROR is a reserved name (special macro) on Windows. - DECODE_ERROR = kDecodeErrorDoNotUse, - // Special codes kGenericErrorPleaseRemove = 0x7999, kCodeOnlyForTesting = std::numeric_limits<StatusCodeType>::max(),
diff --git a/media/base/test_helpers.h b/media/base/test_helpers.h index 04da5a9b..f257a1e 100644 --- a/media/base/test_helpers.h +++ b/media/base/test_helpers.h
@@ -15,6 +15,7 @@ #include "base/strings/stringprintf.h" #include "media/base/audio_parameters.h" #include "media/base/channel_layout.h" +#include "media/base/decoder_status.h" #include "media/base/demuxer_stream.h" #include "media/base/media_log.h" #include "media/base/pipeline_status.h" @@ -261,7 +262,7 @@ // True if and only if the Status would be interpreted as an error from a decode // callback (not okay, not aborted). MATCHER(IsDecodeErrorStatus, "") { - return !arg.is_ok() && arg.code() != StatusCode::kAborted; + return !arg.is_ok() && arg.code() != DecoderStatus::Codes::kAborted; } // Compares two {Audio|Video}DecoderConfigs
diff --git a/media/base/video_decoder.h b/media/base/video_decoder.h index 892bce6..7eb5a98f 100644 --- a/media/base/video_decoder.h +++ b/media/base/video_decoder.h
@@ -6,8 +6,8 @@ #define MEDIA_BASE_VIDEO_DECODER_H_ #include "base/memory/ref_counted.h" -#include "media/base/decode_status.h" #include "media/base/decoder.h" +#include "media/base/decoder_status.h" #include "media/base/media_export.h" #include "media/base/pipeline_status.h" #include "media/base/waiting.h" @@ -23,7 +23,7 @@ class MEDIA_EXPORT VideoDecoder : public Decoder { public: // Callback for Decoder initialization. - using InitCB = base::OnceCallback<void(Status)>; + using InitCB = base::OnceCallback<void(DecoderStatus)>; // Callback for VideoDecoder to return a decoded frame whenever it becomes // available. Only non-EOS frames should be returned via this callback. @@ -35,7 +35,7 @@ // decode was aborted, which does not necessarily indicate an error. For // example, a Reset() can trigger this. Any other status code indicates that // the decoder encountered an error, and must be reset. - using DecodeCB = base::OnceCallback<void(Status)>; + using DecodeCB = base::OnceCallback<void(DecoderStatus)>; VideoDecoder(); VideoDecoder(const VideoDecoder&) = delete;
diff --git a/media/base/video_thumbnail_decoder.cc b/media/base/video_thumbnail_decoder.cc index ab3033cc..11cd0cac 100644 --- a/media/base/video_thumbnail_decoder.cc +++ b/media/base/video_thumbnail_decoder.cc
@@ -36,7 +36,7 @@ base::DoNothing()); } -void VideoThumbnailDecoder::OnVideoDecoderInitialized(Status status) { +void VideoThumbnailDecoder::OnVideoDecoderInitialized(DecoderStatus status) { if (!status.is_ok()) { NotifyComplete(nullptr); return; @@ -50,7 +50,7 @@ weak_factory_.GetWeakPtr())); } -void VideoThumbnailDecoder::OnVideoBufferDecoded(Status status) { +void VideoThumbnailDecoder::OnVideoBufferDecoded(DecoderStatus status) { if (!status.is_ok()) { NotifyComplete(nullptr); return; @@ -62,7 +62,7 @@ weak_factory_.GetWeakPtr())); } -void VideoThumbnailDecoder::OnEosBufferDecoded(Status status) { +void VideoThumbnailDecoder::OnEosBufferDecoded(DecoderStatus status) { if (!status.is_ok()) NotifyComplete(nullptr); }
diff --git a/media/base/video_thumbnail_decoder.h b/media/base/video_thumbnail_decoder.h index af70aaf2..4d83e76 100644 --- a/media/base/video_thumbnail_decoder.h +++ b/media/base/video_thumbnail_decoder.h
@@ -39,9 +39,9 @@ void Start(VideoFrameCallback video_frame_callback); private: - void OnVideoDecoderInitialized(Status status); - void OnVideoBufferDecoded(Status status); - void OnEosBufferDecoded(Status status); + void OnVideoDecoderInitialized(DecoderStatus status); + void OnVideoBufferDecoded(DecoderStatus status); + void OnEosBufferDecoded(DecoderStatus status); // Called when the output frame is generated. void OnVideoFrameDecoded(scoped_refptr<VideoFrame> frame);
diff --git a/media/base/video_thumbnail_decoder_unittest.cc b/media/base/video_thumbnail_decoder_unittest.cc index be746fc..ed7b4ef 100644 --- a/media/base/video_thumbnail_decoder_unittest.cc +++ b/media/base/video_thumbnail_decoder_unittest.cc
@@ -88,11 +88,11 @@ TEST_F(VideoThumbnailDecoderTest, Success) { auto expected_frame = CreateFrame(); EXPECT_CALL(*mock_video_decoder(), Initialize_(_, _, _, _, _, _)) - .WillOnce(DoAll(RunOnceCallback<3>(OkStatus()), + .WillOnce(DoAll(RunOnceCallback<3>(DecoderStatus::Codes::kOk), RunCallback<4>(expected_frame))); EXPECT_CALL(*mock_video_decoder(), Decode_(_, _)) .Times(2) - .WillRepeatedly(RunOnceCallback<1>(DecodeStatus::OK)); + .WillRepeatedly(RunOnceCallback<1>(DecoderStatus::Codes::kOk)); Start(); EXPECT_TRUE(frame()); @@ -102,7 +102,7 @@ TEST_F(VideoThumbnailDecoderTest, InitializationFailed) { auto expected_frame = CreateFrame(); EXPECT_CALL(*mock_video_decoder(), Initialize_(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<3>(StatusCode::kCodeOnlyForTesting)); + .WillOnce(RunOnceCallback<3>(DecoderStatus::Codes::kFailed)); Start(); EXPECT_FALSE(frame()); @@ -112,9 +112,9 @@ TEST_F(VideoThumbnailDecoderTest, DecodingFailed) { auto expected_frame = CreateFrame(); EXPECT_CALL(*mock_video_decoder(), Initialize_(_, _, _, _, _, _)) - .WillOnce(RunOnceCallback<3>(OkStatus())); + .WillOnce(RunOnceCallback<3>(DecoderStatus::Codes::kOk)); EXPECT_CALL(*mock_video_decoder(), Decode_(_, _)) - .WillOnce(RunOnceCallback<1>(DecodeStatus::DECODE_ERROR)); + .WillOnce(RunOnceCallback<1>(DecoderStatus::Codes::kFailed)); Start(); EXPECT_FALSE(frame());
diff --git a/media/cast/sender/h264_vt_encoder_unittest.cc b/media/cast/sender/h264_vt_encoder_unittest.cc index 6cfa165..80a349b 100644 --- a/media/cast/sender/h264_vt_encoder_unittest.cc +++ b/media/cast/sender/h264_vt_encoder_unittest.cc
@@ -59,7 +59,7 @@ // See comment in end2end_unittest.cc for details on this value. const double kVideoAcceptedPSNR = 38.0; -void SaveDecoderInitResult(bool* out_result, ::media::Status in_result) { +void SaveDecoderInitResult(bool* out_result, DecoderStatus in_result) { *out_result = in_result.is_ok(); } @@ -160,7 +160,7 @@ ++count_frames_checked_; } - void DecodeDone(Status status) { EXPECT_TRUE(status.is_ok()); } + void DecodeDone(DecoderStatus status) { EXPECT_TRUE(status.is_ok()); } int count_frames_checked() const { return count_frames_checked_; }
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc index bbcd531..6c80b2d5 100644 --- a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc +++ b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
@@ -23,7 +23,7 @@ #include "base/run_loop.h" #include "base/task/single_thread_task_executor.h" #include "base/threading/thread_task_runner_handle.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/media_switches.h" #include "media/base/media_util.h" #include "media/cdm/cdm_type_conversion.h" @@ -186,7 +186,7 @@ ~VideoDecoderAdapter() final = default; // CdmVideoDecoder implementation. - Status Initialize(const cdm::VideoDecoderConfig_3& config) final { + DecoderStatus Initialize(const cdm::VideoDecoderConfig_3& config) final { auto clear_config = ToClearMediaVideoDecoderConfig(config); DVLOG(1) << __func__ << ": " << clear_config.AsHumanReadableString(); DCHECK(!last_init_result_.has_value()); @@ -244,7 +244,7 @@ // "kAborted" shouldn't happen during a sync decode, so treat it as an // error. - DCHECK_NE(decode_status.code(), StatusCode::kAborted); + DCHECK_NE(decode_status.code(), DecoderStatus::Codes::kAborted); if (!decode_status.is_ok()) return cdm::kDecodeError; @@ -261,7 +261,7 @@ } private: - void OnInitialized(base::OnceClosure quit_closure, Status status) { + void OnInitialized(base::OnceClosure quit_closure, DecoderStatus status) { DVLOG(1) << __func__ << " success = " << status.is_ok(); DCHECK(!last_init_result_.has_value()); last_init_result_ = std::move(status); @@ -282,7 +282,7 @@ std::move(quit_closure).Run(); } - void OnDecoded(base::OnceClosure quit_closure, Status decode_status) { + void OnDecoded(base::OnceClosure quit_closure, DecoderStatus decode_status) { DCHECK(!last_decode_status_.has_value()); last_decode_status_ = std::move(decode_status); std::move(quit_closure).Run(); @@ -293,8 +293,8 @@ // Results of |video_decoder_| operations. Set iff the callback of the // operation has been called. - absl::optional<Status> last_init_result_; - absl::optional<Status> last_decode_status_; + absl::optional<DecoderStatus> last_init_result_; + absl::optional<DecoderStatus> last_decode_status_; // Queue of decoded video frames. using VideoFrameQueue = base::queue<scoped_refptr<VideoFrame>>;
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.h b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.h index 7346d330..133af1fc 100644 --- a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.h +++ b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.h
@@ -11,7 +11,7 @@ #include "base/memory/ref_counted.h" #include "media/base/decoder_buffer.h" -#include "media/base/status.h" +#include "media/base/decoder_status.h" #include "media/cdm/api/content_decryption_module.h" namespace media { @@ -22,8 +22,8 @@ public: using CdmVideoFrame = cdm::VideoFrame_2; - virtual ~CdmVideoDecoder() {} - virtual Status Initialize(const cdm::VideoDecoderConfig_3& config) = 0; + virtual ~CdmVideoDecoder() = default; + virtual DecoderStatus Initialize(const cdm::VideoDecoderConfig_3& config) = 0; virtual void Deinitialize() = 0; virtual void Reset() = 0; virtual cdm::Status Decode(scoped_refptr<DecoderBuffer> buffer,
diff --git a/media/filters/android/media_codec_audio_decoder.cc b/media/filters/android/media_codec_audio_decoder.cc index e48a737e..66652fc 100644 --- a/media/filters/android/media_codec_audio_decoder.cc +++ b/media/filters/android/media_codec_audio_decoder.cc
@@ -46,7 +46,7 @@ if (media_crypto_context_) media_crypto_context_->SetMediaCryptoReadyCB(base::NullCallback()); - ClearInputQueue(DecodeStatus::ABORTED); + ClearInputQueue(DecoderStatus::Codes::kAborted); } AudioDecoderType MediaCodecAudioDecoder::GetDecoderType() const { @@ -66,7 +66,7 @@ // Initialization and reinitialization should not be called during pending // decode. DCHECK(input_queue_.empty()); - ClearInputQueue(DecodeStatus::ABORTED); + ClearInputQueue(DecoderStatus::Codes::kAborted); is_passthrough_ = MediaCodecUtil::IsPassthroughAudioFormat(config.codec()); sample_format_ = kSampleFormatS16; @@ -80,8 +80,7 @@ if (state_ == STATE_ERROR) { DVLOG(1) << "Decoder is in error state."; - BindToCurrentLoop(std::move(init_cb)) - .Run(StatusCode::kDecoderFailedInitialization); + BindToCurrentLoop(std::move(init_cb)).Run(DecoderStatus::Codes::kFailed); return; } @@ -96,7 +95,7 @@ if (!is_codec_supported) { DVLOG(1) << "Unsuported codec " << GetCodecName(config.codec()); BindToCurrentLoop(std::move(init_cb)) - .Run(StatusCode::kDecoderUnsupportedCodec); + .Run(DecoderStatus::Codes::kUnsupportedCodec); return; } @@ -114,7 +113,7 @@ "MediaCryptoContext is not supported"; SetState(STATE_ERROR); BindToCurrentLoop(std::move(init_cb)) - .Run(StatusCode::kDecoderMissingCdmForEncryptedContent); + .Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -126,13 +125,12 @@ } if (!CreateMediaCodecLoop()) { - BindToCurrentLoop(std::move(init_cb)) - .Run(StatusCode::kDecoderFailedInitialization); + BindToCurrentLoop(std::move(init_cb)).Run(DecoderStatus::Codes::kFailed); return; } SetState(STATE_READY); - BindToCurrentLoop(std::move(init_cb)).Run(OkStatus()); + BindToCurrentLoop(std::move(init_cb)).Run(DecoderStatus::Codes::kOk); } bool MediaCodecAudioDecoder::CreateMediaCodecLoop() { @@ -171,7 +169,7 @@ if (!buffer->end_of_stream() && buffer->timestamp() == kNoTimestamp) { DVLOG(2) << __func__ << " " << buffer->AsHumanReadableString() << ": no timestamp, skipping this buffer"; - std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } @@ -180,8 +178,8 @@ // We get here if an error happens in DequeueOutput() or Reset(). DVLOG(2) << __func__ << " " << buffer->AsHumanReadableString() << ": Error state, returning decode error for all buffers"; - ClearInputQueue(DecodeStatus::DECODE_ERROR); - std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR); + ClearInputQueue(DecoderStatus::Codes::kFailed); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } @@ -204,7 +202,7 @@ void MediaCodecAudioDecoder::Reset(base::OnceClosure closure) { DVLOG(2) << __func__; - ClearInputQueue(DecodeStatus::ABORTED); + ClearInputQueue(DecoderStatus::Codes::kAborted); // Flush if we can, otherwise completely recreate and reconfigure the codec. bool success = codec_loop_->TryFlush(); @@ -267,7 +265,7 @@ if (media_crypto->is_null()) { LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream."; SetState(STATE_UNINITIALIZED); - std::move(init_cb).Run(StatusCode::kDecoderMissingCdmForEncryptedContent); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -280,12 +278,12 @@ // After receiving |media_crypto_| we can configure MediaCodec. if (!CreateMediaCodecLoop()) { SetState(STATE_UNINITIALIZED); - std::move(init_cb).Run(StatusCode::kDecoderFailedInitialization); + std::move(init_cb).Run(DecoderStatus::Codes::kFailed); return; } SetState(STATE_READY); - std::move(init_cb).Run(OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); } bool MediaCodecAudioDecoder::IsAnyInputPending() const { @@ -332,11 +330,11 @@ return; std::move(input_queue_.front().second) - .Run(success ? DecodeStatus::OK : DecodeStatus::DECODE_ERROR); + .Run(success ? DecoderStatus::Codes::kOk : DecoderStatus::Codes::kFailed); input_queue_.pop_front(); } -void MediaCodecAudioDecoder::ClearInputQueue(DecodeStatus decode_status) { +void MediaCodecAudioDecoder::ClearInputQueue(DecoderStatus decode_status) { DVLOG(2) << __func__; for (auto& entry : input_queue_) @@ -354,7 +352,7 @@ void MediaCodecAudioDecoder::OnCodecLoopError() { // If the codec transitions into the error state, then so should we. SetState(STATE_ERROR); - ClearInputQueue(DecodeStatus::DECODE_ERROR); + ClearInputQueue(DecoderStatus::Codes::kFailed); } bool MediaCodecAudioDecoder::OnDecodedEos( @@ -376,7 +374,7 @@ // So, we shouldn't be in that state. So, just DCHECK here. DCHECK_NE(state_, STATE_ERROR); - std::move(input_queue_.front()).second.Run(DecodeStatus::OK); + std::move(input_queue_.front()).second.Run(DecoderStatus::Codes::kOk); input_queue_.pop_front(); return true;
diff --git a/media/filters/android/media_codec_audio_decoder.h b/media/filters/android/media_codec_audio_decoder.h index 0f1c6c3..7971cf36 100644 --- a/media/filters/android/media_codec_audio_decoder.h +++ b/media/filters/android/media_codec_audio_decoder.h
@@ -142,7 +142,7 @@ // Calls DecodeCB with |decode_status| for every frame in |input_queue| and // then clears it. - void ClearInputQueue(DecodeStatus decode_status); + void ClearInputQueue(DecoderStatus decode_status); // Helper method to change the state. void SetState(State new_state);
diff --git a/media/filters/audio_decoder_stream_unittest.cc b/media/filters/audio_decoder_stream_unittest.cc index 0f9e4bb9..7040c14 100644 --- a/media/filters/audio_decoder_stream_unittest.cc +++ b/media/filters/audio_decoder_stream_unittest.cc
@@ -98,7 +98,8 @@ config.channel_layout(), config.channels(), config.samples_per_second(), 1221, last_timestamp_))); base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(decode_cb), DecodeStatus::OK)); + FROM_HERE, + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kOk)); } void RunUntilIdle() { task_environment_.RunUntilIdle(); } @@ -109,7 +110,7 @@ EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _)) .Times(AnyNumber()) .WillRepeatedly(DoAll(SaveArg<3>(&decoder_output_cb_), - RunOnceCallback<2>(OkStatus()))); + RunOnceCallback<2>(DecoderStatus::Codes::kOk))); decoder_ = decoder.get(); std::vector<std::unique_ptr<AudioDecoder>> result;
diff --git a/media/filters/audio_decoder_unittest.cc b/media/filters/audio_decoder_unittest.cc index 06f22b1..5718906 100644 --- a/media/filters/audio_decoder_unittest.cc +++ b/media/filters/audio_decoder_unittest.cc
@@ -124,7 +124,7 @@ params_(std::get<1>(GetParam())), pending_decode_(false), pending_reset_(false), - last_decode_status_(DecodeStatus::DECODE_ERROR) { + last_decode_status_(DecoderStatus::Codes::kFailed) { switch (decoder_type_) { case FFMPEG: decoder_ = std::make_unique<FFmpegAudioDecoder>( @@ -151,7 +151,7 @@ void DecodeBuffer(scoped_refptr<DecoderBuffer> buffer) { ASSERT_FALSE(pending_decode_); pending_decode_ = true; - last_decode_status_ = DecodeStatus::DECODE_ERROR; + last_decode_status_ = DecoderStatus::Codes::kFailed; base::RunLoop run_loop; decoder_->Decode( @@ -227,7 +227,7 @@ bool success) { decoder_->Initialize(config, nullptr, base::BindOnce( - [](bool success, Status status) { + [](bool success, DecoderStatus status) { EXPECT_EQ(status.is_ok(), success); }, success), @@ -280,7 +280,7 @@ decoded_audio_.push_back(std::move(buffer)); } - void DecodeFinished(base::OnceClosure quit_closure, Status status) { + void DecodeFinished(base::OnceClosure quit_closure, DecoderStatus status) { EXPECT_TRUE(pending_decode_); EXPECT_FALSE(pending_reset_); pending_decode_ = false; @@ -353,7 +353,9 @@ const scoped_refptr<AudioBuffer>& decoded_audio(size_t i) { return decoded_audio_[i]; } - const Status& last_decode_status() const { return last_decode_status_; } + const DecoderStatus& last_decode_status() const { + return last_decode_status_; + } private: const TestAudioDecoderType decoder_type_; @@ -373,7 +375,7 @@ std::unique_ptr<AudioDecoder> decoder_; bool pending_decode_; bool pending_reset_; - Status last_decode_status_; + DecoderStatus last_decode_status_ = DecoderStatus::Codes::kOk; base::circular_deque<scoped_refptr<AudioBuffer>> decoded_audio_; base::TimeDelta start_timestamp_;
diff --git a/media/filters/dav1d_video_decoder.cc b/media/filters/dav1d_video_decoder.cc index 1633956..830b6bd 100644 --- a/media/filters/dav1d_video_decoder.cc +++ b/media/filters/dav1d_video_decoder.cc
@@ -169,13 +169,14 @@ InitCB bound_init_cb = bind_callbacks_ ? BindToCurrentLoop(std::move(init_cb)) : std::move(init_cb); if (config.is_encrypted()) { - std::move(bound_init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(bound_init_cb) + .Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } if (config.codec() != VideoCodec::kAV1) { std::move(bound_init_cb) - .Run(Status(StatusCode::kDecoderUnsupportedCodec) + .Run(DecoderStatus(DecoderStatus::Codes::kUnsupportedCodec) .WithData("codec", config.codec())); return; } @@ -211,14 +212,14 @@ // TODO(tmathmeyer) write the dav1d error into the data for the media error. if (dav1d_open(&dav1d_decoder_, &s) < 0) { - std::move(bound_init_cb).Run(StatusCode::kDecoderFailedInitialization); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kFailedToCreateDecoder); return; } config_ = config; state_ = DecoderState::kNormal; output_cb_ = output_cb; - std::move(bound_init_cb).Run(OkStatus()); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kOk); } void Dav1dVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, @@ -234,18 +235,18 @@ : std::move(decode_cb); if (state_ == DecoderState::kError) { - std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } if (!DecodeBuffer(std::move(buffer))) { state_ = DecoderState::kError; - std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } // VideoDecoderShim expects |decode_cb| call after |output_cb_|. - std::move(bound_decode_cb).Run(DecodeStatus::OK); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kOk); } void Dav1dVideoDecoder::Reset(base::OnceClosure reset_cb) {
diff --git a/media/filters/dav1d_video_decoder_unittest.cc b/media/filters/dav1d_video_decoder_unittest.cc index 61f51fc5..676a02b8 100644 --- a/media/filters/dav1d_video_decoder_unittest.cc +++ b/media/filters/dav1d_video_decoder_unittest.cc
@@ -57,7 +57,7 @@ config, true, // Use low delay so we get 1 frame out for each frame in. nullptr, base::BindOnce( - [](bool success, Status status) { + [](bool success, DecoderStatus status) { EXPECT_EQ(status.is_ok(), success); }, success), @@ -105,14 +105,14 @@ // Decodes all buffers in |input_buffers| and push all successfully decoded // output frames into |output_frames|. Returns the last decode status returned // by the decoder. - Status DecodeMultipleFrames(const InputBuffers& input_buffers) { + DecoderStatus DecodeMultipleFrames(const InputBuffers& input_buffers) { for (auto iter = input_buffers.begin(); iter != input_buffers.end(); ++iter) { - Status status = Decode(*iter); + DecoderStatus status = Decode(*iter); switch (status.code()) { - case StatusCode::kOk: + case DecoderStatus::Codes::kOk: break; - case StatusCode::kAborted: + case DecoderStatus::Codes::kAborted: NOTREACHED(); [[fallthrough]]; default: @@ -120,11 +120,11 @@ return status; } } - return StatusCode::kOk; + return DecoderStatus::Codes::kOk; } // Decodes the single compressed frame in |buffer|. - Status DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { + DecoderStatus DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { InputBuffers input_buffers; input_buffers.push_back(std::move(buffer)); return DecodeMultipleFrames(input_buffers); @@ -143,7 +143,7 @@ input_buffers.push_back(buffer); input_buffers.push_back(DecoderBuffer::CreateEOSBuffer()); - Status status = DecodeMultipleFrames(input_buffers); + DecoderStatus status = DecodeMultipleFrames(input_buffers); EXPECT_TRUE(status.is_ok()); ASSERT_EQ(2U, output_frames_.size()); @@ -159,8 +159,8 @@ output_frames_[1]->visible_rect().size().height()); } - Status Decode(scoped_refptr<DecoderBuffer> buffer) { - Status status; + DecoderStatus Decode(scoped_refptr<DecoderBuffer> buffer) { + DecoderStatus status; EXPECT_CALL(*this, DecodeDone(_)).WillOnce(testing::SaveArg<0>(&status)); decoder_->Decode(std::move(buffer), @@ -185,7 +185,7 @@ return base::MD5DigestToBase16(digest); } - MOCK_METHOD1(DecodeDone, void(Status)); + MOCK_METHOD1(DecodeDone, void(DecoderStatus)); testing::StrictMock<MockMediaLog> media_log_;
diff --git a/media/filters/decoder_selector.cc b/media/filters/decoder_selector.cc index aa9973d1..3cbaaf3 100644 --- a/media/filters/decoder_selector.cc +++ b/media/filters/decoder_selector.cc
@@ -321,9 +321,10 @@ } template <DemuxerStream::Type StreamType> -void DecoderSelector<StreamType>::OnDecoderInitializeDone(Status status) { +void DecoderSelector<StreamType>::OnDecoderInitializeDone( + DecoderStatus status) { DVLOG(2) << __func__ << ": " << decoder_->GetDecoderType() - << " success=" << std::hex << status.code(); + << " success=" << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!status.is_ok()) {
diff --git a/media/filters/decoder_selector.h b/media/filters/decoder_selector.h index 9e73a52..152785b 100644 --- a/media/filters/decoder_selector.h +++ b/media/filters/decoder_selector.h
@@ -132,7 +132,7 @@ private: void CreateDecoders(); void InitializeDecoder(); - void OnDecoderInitializeDone(Status status); + void OnDecoderInitializeDone(DecoderStatus status); void ReturnNullDecoder(); void InitializeDecryptingDemuxerStream(); void OnDecryptingDemuxerStreamInitializeDone(PipelineStatus status);
diff --git a/media/filters/decoder_selector_unittest.cc b/media/filters/decoder_selector_unittest.cc index 8bfbf8b1..4856e5d 100644 --- a/media/filters/decoder_selector_unittest.cc +++ b/media/filters/decoder_selector_unittest.cc
@@ -68,16 +68,19 @@ } } -Status IsConfigSupported(DecoderCapability capability, bool is_encrypted) { +DecoderStatus IsConfigSupported(DecoderCapability capability, + bool is_encrypted) { switch (capability) { case kAlwaysFail: - return StatusCode::kCodeOnlyForTesting; + return DecoderStatus::Codes::kFailed; case kClearOnly: - return is_encrypted ? StatusCode::kCodeOnlyForTesting : StatusCode::kOk; + return is_encrypted ? DecoderStatus::Codes::kUnsupportedEncryptionMode + : DecoderStatus::Codes::kOk; case kEncryptedOnly: - return is_encrypted ? StatusCode::kOk : StatusCode::kCodeOnlyForTesting; + return is_encrypted ? DecoderStatus::Codes::kOk + : DecoderStatus::Codes::kUnsupportedEncryptionMode; case kAlwaysSucceed: - return OkStatus(); + return DecoderStatus::Codes::kOk; } }
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc index 09bc37f..b67fb512 100644 --- a/media/filters/decoder_stream.cc +++ b/media/filters/decoder_stream.cc
@@ -78,12 +78,12 @@ return "AudioDecoderStream::PrepareOutput"; } -const char* GetStatusString(const Status& status) { +const char* GetStatusString(const DecoderStatus& status) { // TODO(crbug.com/1129662): Replace this with generic Status-to-string. switch (status.code()) { - case StatusCode::kOk: + case DecoderStatus::Codes::kOk: return "okay"; - case StatusCode::kAborted: + case DecoderStatus::Codes::kAborted: return "aborted"; default: return "decode_error"; @@ -127,7 +127,7 @@ } if (read_cb_) { read_cb_ = BindToCurrentLoop(std::move(read_cb_)); - SatisfyRead(StatusCode::kAborted); + SatisfyRead(DecoderStatus::Codes::kAborted); } if (reset_cb_) task_runner_->PostTask(FROM_HERE, std::move(reset_cb_)); @@ -188,7 +188,7 @@ read_cb_ = BindToCurrentLoop(std::move(read_cb)); // TODO(crbug.com/1129662): Consider attaching a caused-by of the original // error as well. - SatisfyRead(StatusCode::kDecoderStreamInErrorState); + SatisfyRead(DecoderStatus::Codes::kDecoderStreamInErrorState); return; } @@ -223,7 +223,7 @@ if (read_cb_) { read_cb_ = BindToCurrentLoop(std::move(read_cb_)); - SatisfyRead(StatusCode::kAborted); + SatisfyRead(DecoderStatus::Codes::kAborted); } ClearOutputs(); @@ -519,8 +519,9 @@ int buffer_size, bool end_of_stream, std::unique_ptr<ScopedDecodeTrace> trace_event, - Status status) { - FUNCTION_DVLOG(status.is_ok() ? 3 : 1) << ": " << status.code(); + DecoderStatus status) { + FUNCTION_DVLOG(status.is_ok() ? 3 : 1) + << ": " << static_cast<int>(status.code()); DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || state_ == STATE_ERROR) << state_; @@ -552,11 +553,11 @@ return; switch (status.code()) { - case StatusCode::kAborted: + case DecoderStatus::Codes::kAborted: // Decoder can return kAborted during Reset() or during destruction. return; - case StatusCode::kOk: + case DecoderStatus::Codes::kOk: // Any successful decode counts! if (buffer_size > 0) traits_->ReportStatistics(statistics_cb_, buffer_size); @@ -742,7 +743,7 @@ pending_buffers_.clear(); ClearOutputs(); if (read_cb_) - SatisfyRead(StatusCode::kDecoderStreamDemuxerError); + SatisfyRead(DecoderStatus::Codes::kDecoderStreamDemuxerError); } // Decoding has been stopped. @@ -818,7 +819,7 @@ if (status == DemuxerStream::kAborted) { if (read_cb_) - SatisfyRead(StatusCode::kAborted); + SatisfyRead(DecoderStatus::Codes::kAborted); return; } @@ -870,7 +871,7 @@ if (state_ == STATE_ERROR) { MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decoder reinitialization failed"; - SatisfyRead(StatusCode::kDecoderStreamReinitFailed); + SatisfyRead(DecoderStatus::Codes::kDecoderStreamReinitFailed); return; }
diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h index cbe5750..0c669bd 100644 --- a/media/filters/decoder_stream.h +++ b/media/filters/decoder_stream.h
@@ -18,6 +18,7 @@ #include "base/types/pass_key.h" #include "media/base/audio_decoder.h" #include "media/base/audio_timestamp_helper.h" +#include "media/base/decoder_status.h" #include "media/base/demuxer_stream.h" #include "media/base/media_export.h" #include "media/base/media_log.h" @@ -55,7 +56,7 @@ using InitCB = base::OnceCallback<void(bool success)>; // Indicates completion of a DecoderStream read. - using ReadResult = StatusOr<scoped_refptr<Output>>; + using ReadResult = DecoderStatus::Or<scoped_refptr<Output>>; using ReadCB = base::OnceCallback<void(ReadResult)>; DecoderStream(std::unique_ptr<DecoderStreamTraits<StreamType>> traits, @@ -199,7 +200,7 @@ void OnDecodeDone(int buffer_size, bool end_of_stream, std::unique_ptr<ScopedDecodeTrace> trace_event, - media::Status status); + DecoderStatus status); // Output callback passed to Decoder::Initialize(). void OnDecodeOutputReady(scoped_refptr<Output> output);
diff --git a/media/filters/decoder_stream_traits.cc b/media/filters/decoder_stream_traits.cc index a7b3a82..322134fa 100644 --- a/media/filters/decoder_stream_traits.cc +++ b/media/filters/decoder_stream_traits.cc
@@ -102,7 +102,7 @@ void DecoderStreamTraits<DemuxerStream::AUDIO>::OnDecoderInitialized( DecoderType* decoder, InitCB cb, - Status result) { + DecoderStatus result) { if (result.is_ok()) stats_.audio_pipeline_info.decoder_type = decoder->GetDecoderType(); std::move(cb).Run(result); @@ -227,7 +227,7 @@ void DecoderStreamTraits<DemuxerStream::VIDEO>::OnDecoderInitialized( DecoderType* decoder, InitCB cb, - Status result) { + DecoderStatus result) { if (result.is_ok()) { stats_.video_pipeline_info.decoder_type = decoder->GetDecoderType(); DVLOG(2) << stats_.video_pipeline_info.decoder_type;
diff --git a/media/filters/decoder_stream_traits.h b/media/filters/decoder_stream_traits.h index ea5369d..d3d3afba 100644 --- a/media/filters/decoder_stream_traits.h +++ b/media/filters/decoder_stream_traits.h
@@ -67,7 +67,9 @@ InitCB init_cb, const OutputCB& output_cb, const WaitingCB& waiting_cb); - void OnDecoderInitialized(DecoderType* decoder, InitCB cb, Status status); + void OnDecoderInitialized(DecoderType* decoder, + InitCB cb, + DecoderStatus status); DecoderConfigType GetDecoderConfig(DemuxerStream* stream); void OnDecode(const DecoderBuffer& buffer); PostDecodeAction OnDecodeDone(OutputType* buffer); @@ -126,7 +128,9 @@ InitCB init_cb, const OutputCB& output_cb, const WaitingCB& waiting_cb); - void OnDecoderInitialized(DecoderType* decoder, InitCB cb, Status status); + void OnDecoderInitialized(DecoderType* decoder, + InitCB cb, + DecoderStatus status); void OnDecode(const DecoderBuffer& buffer); PostDecodeAction OnDecodeDone(OutputType* buffer); void OnStreamReset(DemuxerStream* stream);
diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc index c86740c..67035105 100644 --- a/media/filters/decrypting_audio_decoder.cc +++ b/media/filters/decrypting_audio_decoder.cc
@@ -61,12 +61,12 @@ if (!cdm_context) { // Once we have a CDM context, one should always be present. DCHECK(!support_clear_content_); - std::move(init_cb_).Run(StatusCode::kDecoderMissingCdmForEncryptedContent); + std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } if (!config.is_encrypted() && !support_clear_content_) { - std::move(init_cb_).Run(StatusCode::kClearContentUnsupported); + std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -82,7 +82,7 @@ // TODO(xhwang): We should be able to DCHECK config.IsValidConfig(). if (!config.IsValidConfig()) { DLOG(ERROR) << "Invalid audio stream config."; - std::move(init_cb_).Run(StatusCode::kDecoderUnsupportedCodec); + std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedCodec); return; } @@ -91,7 +91,7 @@ if (state_ == kUninitialized) { if (!cdm_context->GetDecryptor()) { DVLOG(1) << __func__ << ": no decryptor"; - std::move(init_cb_).Run(StatusCode::kDecoderFailedInitialization); + std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -121,7 +121,7 @@ // Return empty (end-of-stream) frames if decoding has finished. if (state_ == kDecodeFinished) { output_cb_.Run(AudioBuffer::CreateEOSBuffer()); - std::move(decode_cb_).Run(DecodeStatus::OK); + std::move(decode_cb_).Run(DecoderStatus::Codes::kOk); return; } @@ -162,7 +162,7 @@ if (state_ == kWaitingForKey) { DCHECK(decode_cb_); pending_buffer_to_decode_.reset(); - std::move(decode_cb_).Run(DecodeStatus::ABORTED); + std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted); } DCHECK(!decode_cb_); @@ -182,9 +182,9 @@ } pending_buffer_to_decode_.reset(); if (init_cb_) - std::move(init_cb_).Run(StatusCode::kDecoderInitializeNeverCompleted); + std::move(init_cb_).Run(DecoderStatus::Codes::kInterrupted); if (decode_cb_) - std::move(decode_cb_).Run(DecodeStatus::ABORTED); + std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted); if (reset_cb_) std::move(reset_cb_).Run(); } @@ -207,7 +207,7 @@ if (!success) { DVLOG(1) << __func__ << ": failed to init audio decoder on decryptor"; - std::move(init_cb_).Run(StatusCode::kDecoderInitializeNeverCompleted); + std::move(init_cb_).Run(DecoderStatus::Codes::kFailedToCreateDecoder); decryptor_ = nullptr; event_cb_registration_.reset(); state_ = kError; @@ -219,7 +219,7 @@ std::make_unique<AudioTimestampHelper>(config_.samples_per_second()); state_ = kIdle; - std::move(init_cb_).Run(OkStatus()); + std::move(init_cb_).Run(DecoderStatus::Codes::kOk); } void DecryptingAudioDecoder::DecodePendingBuffer() { @@ -254,7 +254,7 @@ std::move(pending_buffer_to_decode_); if (reset_cb_) { - std::move(decode_cb_).Run(DecodeStatus::ABORTED); + std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted); DoReset(); return; } @@ -265,7 +265,7 @@ DVLOG(2) << "DeliverFrame() - kError"; MEDIA_LOG(ERROR, media_log_) << GetDecoderType() << ": decode error"; state_ = kDecodeFinished; // TODO add kError state - std::move(decode_cb_).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb_).Run(DecoderStatus::Codes::kFailed); return; } @@ -299,7 +299,7 @@ DVLOG(2) << "DeliverFrame() - kNeedMoreData"; state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished : kIdle; - std::move(decode_cb_).Run(DecodeStatus::OK); + std::move(decode_cb_).Run(DecoderStatus::Codes::kOk); return; } @@ -316,7 +316,7 @@ } state_ = kIdle; - std::move(decode_cb_).Run(DecodeStatus::OK); + std::move(decode_cb_).Run(DecoderStatus::Codes::kOk); } void DecryptingAudioDecoder::OnCdmContextEvent(CdmContext::Event event) {
diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc index a55e5d5f..0774de1 100644 --- a/media/filters/decrypting_audio_decoder_unittest.cc +++ b/media/filters/decrypting_audio_decoder_unittest.cc
@@ -89,7 +89,7 @@ decoder_->Initialize( config, cdm_context_.get(), base::BindOnce( - [](bool success, Status status) { + [](bool success, DecoderStatus status) { EXPECT_EQ(status.is_ok(), success); }, success), @@ -132,7 +132,8 @@ .WillOnce(RunOnceCallback<1>(true)); decoder_->Initialize( new_config, cdm_context_.get(), - base::BindOnce([](Status status) { EXPECT_TRUE(status.is_ok()); }), + base::BindOnce( + [](DecoderStatus status) { EXPECT_TRUE(status.is_ok()); }), base::BindRepeating(&DecryptingAudioDecoderTest::FrameReady, base::Unretained(this)), base::BindRepeating(&DecryptingAudioDecoderTest::OnWaiting, @@ -140,7 +141,8 @@ } // Decode |buffer| and expect DecodeDone to get called with |status|. - void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer, StatusCode status) { + void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer, + DecoderStatus status) { EXPECT_CALL(*this, DecodeDone(HasStatusCode(status))); decoder_->Decode(buffer, base::BindOnce(&DecryptingAudioDecoderTest::DecodeDone, @@ -176,7 +178,7 @@ Invoke(this, &DecryptingAudioDecoderTest::DecryptAndDecodeAudio)); EXPECT_CALL(*this, FrameReady(decoded_frame_)); for (int i = 0; i < kDecodingDelay + 1; ++i) - DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK); + DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk); } // Sets up expectations and actions to put DecryptingAudioDecoder in an end @@ -185,7 +187,8 @@ void EnterEndOfStreamState() { // The codec in the |decryptor_| will be flushed. EXPECT_CALL(*this, FrameReady(decoded_frame_)).Times(kDecodingDelay); - DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), DecodeStatus::OK); + DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), + DecoderStatus::Codes::kOk); EXPECT_EQ(0, num_frames_in_decryptor_); } @@ -252,7 +255,7 @@ } MOCK_METHOD1(FrameReady, void(scoped_refptr<AudioBuffer>)); - MOCK_METHOD1(DecodeDone, void(Status)); + MOCK_METHOD1(DecodeDone, void(DecoderStatus)); MOCK_METHOD1(OnWaiting, void(WaitingReason)); @@ -329,7 +332,7 @@ .WillRepeatedly( RunOnceCallback<1>(Decryptor::kError, Decryptor::AudioFrames())); - DecodeAndExpect(encrypted_buffer_, DecodeStatus::DECODE_ERROR); + DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kFailed); } // Test the case where the decryptor returns multiple decoded frames. @@ -353,7 +356,7 @@ EXPECT_CALL(*this, FrameReady(decoded_frame_)); EXPECT_CALL(*this, FrameReady(frame_a)); EXPECT_CALL(*this, FrameReady(frame_b)); - DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK); + DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk); } // Test the case where the decryptor receives end-of-stream buffer. @@ -461,7 +464,7 @@ Initialize(); EnterPendingDecodeState(); - EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted))); Reset(); } @@ -471,7 +474,7 @@ Initialize(); EnterWaitingForKeyState(); - EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted))); Reset(); }
diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc index fc1f044..a98e206b 100644 --- a/media/filters/decrypting_video_decoder.cc +++ b/media/filters/decrypting_video_decoder.cc
@@ -53,12 +53,12 @@ if (!cdm_context) { // Once we have a CDM context, one should always be present. DCHECK(!support_clear_content_); - std::move(init_cb_).Run(StatusCode::kDecoderMissingCdmForEncryptedContent); + std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } if (!config.is_encrypted() && !support_clear_content_) { - std::move(init_cb_).Run(StatusCode::kClearContentUnsupported); + std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -75,7 +75,7 @@ if (state_ == kUninitialized) { if (!cdm_context->GetDecryptor()) { DVLOG(1) << __func__ << ": no decryptor"; - std::move(init_cb_).Run(StatusCode::kDecoderFailedInitialization); + std::move(init_cb_).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -112,13 +112,13 @@ decode_cb_ = BindToCurrentLoop(std::move(decode_cb)); if (state_ == kError) { - std::move(decode_cb_).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb_).Run(DecoderStatus::Codes::kPlatformDecodeFailure); return; } // Return empty frames if decoding has finished. if (state_ == kDecodeFinished) { - std::move(decode_cb_).Run(DecodeStatus::OK); + std::move(decode_cb_).Run(DecoderStatus::Codes::kOk); return; } @@ -154,7 +154,7 @@ CompleteWaitingForDecryptionKey(); DCHECK(decode_cb_); pending_buffer_to_decode_.reset(); - std::move(decode_cb_).Run(DecodeStatus::ABORTED); + std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted); } DCHECK(!decode_cb_); @@ -178,9 +178,9 @@ } pending_buffer_to_decode_.reset(); if (init_cb_) - std::move(init_cb_).Run(StatusCode::kDecoderInitializeNeverCompleted); + std::move(init_cb_).Run(DecoderStatus::Codes::kInterrupted); if (decode_cb_) - std::move(decode_cb_).Run(DecodeStatus::ABORTED); + std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted); if (reset_cb_) std::move(reset_cb_).Run(); } @@ -195,7 +195,9 @@ if (!success) { DVLOG(1) << __func__ << ": failed to init video decoder on decryptor"; - std::move(init_cb_).Run(StatusCode::kDecoderInitializeNeverCompleted); + // TODO(*) Is there a better reason? Should this method itself take a + // status? + std::move(init_cb_).Run(DecoderStatus::Codes::kFailed); decryptor_ = nullptr; event_cb_registration_.reset(); state_ = kError; @@ -204,7 +206,7 @@ // Success! state_ = kIdle; - std::move(init_cb_).Run(OkStatus()); + std::move(init_cb_).Run(DecoderStatus::Codes::kOk); } void DecryptingVideoDecoder::DecodePendingBuffer() { @@ -243,7 +245,7 @@ std::move(pending_buffer_to_decode_); if (reset_cb_) { - std::move(decode_cb_).Run(DecodeStatus::ABORTED); + std::move(decode_cb_).Run(DecoderStatus::Codes::kAborted); DoReset(); return; } @@ -254,7 +256,7 @@ DVLOG(2) << "DeliverFrame() - kError"; MEDIA_LOG(ERROR, media_log_) << GetDecoderType() << ": decode error"; state_ = kError; - std::move(decode_cb_).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb_).Run(DecoderStatus::Codes::kPlatformDecodeFailure); return; } @@ -290,7 +292,7 @@ DVLOG(2) << "DeliverFrame() - kNeedMoreData"; state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished : kIdle; - std::move(decode_cb_).Run(DecodeStatus::OK); + std::move(decode_cb_).Run(DecoderStatus::Codes::kOk); return; } @@ -318,7 +320,7 @@ } state_ = kIdle; - std::move(decode_cb_).Run(DecodeStatus::OK); + std::move(decode_cb_).Run(DecoderStatus::Codes::kOk); } void DecryptingVideoDecoder::OnCdmContextEvent(CdmContext::Event event) {
diff --git a/media/filters/decrypting_video_decoder_unittest.cc b/media/filters/decrypting_video_decoder_unittest.cc index 69c1b424..74c11b4 100644 --- a/media/filters/decrypting_video_decoder_unittest.cc +++ b/media/filters/decrypting_video_decoder_unittest.cc
@@ -84,7 +84,7 @@ decoder_->Initialize( config, false, cdm_context_.get(), base::BindOnce( - [](bool success, Status status) { + [](bool success, DecoderStatus status) { EXPECT_EQ(status.is_ok(), success); }, success), @@ -118,7 +118,8 @@ } // Decode |buffer| and expect DecodeDone to get called with |status|. - void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer, StatusCode status) { + void DecodeAndExpect(scoped_refptr<DecoderBuffer> buffer, + DecoderStatus::Codes status) { EXPECT_CALL(*this, DecodeDone(HasStatusCode(status))); decoder_->Decode(buffer, base::BindOnce(&DecryptingVideoDecoderTest::DecodeDone, @@ -162,7 +163,7 @@ Invoke(this, &DecryptingVideoDecoderTest::DecryptAndDecodeVideo)); EXPECT_CALL(*this, FrameReady(decoded_video_frame_)); for (int i = 0; i < kDecodingDelay + 1; ++i) - DecodeAndExpect(encrypted_buffer_, DecodeStatus::OK); + DecodeAndExpect(encrypted_buffer_, DecoderStatus::Codes::kOk); } // Sets up expectations and actions to put DecryptingVideoDecoder in an end @@ -171,7 +172,8 @@ void EnterEndOfStreamState() { // The codec in the |decryptor_| will be flushed. EXPECT_CALL(*this, FrameReady(decoded_video_frame_)).Times(kDecodingDelay); - DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), DecodeStatus::OK); + DecodeAndExpect(DecoderBuffer::CreateEOSBuffer(), + DecoderStatus::Codes::kOk); EXPECT_EQ(0, num_frames_in_decryptor_); } @@ -237,7 +239,7 @@ } MOCK_METHOD1(FrameReady, void(scoped_refptr<VideoFrame>)); - MOCK_METHOD1(DecodeDone, void(Status)); + MOCK_METHOD1(DecodeDone, void(DecoderStatus)); MOCK_METHOD1(OnWaiting, void(WaitingReason)); @@ -389,7 +391,7 @@ Initialize(); EnterPendingDecodeState(); - EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted))); Reset(); } @@ -399,7 +401,7 @@ Initialize(); EnterWaitingForKeyState(); - EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted))); Reset(); } @@ -459,7 +461,7 @@ Initialize(); EnterPendingDecodeState(); - EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted))); Destroy(); } @@ -469,7 +471,7 @@ Initialize(); EnterWaitingForKeyState(); - EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted))); Destroy(); } @@ -491,7 +493,7 @@ EnterPendingDecodeState(); EXPECT_CALL(*decryptor_, ResetDecoder(Decryptor::kVideo)); - EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted))); decoder_->Reset(NewExpectedClosure()); Destroy();
diff --git a/media/filters/fake_video_decoder.cc b/media/filters/fake_video_decoder.cc index 5803459..d37f69d 100644 --- a/media/filters/fake_video_decoder.cc +++ b/media/filters/fake_video_decoder.cc
@@ -96,18 +96,18 @@ if (config.is_encrypted() && (!supports_encrypted_config_ || !cdm_context)) { DVLOG(1) << "Encrypted config not supported."; state_ = STATE_NORMAL; - init_cb_.RunOrHold(StatusCode::kEncryptedContentUnsupported); + init_cb_.RunOrHold(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } if (fail_to_initialize_) { DVLOG(1) << decoder_id_ << ": Initialization failed."; state_ = STATE_ERROR; - init_cb_.RunOrHold(StatusCode::kDecoderInitializeNeverCompleted); + init_cb_.RunOrHold(DecoderStatus::Codes::kFailed); } else { DVLOG(1) << decoder_id_ << ": Initialization succeeded."; state_ = STATE_NORMAL; - init_cb_.RunOrHold(OkStatus()); + init_cb_.RunOrHold(DecoderStatus::Codes::kOk); } } @@ -127,7 +127,7 @@ buffer_size, BindToCurrentLoop(std::move(decode_cb))); if (state_ == STATE_ERROR) { - std::move(wrapped_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(wrapped_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } @@ -218,7 +218,8 @@ state_ = STATE_ERROR; while (!held_decode_callbacks_.empty()) { - std::move(held_decode_callbacks_.front()).Run(DecodeStatus::DECODE_ERROR); + std::move(held_decode_callbacks_.front()) + .Run(DecoderStatus::Codes::kFailed); held_decode_callbacks_.pop_front(); } decoded_frames_.clear(); @@ -234,7 +235,7 @@ void FakeVideoDecoder::OnFrameDecoded(int buffer_size, DecodeCB decode_cb, - Status status) { + DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (status.is_ok()) { @@ -261,7 +262,7 @@ if (!reset_cb_.IsNull()) { DCHECK(decoded_frames_.empty()); - std::move(decode_cb).Run(DecodeStatus::ABORTED); + std::move(decode_cb).Run(DecoderStatus::Codes::kAborted); return; } @@ -286,7 +287,7 @@ } } - std::move(decode_cb).Run(DecodeStatus::OK); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); } void FakeVideoDecoder::DoReset() {
diff --git a/media/filters/fake_video_decoder.h b/media/filters/fake_video_decoder.h index aa80fda8..52ac03f 100644 --- a/media/filters/fake_video_decoder.h +++ b/media/filters/fake_video_decoder.h
@@ -101,7 +101,9 @@ virtual scoped_refptr<VideoFrame> MakeVideoFrame(const DecoderBuffer& buffer); // Callback for updating |total_bytes_decoded_|. - void OnFrameDecoded(int buffer_size, DecodeCB decode_cb, Status status); + void OnFrameDecoded(int buffer_size, + DecodeCB decode_cb, + DecoderStatus status); // Runs |decode_cb| or puts it to |held_decode_callbacks_| depending on // current value of |hold_decode_|.
diff --git a/media/filters/fake_video_decoder_unittest.cc b/media/filters/fake_video_decoder_unittest.cc index 1e8b46e..18063e9 100644 --- a/media/filters/fake_video_decoder_unittest.cc +++ b/media/filters/fake_video_decoder_unittest.cc
@@ -45,7 +45,7 @@ num_decoded_frames_(0), num_bytes_decoded_(0), total_bytes_in_buffers_(0), - last_decode_status_(DecodeStatus::OK), + last_decode_status_(DecoderStatus::Codes::kOk), pending_decode_requests_(0), is_reset_pending_(false) {} @@ -60,7 +60,7 @@ bool success) { decoder_->Initialize(config, false, nullptr, base::BindOnce( - [](bool success, Status status) { + [](bool success, DecoderStatus status) { EXPECT_EQ(status.is_ok(), success); }, success), @@ -86,7 +86,7 @@ } // Callback for VideoDecoder::Decode(). - void DecodeDone(Status status) { + void DecodeDone(DecoderStatus status) { DCHECK_GT(pending_decode_requests_, 0); --pending_decode_requests_; last_decode_status_ = std::move(status); @@ -126,7 +126,7 @@ break; case ABORTED: EXPECT_EQ(0, pending_decode_requests_); - ASSERT_EQ(StatusCode::kAborted, last_decode_status_.code()); + ASSERT_EQ(DecoderStatus::Codes::kAborted, last_decode_status_.code()); EXPECT_FALSE(last_decoded_frame_.get()); break; } @@ -241,7 +241,7 @@ int total_bytes_in_buffers_; // Callback result/status. - Status last_decode_status_; + DecoderStatus last_decode_status_; scoped_refptr<VideoFrame> last_decoded_frame_; int pending_decode_requests_; bool is_reset_pending_;
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc index d94bfe6..6a56c67 100644 --- a/media/filters/ffmpeg_audio_decoder.cc +++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -82,15 +82,16 @@ if (config.is_encrypted()) { std::move(bound_init_cb) - .Run(Status(StatusCode::kEncryptedContentUnsupported, - "FFmpegAudioDecoder does not support encrypted content")); + .Run(DecoderStatus( + DecoderStatus::Codes::kUnsupportedEncryptionMode, + "FFmpegAudioDecoder does not support encrypted content")); return; } // TODO(dalecurtis): Remove this if ffmpeg ever gets xHE-AAC support. if (config.profile() == AudioCodecProfile::kXHE_AAC) { std::move(bound_init_cb) - .Run(Status(StatusCode::kDecoderUnsupportedProfile) + .Run(DecoderStatus(DecoderStatus::Codes::kUnsupportedProfile) .WithData("decoder", "FFmpegAudioDecoder") .WithData("profile", config.profile())); return; @@ -98,7 +99,7 @@ if (!ConfigureDecoder(config)) { av_sample_format_ = 0; - std::move(bound_init_cb).Run(StatusCode::kDecoderFailedInitialization); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kUnsupportedConfig); return; } @@ -106,7 +107,7 @@ config_ = config; output_cb_ = BindToCurrentLoop(output_cb); state_ = DecoderState::kNormal; - std::move(bound_init_cb).Run(OkStatus()); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kOk); } void FFmpegAudioDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, @@ -117,13 +118,13 @@ DecodeCB decode_cb_bound = BindToCurrentLoop(std::move(decode_cb)); if (state_ == DecoderState::kError) { - std::move(decode_cb_bound).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb_bound).Run(DecoderStatus::Codes::kFailed); return; } // Do nothing if decoding has finished. if (state_ == DecoderState::kDecodeFinished) { - std::move(decode_cb_bound).Run(DecodeStatus::OK); + std::move(decode_cb_bound).Run(DecoderStatus::Codes::kOk); return; } @@ -150,20 +151,20 @@ // occurs with some damaged files. if (!buffer.end_of_stream() && buffer.timestamp() == kNoTimestamp) { DVLOG(1) << "Received a buffer without timestamps!"; - std::move(decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb).Run(DecoderStatus::Codes::kFailed); return; } if (!FFmpegDecode(buffer)) { state_ = DecoderState::kError; - std::move(decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb).Run(DecoderStatus::Codes::kFailed); return; } if (buffer.end_of_stream()) state_ = DecoderState::kDecodeFinished; - std::move(decode_cb).Run(DecodeStatus::OK); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); } bool FFmpegAudioDecoder::FFmpegDecode(const DecoderBuffer& buffer) {
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc index 9d028bf..99f5231 100644 --- a/media/filters/ffmpeg_video_decoder.cc +++ b/media/filters/ffmpeg_video_decoder.cc
@@ -248,12 +248,13 @@ InitCB bound_init_cb = BindToCurrentLoop(std::move(init_cb)); if (config.is_encrypted()) { - std::move(bound_init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(bound_init_cb) + .Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } if (!ConfigureDecoder(config, low_delay)) { - std::move(bound_init_cb).Run(StatusCode::kDecoderFailedInitialization); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kUnsupportedConfig); return; } @@ -261,7 +262,7 @@ config_ = config; output_cb_ = output_cb; state_ = DecoderState::kNormal; - std::move(bound_init_cb).Run(OkStatus()); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kOk); } void FFmpegVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, @@ -275,12 +276,12 @@ DecodeCB decode_cb_bound = BindToCurrentLoop(std::move(decode_cb)); if (state_ == DecoderState::kError) { - std::move(decode_cb_bound).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb_bound).Run(DecoderStatus::Codes::kFailed); return; } if (state_ == DecoderState::kDecodeFinished) { - std::move(decode_cb_bound).Run(DecodeStatus::OK); + std::move(decode_cb_bound).Run(DecoderStatus::Codes::kOk); return; } @@ -306,7 +307,7 @@ if (!FFmpegDecode(*buffer)) { state_ = DecoderState::kError; - std::move(decode_cb_bound).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb_bound).Run(DecoderStatus::Codes::kFailed); return; } @@ -315,7 +316,7 @@ // VideoDecoderShim expects that |decode_cb| is called only after // |output_cb_|. - std::move(decode_cb_bound).Run(DecodeStatus::OK); + std::move(decode_cb_bound).Run(DecoderStatus::Codes::kOk); } void FFmpegVideoDecoder::Reset(base::OnceClosure closure) {
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc index 76b30ab..6f11af4 100644 --- a/media/filters/ffmpeg_video_decoder_unittest.cc +++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -78,7 +78,7 @@ decoder_->Initialize( config, false, nullptr, base::BindOnce( - [](bool success, Status status) { + [](bool success, DecoderStatus status) { EXPECT_EQ(status.is_ok(), success); }, success), @@ -126,14 +126,14 @@ // Decodes all buffers in |input_buffers| and push all successfully decoded // output frames into |output_frames|. // Returns the last decode status returned by the decoder. - Status DecodeMultipleFrames(const InputBuffers& input_buffers) { + DecoderStatus DecodeMultipleFrames(const InputBuffers& input_buffers) { for (auto iter = input_buffers.begin(); iter != input_buffers.end(); ++iter) { - Status status = Decode(*iter); + DecoderStatus status = Decode(*iter); switch (status.code()) { - case StatusCode::kOk: + case DecoderStatus::Codes::kOk: break; - case StatusCode::kAborted: + case DecoderStatus::Codes::kAborted: NOTREACHED(); [[fallthrough]]; default: @@ -141,14 +141,14 @@ return status; } } - return StatusCode::kOk; + return DecoderStatus::Codes::kOk; } // Decodes the single compressed frame in |buffer| and writes the // uncompressed output to |video_frame|. This method works with single // and multithreaded decoders. End of stream buffers are used to trigger // the frame to be returned in the multithreaded decoder case. - Status DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { + DecoderStatus DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { InputBuffers input_buffers; input_buffers.push_back(buffer); input_buffers.push_back(end_of_stream_buffer_); @@ -170,7 +170,7 @@ input_buffers.push_back(buffer); input_buffers.push_back(end_of_stream_buffer_); - Status status = DecodeMultipleFrames(input_buffers); + DecoderStatus status = DecodeMultipleFrames(input_buffers); EXPECT_TRUE(status.is_ok()); ASSERT_EQ(2U, output_frames_.size()); @@ -186,8 +186,8 @@ output_frames_[1]->visible_rect().size().height()); } - Status Decode(scoped_refptr<DecoderBuffer> buffer) { - Status status; + DecoderStatus Decode(scoped_refptr<DecoderBuffer> buffer) { + DecoderStatus status; EXPECT_CALL(*this, DecodeDone(_)).WillOnce(SaveArg<0>(&status)); decoder_->Decode(buffer, base::BindOnce(&FFmpegVideoDecoderTest::DecodeDone, @@ -203,7 +203,7 @@ output_frames_.push_back(std::move(frame)); } - MOCK_METHOD1(DecodeDone, void(Status)); + MOCK_METHOD1(DecodeDone, void(DecoderStatus)); StrictMock<MockMediaLog> media_log_; @@ -281,7 +281,7 @@ EXPECT_TRUE(output_frames_.empty()); // After a decode error occurred, all following decodes will return - // DecodeStatus::DECODE_ERROR. + // DecoderStatus::Codes::kFailed. EXPECT_THAT(Decode(i_frame_buffer_), IsDecodeErrorStatus()); EXPECT_TRUE(output_frames_.empty()); }
diff --git a/media/filters/fuchsia/fuchsia_video_decoder.cc b/media/filters/fuchsia/fuchsia_video_decoder.cc index db80b84..9669b80 100644 --- a/media/filters/fuchsia/fuchsia_video_decoder.cc +++ b/media/filters/fuchsia/fuchsia_video_decoder.cc
@@ -242,7 +242,7 @@ // There should be no pending decode request, so DropInputQueue() is not // expected to fail. - bool result = DropInputQueue(DecodeStatus::ABORTED); + bool result = DropInputQueue(DecoderStatus::Codes::kAborted); DCHECK(result); output_cb_ = output_cb; @@ -252,7 +252,7 @@ // Keep decoder and decryptor if the configuration hasn't changed. if (decoder_ && current_config_.codec() == config.codec() && current_config_.is_encrypted() == config.is_encrypted()) { - std::move(done_callback).Run(OkStatus()); + std::move(done_callback).Run(DecoderStatus::Codes::kOk); return; } @@ -261,10 +261,10 @@ // Initialize the stream. bool secure_mode = false; - StatusCode status = InitializeSysmemBufferStream(config.is_encrypted(), - cdm_context, &secure_mode); - if (status != StatusCode::kOk) { - std::move(done_callback).Run(StatusCode::kOk); + DecoderStatus status = InitializeSysmemBufferStream( + config.is_encrypted(), cdm_context, &secure_mode); + if (!status.is_ok()) { + std::move(done_callback).Run(status); return; } @@ -292,7 +292,7 @@ break; default: - std::move(done_callback).Run(StatusCode::kDecoderUnsupportedCodec); + std::move(done_callback).Run(DecoderStatus::Codes::kUnsupportedCodec); return; } @@ -320,7 +320,7 @@ current_config_ = config; - std::move(done_callback).Run(OkStatus()); + std::move(done_callback).Run(DecoderStatus::Codes::kOk); } void FuchsiaVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, @@ -330,7 +330,7 @@ // Decode() to complete synchronously. base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kFailed)); return; } @@ -340,7 +340,7 @@ } void FuchsiaVideoDecoder::Reset(base::OnceClosure closure) { - DropInputQueue(DecodeStatus::ABORTED); + DropInputQueue(DecoderStatus::Codes::kAborted); base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(closure)); } @@ -357,7 +357,7 @@ return max_decoder_requests_; } -StatusCode FuchsiaVideoDecoder::InitializeSysmemBufferStream( +DecoderStatus FuchsiaVideoDecoder::InitializeSysmemBufferStream( bool is_encrypted, CdmContext* cdm_context, bool* out_secure_mode) { @@ -373,7 +373,7 @@ // Caller makes sure |cdm_context| is available if the stream is encrypted. if (!cdm_context) { DLOG(ERROR) << "No cdm context for encrypted stream."; - return StatusCode::kDecoderMissingCdmForEncryptedContent; + return DecoderStatus::Codes::kUnsupportedEncryptionMode; } // Use FuchsiaStreamDecryptor with FuchsiaCdm (it doesn't support @@ -400,7 +400,7 @@ sysmem_buffer_stream_->Initialize(this, kInputBufferSize, kNumInputBuffers); - return StatusCode::kOk; + return DecoderStatus::Codes::kOk; } void FuchsiaVideoDecoder::OnSysmemBufferStreamBufferCollectionToken( @@ -597,10 +597,10 @@ auto cb = std::move(decode_callbacks_.front()); decode_callbacks_.pop_front(); - std::move(cb).Run(DecodeStatus::OK); + std::move(cb).Run(DecoderStatus::Codes::kOk); } -bool FuchsiaVideoDecoder::DropInputQueue(DecodeStatus status) { +bool FuchsiaVideoDecoder::DropInputQueue(DecoderStatus status) { // Invalidate callbacks for CallNextDecodeCallback(), so the callbacks are not // called when the |decoder_| is dropped below. The callbacks are called // explicitly later. @@ -617,7 +617,7 @@ auto weak_this = weak_this_; for (auto& cb : decode_callbacks_) { - std::move(cb).Run(status); + std::move(cb).Run(std::move(status)); // DecodeCB may destroy |this|. if (!weak_this) @@ -634,7 +634,7 @@ ReleaseOutputBuffers(); - DropInputQueue(DecodeStatus::DECODE_ERROR); + DropInputQueue(DecoderStatus::Codes::kFailed); } void FuchsiaVideoDecoder::SetBufferCollectionTokenForGpu(
diff --git a/media/filters/fuchsia/fuchsia_video_decoder.h b/media/filters/fuchsia/fuchsia_video_decoder.h index 95889cf..bdabdb9 100644 --- a/media/filters/fuchsia/fuchsia_video_decoder.h +++ b/media/filters/fuchsia/fuchsia_video_decoder.h
@@ -74,9 +74,9 @@ private: class OutputMailbox; - StatusCode InitializeSysmemBufferStream(bool is_encrypted, - CdmContext* cdm_context, - bool* secure_mode); + DecoderStatus InitializeSysmemBufferStream(bool is_encrypted, + CdmContext* cdm_context, + bool* secure_mode); // SysmemBufferStream::Sink implementation. void OnSysmemBufferStreamBufferCollectionToken( @@ -104,7 +104,7 @@ // Drops all pending input buffers and then calls all pending DecodeCB with // |status|. Returns true if the decoder still exists. - bool DropInputQueue(DecodeStatus status); + bool DropInputQueue(DecoderStatus status); // Called on errors to shutdown the decoder and notify the client. void OnError();
diff --git a/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc b/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc index 213af7e..1277788 100644 --- a/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc +++ b/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc
@@ -308,7 +308,8 @@ decoder_->Initialize( config, true, /*cdm_context=*/nullptr, base::BindRepeating( - [](bool* init_cb_result, base::RunLoop* run_loop, Status status) { + [](bool* init_cb_result, base::RunLoop* run_loop, + DecoderStatus status) { *init_cb_result = status.is_ok(); run_loop->Quit(); }, @@ -351,7 +352,7 @@ DecodeBuffer(ReadTestDataFile(name)); } - void OnFrameDecoded(size_t frame_pos, Status status) { + void OnFrameDecoded(size_t frame_pos, DecoderStatus status) { EXPECT_EQ(frame_pos, num_decoded_buffers_); num_decoded_buffers_ += 1; last_decode_status_ = std::move(status); @@ -388,7 +389,7 @@ std::list<scoped_refptr<VideoFrame>> output_frames_; size_t num_output_frames_ = 0; - Status last_decode_status_; + DecoderStatus last_decode_status_; base::RunLoop* run_loop_ = nullptr; // Number of frames that OnVideoFrame() should keep in |output_frames_|.
diff --git a/media/filters/gav1_video_decoder.cc b/media/filters/gav1_video_decoder.cc index ae2901a..56b2c69 100644 --- a/media/filters/gav1_video_decoder.cc +++ b/media/filters/gav1_video_decoder.cc
@@ -269,7 +269,8 @@ InitCB bound_init_cb = bind_callbacks_ ? BindToCurrentLoop(std::move(init_cb)) : std::move(init_cb); if (config.is_encrypted() || config.codec() != VideoCodec::kAV1) { - std::move(bound_init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(bound_init_cb) + .Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -295,7 +296,7 @@ if (status != kLibgav1StatusOk) { MEDIA_LOG(ERROR, media_log_) << "libgav1::Decoder::Init() failed, " << "status=" << status; - std::move(bound_init_cb).Run(StatusCode::kDecoderFailedInitialization); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kFailedToCreateDecoder); return; } @@ -303,7 +304,7 @@ state_ = DecoderState::kDecoding; color_space_ = config.color_space_info(); aspect_ratio_ = config.aspect_ratio(); - std::move(bound_init_cb).Run(OkStatus()); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kOk); } void Gav1VideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, @@ -320,18 +321,18 @@ : std::move(decode_cb); if (state_ == DecoderState::kError) { - std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } if (!DecodeBuffer(std::move(buffer))) { state_ = DecoderState::kError; - std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } // VideoDecoderShim expects |decode_cb| call after |output_cb_|. - std::move(bound_decode_cb).Run(DecodeStatus::OK); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kOk); } bool Gav1VideoDecoder::DecodeBuffer(scoped_refptr<DecoderBuffer> buffer) {
diff --git a/media/filters/gav1_video_decoder_unittest.cc b/media/filters/gav1_video_decoder_unittest.cc index ee67114f..b2d57be 100644 --- a/media/filters/gav1_video_decoder_unittest.cc +++ b/media/filters/gav1_video_decoder_unittest.cc
@@ -82,7 +82,7 @@ bool success) { decoder_->Initialize(config, false, nullptr, base::BindOnce( - [](bool success, Status status) { + [](bool success, DecoderStatus status) { EXPECT_EQ(status.is_ok(), success); }, success), @@ -130,14 +130,14 @@ // Decodes all buffers in |input_buffers| and push all successfully decoded // output frames into |output_frames|. Returns the last decode status returned // by the decoder. - Status DecodeMultipleFrames(const InputBuffers& input_buffers) { + DecoderStatus DecodeMultipleFrames(const InputBuffers& input_buffers) { for (auto iter = input_buffers.begin(); iter != input_buffers.end(); ++iter) { - Status status = Decode(*iter); + DecoderStatus status = Decode(*iter); switch (status.code()) { - case StatusCode::kOk: + case DecoderStatus::Codes::kOk: break; - case StatusCode::kAborted: + case DecoderStatus::Codes::kAborted: NOTREACHED(); [[fallthrough]]; default: @@ -145,11 +145,11 @@ return status; } } - return StatusCode::kOk; + return DecoderStatus::Codes::kOk; } // Decodes the single compressed frame in |buffer|. - Status DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { + DecoderStatus DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { InputBuffers input_buffers; input_buffers.push_back(std::move(buffer)); return DecodeMultipleFrames(input_buffers); @@ -168,9 +168,7 @@ input_buffers.push_back(buffer); input_buffers.push_back(DecoderBuffer::CreateEOSBuffer()); - Status status = DecodeMultipleFrames(input_buffers); - - EXPECT_TRUE(status.is_ok()); + EXPECT_TRUE(DecodeMultipleFrames(input_buffers).is_ok()); ASSERT_EQ(2U, output_frames_.size()); gfx::Size original_size = TestVideoConfig::NormalCodedSize(); @@ -184,8 +182,8 @@ output_frames_[1]->visible_rect().size().height()); } - Status Decode(scoped_refptr<DecoderBuffer> buffer) { - Status status; + DecoderStatus Decode(scoped_refptr<DecoderBuffer> buffer) { + DecoderStatus status; EXPECT_CALL(*this, DecodeDone(_)).WillOnce(testing::SaveArg<0>(&status)); decoder_->Decode(std::move(buffer), @@ -210,7 +208,7 @@ return base::MD5DigestToBase16(digest); } - MOCK_METHOD1(DecodeDone, void(Status)); + MOCK_METHOD1(DecodeDone, void(DecoderStatus)); testing::StrictMock<MockMediaLog> media_log_;
diff --git a/media/filters/offloading_video_decoder.cc b/media/filters/offloading_video_decoder.cc index 7197ad5..daba407 100644 --- a/media/filters/offloading_video_decoder.cc +++ b/media/filters/offloading_video_decoder.cc
@@ -35,7 +35,7 @@ void Decode(scoped_refptr<DecoderBuffer> buffer, VideoDecoder::DecodeCB decode_cb) { if (cancellation_flag_->IsSet()) { - std::move(decode_cb).Run(DecodeStatus::ABORTED); + std::move(decode_cb).Run(DecoderStatus::Codes::kAborted); return; }
diff --git a/media/filters/offloading_video_decoder_unittest.cc b/media/filters/offloading_video_decoder_unittest.cc index 12cad0e..8fcda25 100644 --- a/media/filters/offloading_video_decoder_unittest.cc +++ b/media/filters/offloading_video_decoder_unittest.cc
@@ -87,7 +87,7 @@ EXPECT_CALL(*this, InitDone(success)) .WillOnce(VerifyOn(task_env_.GetMainThreadTaskRunner())); return base::BindOnce( - [](base::OnceCallback<void(bool)> cb, Status status) { + [](base::OnceCallback<void(bool)> cb, DecoderStatus status) { std::move(cb).Run(status.is_ok()); }, base::BindOnce(&OffloadingVideoDecoderTest::InitDone, @@ -101,7 +101,7 @@ base::Unretained(this)); } - VideoDecoder::DecodeCB ExpectDecodeCB(StatusCode status) { + VideoDecoder::DecodeCB ExpectDecodeCB(DecoderStatus status) { EXPECT_CALL(*this, DecodeDone(HasStatusCode(status))) .WillOnce(VerifyOn(task_env_.GetMainThreadTaskRunner())); return base::BindOnce(&OffloadingVideoDecoderTest::DecodeDone, @@ -128,7 +128,7 @@ VideoDecoder::OutputCB output_cb; EXPECT_CALL(*decoder_, Initialize_(_, false, nullptr, _, _, _)) .WillOnce(DoAll(VerifyOn(task_env_.GetMainThreadTaskRunner()), - RunOnceCallback<3>(OkStatus()), + RunOnceCallback<3>(DecoderStatus::Codes::kOk), SaveArg<4>(&output_cb))); offloading_decoder_->Initialize(config, false, nullptr, ExpectInitCB(true), ExpectOutputCB(), base::NullCallback()); @@ -138,9 +138,9 @@ EXPECT_CALL(*decoder_, Decode_(_, _)) .WillOnce(DoAll(VerifyOn(task_env_.GetMainThreadTaskRunner()), RunOnceClosure(base::BindOnce(output_cb, nullptr)), - RunOnceCallback<1>(DecodeStatus::OK))); + RunOnceCallback<1>(DecoderStatus::Codes::kOk))); offloading_decoder_->Decode(DecoderBuffer::CreateEOSBuffer(), - ExpectDecodeCB(DecodeStatus::OK)); + ExpectDecodeCB(DecoderStatus::Codes::kOk)); task_env_.RunUntilIdle(); // Reset so we can call Initialize() again. @@ -170,7 +170,7 @@ ExpectOutputCB(), base::NullCallback()); EXPECT_CALL(*decoder_, Initialize_(_, false, nullptr, _, _, _)) .WillOnce(DoAll(VerifyNotOn(task_env_.GetMainThreadTaskRunner()), - RunOnceCallback<3>(OkStatus()), + RunOnceCallback<3>(DecoderStatus::Codes::kOk), SaveArg<4>(&output_cb))); task_env_.RunUntilIdle(); @@ -179,11 +179,11 @@ // Verify decode works and is called on the right thread. offloading_decoder_->Decode(DecoderBuffer::CreateEOSBuffer(), - ExpectDecodeCB(DecodeStatus::OK)); + ExpectDecodeCB(DecoderStatus::Codes::kOk)); EXPECT_CALL(*decoder_, Decode_(_, _)) .WillOnce(DoAll(VerifyNotOn(task_env_.GetMainThreadTaskRunner()), RunOnceClosure(base::BindOnce(output_cb, nullptr)), - RunOnceCallback<1>(DecodeStatus::OK))); + RunOnceCallback<1>(DecoderStatus::Codes::kOk))); task_env_.RunUntilIdle(); // Reset so we can call Initialize() again. @@ -196,7 +196,7 @@ MOCK_METHOD1(InitDone, void(bool)); MOCK_METHOD1(OutputDone, void(scoped_refptr<VideoFrame>)); - MOCK_METHOD1(DecodeDone, void(Status)); + MOCK_METHOD1(DecodeDone, void(DecoderStatus)); MOCK_METHOD0(ResetDone, void(void)); base::test::TaskEnvironment task_env_; @@ -253,7 +253,8 @@ .WillOnce(VerifyNotOn(task_env_.GetMainThreadTaskRunner())); EXPECT_CALL(*decoder_, Initialize_(_, false, nullptr, _, _, _)) .WillOnce(DoAll(VerifyOn(task_env_.GetMainThreadTaskRunner()), - RunOnceCallback<3>(OkStatus()), SaveArg<4>(&output_cb))); + RunOnceCallback<3>(DecoderStatus::Codes::kOk), + SaveArg<4>(&output_cb))); task_env_.RunUntilIdle(); } @@ -280,7 +281,8 @@ base::NullCallback()); EXPECT_CALL(*decoder_, Initialize_(_, false, nullptr, _, _, _)) .WillOnce(DoAll(VerifyNotOn(task_env_.GetMainThreadTaskRunner()), - RunOnceCallback<3>(OkStatus()), SaveArg<4>(&output_cb))); + RunOnceCallback<3>(DecoderStatus::Codes::kOk), + SaveArg<4>(&output_cb))); task_env_.RunUntilIdle(); // When offloading decodes should be parallelized. @@ -300,7 +302,7 @@ .Times(2) .WillRepeatedly(DoAll(VerifyNotOn(task_env_.GetMainThreadTaskRunner()), RunClosure(base::BindRepeating(output_cb, nullptr)), - RunOnceCallback<1>(DecodeStatus::OK))); + RunOnceCallback<1>(DecoderStatus::Codes::kOk))); EXPECT_CALL(*this, DecodeDone(IsOkStatus())) .Times(2) .WillRepeatedly(VerifyOn(task_env_.GetMainThreadTaskRunner())); @@ -331,7 +333,8 @@ base::NullCallback()); EXPECT_CALL(*decoder_, Initialize_(_, false, nullptr, _, _, _)) .WillOnce(DoAll(VerifyNotOn(task_env_.GetMainThreadTaskRunner()), - RunOnceCallback<3>(OkStatus()), SaveArg<4>(&output_cb))); + RunOnceCallback<3>(DecoderStatus::Codes::kOk), + SaveArg<4>(&output_cb))); task_env_.RunUntilIdle(); // When offloading decodes should be parallelized. @@ -348,7 +351,7 @@ base::Unretained(this))); EXPECT_CALL(*decoder_, Decode_(_, _)).Times(0); - EXPECT_CALL(*this, DecodeDone(HasStatusCode(StatusCode::kAborted))) + EXPECT_CALL(*this, DecodeDone(HasStatusCode(DecoderStatus::Codes::kAborted))) .Times(2) .WillRepeatedly(VerifyOn(task_env_.GetMainThreadTaskRunner())); offloading_decoder_->Reset(ExpectResetCB());
diff --git a/media/filters/video_decoder_stream_unittest.cc b/media/filters/video_decoder_stream_unittest.cc index e1bea9b..f913a66 100644 --- a/media/filters/video_decoder_stream_unittest.cc +++ b/media/filters/video_decoder_stream_unittest.cc
@@ -369,9 +369,10 @@ void FrameReady(VideoDecoderStream::ReadResult result) { DCHECK(pending_read_); last_read_status_code_ = result.code(); - scoped_refptr<VideoFrame> frame = last_read_status_code_ == StatusCode::kOk - ? std::move(result).value() - : nullptr; + scoped_refptr<VideoFrame> frame = + last_read_status_code_ == DecoderStatus::Codes::kOk + ? std::move(result).value() + : nullptr; frame_read_ = frame; if (frame && !frame->metadata().end_of_stream) { EXPECT_EQ(*frame->metadata().frame_duration, demuxer_stream_->duration()); @@ -555,7 +556,7 @@ bool pending_stop_; int num_decoded_bytes_unreported_; scoped_refptr<VideoFrame> frame_read_; - StatusCode last_read_status_code_; + DecoderStatus::Codes last_read_status_code_; // Decryptor has no key to decrypt a frame. bool has_no_key_; @@ -824,7 +825,7 @@ decoder_->SatisfySingleDecode(); base::RunLoop().RunUntilIdle(); ASSERT_FALSE(pending_read_); - EXPECT_EQ(last_read_status_code_, StatusCode::kOk); + EXPECT_EQ(last_read_status_code_, DecoderStatus::Codes::kOk); // The read output should indicate end of stream. ASSERT_TRUE(frame_read_.get()); @@ -847,8 +848,8 @@ base::RunLoop().RunUntilIdle(); ASSERT_FALSE(pending_read_); - EXPECT_NE(last_read_status_code_, StatusCode::kOk); - EXPECT_NE(last_read_status_code_, StatusCode::kAborted); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kOk); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kAborted); } // No Reset() before initialization is successfully completed. @@ -1037,7 +1038,7 @@ ASSERT_EQ(GetDecoderId(1), decoder_->GetDecoderId()); ASSERT_FALSE(pending_read_); - ASSERT_EQ(last_read_status_code_, StatusCode::kOk); + ASSERT_EQ(last_read_status_code_, DecoderStatus::Codes::kOk); // Check that we fell back to Decoder2. ASSERT_GT(decoder_->total_bytes_decoded(), 0); @@ -1077,7 +1078,7 @@ // A frame should have been emitted. EXPECT_FALSE(pending_read_); - EXPECT_EQ(last_read_status_code_, StatusCode::kOk); + EXPECT_EQ(last_read_status_code_, DecoderStatus::Codes::kOk); EXPECT_FALSE(frame_read_->metadata().end_of_stream); EXPECT_GT(decoder_->total_bytes_decoded(), 0); @@ -1151,8 +1152,8 @@ // No decoders left, expect failure. EXPECT_EQ(decoder_, nullptr); EXPECT_FALSE(pending_read_); - EXPECT_NE(last_read_status_code_, StatusCode::kOk); - EXPECT_NE(last_read_status_code_, StatusCode::kAborted); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kOk); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kAborted); } // This tests verifies that we properly fallback to a new decoder if the first @@ -1173,7 +1174,7 @@ // Verify that the first frame was decoded successfully. EXPECT_FALSE(pending_read_); EXPECT_GT(decoder_->total_bytes_decoded(), 0); - EXPECT_EQ(last_read_status_code_, StatusCode::kOk); + EXPECT_EQ(last_read_status_code_, DecoderStatus::Codes::kOk); // Continue up to the point of reinitialization. EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); @@ -1197,7 +1198,7 @@ // Verify that fallback happened. EXPECT_EQ(GetDecoderId(0), decoder_->GetDecoderId()); EXPECT_FALSE(pending_read_); - EXPECT_EQ(last_read_status_code_, StatusCode::kOk); + EXPECT_EQ(last_read_status_code_, DecoderStatus::Codes::kOk); EXPECT_GT(decoder_->total_bytes_decoded(), 0); } @@ -1234,8 +1235,8 @@ // No decoders left. EXPECT_EQ(decoder_, nullptr); EXPECT_FALSE(pending_read_); - EXPECT_NE(last_read_status_code_, StatusCode::kOk); - EXPECT_NE(last_read_status_code_, StatusCode::kAborted); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kOk); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kAborted); } TEST_P(VideoDecoderStreamTest, @@ -1388,7 +1389,7 @@ ASSERT_EQ(GetDecoderId(2), decoder_->GetDecoderId()); ASSERT_FALSE(pending_read_); - ASSERT_EQ(last_read_status_code_, StatusCode::kOk); + ASSERT_EQ(last_read_status_code_, DecoderStatus::Codes::kOk); // Can't check previously selected decoder(s) right now, they might have been // destroyed already. @@ -1413,7 +1414,7 @@ ASSERT_EQ(GetDecoderId(2), decoder_->GetDecoderId()); ASSERT_FALSE(pending_read_); - ASSERT_EQ(last_read_status_code_, StatusCode::kOk); + ASSERT_EQ(last_read_status_code_, DecoderStatus::Codes::kOk); // Can't check previously selected decoder(s) right now, they might have been // destroyed already. @@ -1435,7 +1436,7 @@ decoder_->SimulateError(); // The error must surface from Read() as DECODE_ERROR. - while (last_read_status_code_ == StatusCode::kOk) { + while (last_read_status_code_ == DecoderStatus::Codes::kOk) { ReadOneFrame(); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(pending_read_); @@ -1444,8 +1445,8 @@ // Verify the error was surfaced, rather than falling back to other decoders. ASSERT_EQ(GetDecoderId(0), decoder_->GetDecoderId()); EXPECT_FALSE(pending_read_); - EXPECT_NE(last_read_status_code_, StatusCode::kOk); - EXPECT_NE(last_read_status_code_, StatusCode::kAborted); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kOk); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kAborted); } TEST_P(VideoDecoderStreamTest, DecoderErrorWhenNotReading) { @@ -1464,13 +1465,13 @@ decoder_->SimulateError(); // The error must surface from Read() as DECODE_ERROR. - while (last_read_status_code_ == StatusCode::kOk) { + while (last_read_status_code_ == DecoderStatus::Codes::kOk) { ReadOneFrame(); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(pending_read_); } - EXPECT_NE(last_read_status_code_, StatusCode::kOk); - EXPECT_NE(last_read_status_code_, StatusCode::kAborted); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kOk); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kAborted); } TEST_P(VideoDecoderStreamTest, ReinitializeFailure_Once) { @@ -1531,13 +1532,13 @@ ReadUntilDecoderReinitialized(); // The error will surface from Read() as DECODE_ERROR. - while (last_read_status_code_ == StatusCode::kOk) { + while (last_read_status_code_ == DecoderStatus::Codes::kOk) { ReadOneFrame(); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(pending_read_); } - EXPECT_NE(last_read_status_code_, StatusCode::kOk); - EXPECT_NE(last_read_status_code_, StatusCode::kAborted); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kOk); + EXPECT_NE(last_read_status_code_, DecoderStatus::Codes::kAborted); } TEST_P(VideoDecoderStreamTest, Destroy_DuringFallbackDecoderSelection) {
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc index f11d265e..a444b8e7 100644 --- a/media/filters/vpx_video_decoder.cc +++ b/media/filters/vpx_video_decoder.cc
@@ -146,12 +146,13 @@ InitCB bound_init_cb = bind_callbacks_ ? BindToCurrentLoop(std::move(init_cb)) : std::move(init_cb); if (config.is_encrypted()) { - std::move(bound_init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(bound_init_cb) + .Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } if (!ConfigureDecoder(config)) { - std::move(bound_init_cb).Run(StatusCode::kDecoderFailedInitialization); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kUnsupportedConfig); return; } @@ -159,7 +160,7 @@ config_ = config; state_ = DecoderState::kNormal; output_cb_ = output_cb; - std::move(bound_init_cb).Run(OkStatus()); + std::move(bound_init_cb).Run(DecoderStatus::Codes::kOk); } void VpxVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, @@ -176,25 +177,25 @@ : std::move(decode_cb); if (state_ == DecoderState::kError) { - std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } if (state_ == DecoderState::kDecodeFinished) { - std::move(bound_decode_cb).Run(DecodeStatus::OK); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kOk); return; } if (state_ == DecoderState::kNormal && buffer->end_of_stream()) { state_ = DecoderState::kDecodeFinished; - std::move(bound_decode_cb).Run(DecodeStatus::OK); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kOk); return; } scoped_refptr<VideoFrame> video_frame; if (!VpxDecode(buffer.get(), &video_frame)) { state_ = DecoderState::kError; - std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } @@ -206,7 +207,7 @@ } // VideoDecoderShim expects |decode_cb| call after |output_cb_|. - std::move(bound_decode_cb).Run(DecodeStatus::OK); + std::move(bound_decode_cb).Run(DecoderStatus::Codes::kOk); } void VpxVideoDecoder::Reset(base::OnceClosure reset_cb) {
diff --git a/media/filters/vpx_video_decoder_fuzzertest.cc b/media/filters/vpx_video_decoder_fuzzertest.cc index afeba4f..b0f8194 100644 --- a/media/filters/vpx_video_decoder_fuzzertest.cc +++ b/media/filters/vpx_video_decoder_fuzzertest.cc
@@ -30,13 +30,14 @@ base::test::SingleThreadTaskEnvironment task_environment; }; -void OnDecodeComplete(base::OnceClosure quit_closure, media::Status status) { +void OnDecodeComplete(base::OnceClosure quit_closure, + media::DecoderStatus status) { std::move(quit_closure).Run(); } void OnInitDone(base::OnceClosure quit_closure, bool* success_dest, - media::Status status) { + media::DecoderStatus status) { *success_dest = status.is_ok(); std::move(quit_closure).Run(); }
diff --git a/media/filters/vpx_video_decoder_unittest.cc b/media/filters/vpx_video_decoder_unittest.cc index 8103eae..05729bd08 100644 --- a/media/filters/vpx_video_decoder_unittest.cc +++ b/media/filters/vpx_video_decoder_unittest.cc
@@ -44,7 +44,7 @@ bool success) { decoder_->Initialize(config, false, nullptr, base::BindOnce( - [](bool success, Status status) { + [](bool success, DecoderStatus status) { EXPECT_EQ(status.is_ok(), success); }, success), @@ -92,14 +92,14 @@ // Decodes all buffers in |input_buffers| and push all successfully decoded // output frames into |output_frames|. // Returns the last decode status returned by the decoder. - Status DecodeMultipleFrames(const InputBuffers& input_buffers) { + DecoderStatus DecodeMultipleFrames(const InputBuffers& input_buffers) { for (auto iter = input_buffers.begin(); iter != input_buffers.end(); ++iter) { - Status status = Decode(*iter); + DecoderStatus status = Decode(*iter); switch (status.code()) { - case StatusCode::kOk: + case DecoderStatus::Codes::kOk: break; - case StatusCode::kAborted: + case DecoderStatus::Codes::kAborted: NOTREACHED(); [[fallthrough]]; default: @@ -107,14 +107,14 @@ return status; } } - return OkStatus(); + return DecoderStatus::Codes::kOk; } // Decodes the single compressed frame in |buffer| and writes the // uncompressed output to |video_frame|. This method works with single // and multithreaded decoders. End of stream buffers are used to trigger // the frame to be returned in the multithreaded decoder case. - Status DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { + DecoderStatus DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) { InputBuffers input_buffers; input_buffers.push_back(std::move(buffer)); input_buffers.push_back(DecoderBuffer::CreateEOSBuffer()); @@ -135,7 +135,7 @@ input_buffers.push_back(buffer); input_buffers.push_back(DecoderBuffer::CreateEOSBuffer()); - Status status = DecodeMultipleFrames(input_buffers); + DecoderStatus status = DecodeMultipleFrames(input_buffers); EXPECT_TRUE(status.is_ok()); ASSERT_EQ(2U, output_frames_.size()); @@ -151,8 +151,8 @@ output_frames_[1]->visible_rect().size().height()); } - Status Decode(scoped_refptr<DecoderBuffer> buffer) { - Status status; + DecoderStatus Decode(scoped_refptr<DecoderBuffer> buffer) { + DecoderStatus status; EXPECT_CALL(*this, DecodeDone(_)).WillOnce(testing::SaveArg<0>(&status)); decoder_->Decode(std::move(buffer), @@ -168,7 +168,7 @@ output_frames_.push_back(std::move(frame)); } - MOCK_METHOD1(DecodeDone, void(Status)); + MOCK_METHOD1(DecodeDone, void(DecoderStatus)); base::test::TaskEnvironment task_env_; std::unique_ptr<VideoDecoder> decoder_; @@ -326,7 +326,7 @@ AVPacket packet = {}; while (av_read_frame(glue.format_context(), &packet) >= 0) { - Status decode_status = + DecoderStatus decode_status = Decode(DecoderBuffer::CopyFrom(packet.data, packet.size)); av_packet_unref(&packet); if (!decode_status.is_ok())
diff --git a/media/gpu/android/media_codec_video_decoder.cc b/media/gpu/android/media_codec_video_decoder.cc index 577bdd3..b3604b3 100644 --- a/media/gpu/android/media_codec_video_decoder.cc +++ b/media/gpu/android/media_codec_video_decoder.cc
@@ -309,7 +309,7 @@ // Cancel callbacks we no longer want. self->codec_allocator_weak_factory_.InvalidateWeakPtrs(); - self->CancelPendingDecodes(DecodeStatus::ABORTED); + self->CancelPendingDecodes(DecoderStatus::Codes::kAborted); self->StartDrainingCodec(DrainType::kForDestroy); // Per the WARNING above. Validate that no draining work remains. @@ -336,7 +336,7 @@ << config.AsHumanReadableString(); DVLOG(1) << "Invalid configuration."; BindToCurrentLoop(std::move(init_cb)) - .Run(StatusCode::kDecoderUnsupportedConfig); + .Run(DecoderStatus::Codes::kUnsupportedConfig); return; } @@ -351,7 +351,7 @@ MEDIA_LOG(INFO, media_log_) << "Video configuration is not valid: " << config.AsHumanReadableString(); BindToCurrentLoop(std::move(init_cb)) - .Run(StatusCode::kDecoderUnsupportedConfig); + .Run(DecoderStatus::Codes::kUnsupportedConfig); return; } @@ -362,7 +362,7 @@ << decoder_config_.AsHumanReadableString() << " -> " << config.AsHumanReadableString(); BindToCurrentLoop(std::move(init_cb)) - .Run(StatusCode::kDecoderCantChangeCodec); + .Run(DecoderStatus::Codes::kCantChangeCodec); return; } decoder_config_ = config; @@ -391,12 +391,12 @@ DVLOG(1) << "No MediaCrypto to handle encrypted config"; MEDIA_LOG(INFO, media_log_) << "No MediaCrypto to handle encrypted config"; BindToCurrentLoop(std::move(init_cb)) - .Run(StatusCode::kDecoderMissingCdmForEncryptedContent); + .Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } // Do the rest of the initialization lazily on the first decode. - BindToCurrentLoop(std::move(init_cb)).Run(OkStatus()); + BindToCurrentLoop(std::move(init_cb)).Run(DecoderStatus::Codes::kOk); const int width = decoder_config_.coded_size().width(); // On re-init, reallocate the codec if the size has changed too much. @@ -451,14 +451,14 @@ if (decoder_config_.is_encrypted()) { LOG(ERROR) << "MediaCrypto is not available"; EnterTerminalState(State::kError, "MediaCrypto is not available"); - std::move(init_cb).Run(StatusCode::kDecoderMissingCdmForEncryptedContent); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } // MediaCrypto is not available, but the stream is clear. So we can still // play the current stream. But if we switch to an encrypted stream playback // will fail. - std::move(init_cb).Run(OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); return; } @@ -473,7 +473,7 @@ : SurfaceChooserHelper::SecureSurfaceMode::kRequested); // Signal success, and create the codec lazily on the first decode. - std::move(init_cb).Run(OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); } void MediaCodecVideoDecoder::OnCdmContextEvent(CdmContext::Event event) { @@ -736,7 +736,7 @@ DecodeCB decode_cb) { DVLOG(3) << __func__ << ": " << buffer->AsHumanReadableString(); if (state_ == State::kError) { - std::move(decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb).Run(DecoderStatus::Codes::kFailed); return; } pending_decodes_.emplace_back(std::move(buffer), std::move(decode_cb)); @@ -932,7 +932,7 @@ DCHECK(!eos_decode_cb_); eos_decode_cb_ = std::move(pending_decode.decode_cb); } else { - std::move(pending_decode.decode_cb).Run(DecodeStatus::OK); + std::move(pending_decode.decode_cb).Run(DecoderStatus::Codes::kOk); } pending_decodes_.pop_front(); return true; @@ -1039,7 +1039,7 @@ // * After a Reset(), the reset generations won't match, but we might already // have a new |eos_decode_cb_| for the new generation. if (reset_generation == reset_generation_ && eos_decode_cb_) - std::move(eos_decode_cb_).Run(DecodeStatus::OK); + std::move(eos_decode_cb_).Run(DecoderStatus::Codes::kOk); } void MediaCodecVideoDecoder::ForwardVideoFrame( @@ -1080,7 +1080,7 @@ DCHECK(!reset_cb_); reset_generation_++; reset_cb_ = std::move(closure); - CancelPendingDecodes(DecodeStatus::ABORTED); + CancelPendingDecodes(DecoderStatus::Codes::kAborted); StartDrainingCodec(DrainType::kForReset); } @@ -1163,7 +1163,7 @@ target_surface_bundle_ = nullptr; texture_owner_bundle_ = nullptr; if (state == State::kError) - CancelPendingDecodes(DecodeStatus::DECODE_ERROR); + CancelPendingDecodes(DecoderStatus::Codes::kFailed); if (drain_type_) OnCodecDrained(); } @@ -1172,7 +1172,7 @@ return state_ == State::kSurfaceDestroyed || state_ == State::kError; } -void MediaCodecVideoDecoder::CancelPendingDecodes(DecodeStatus status) { +void MediaCodecVideoDecoder::CancelPendingDecodes(DecoderStatus status) { for (auto& pending_decode : pending_decodes_) std::move(pending_decode.decode_cb).Run(status); pending_decodes_.clear();
diff --git a/media/gpu/android/media_codec_video_decoder.h b/media/gpu/android/media_codec_video_decoder.h index 73ec387..1c8740517 100644 --- a/media/gpu/android/media_codec_video_decoder.h +++ b/media/gpu/android/media_codec_video_decoder.h
@@ -211,7 +211,7 @@ // if possible. void StartDrainingCodec(DrainType drain_type); void OnCodecDrained(); - void CancelPendingDecodes(DecodeStatus status); + void CancelPendingDecodes(DecoderStatus status); // Sets |state_| and does common teardown for the terminal states. |state_| // must be either kSurfaceDestroyed or kError. |reason| will be logged to
diff --git a/media/gpu/android/media_codec_video_decoder_unittest.cc b/media/gpu/android/media_codec_video_decoder_unittest.cc index ff467c0..6481bee 100644 --- a/media/gpu/android/media_codec_video_decoder_unittest.cc +++ b/media/gpu/android/media_codec_video_decoder_unittest.cc
@@ -185,7 +185,7 @@ if (!mcvd_) CreateMcvd(); bool result = false; - auto init_cb = [](bool* result_out, Status result) { + auto init_cb = [](bool* result_out, DecoderStatus result) { *result_out = result.is_ok(); }; mcvd_->Initialize( @@ -602,7 +602,7 @@ TEST_P(MediaCodecVideoDecoderTest, ResetAbortsPendingDecodes) { InitializeWithTextureOwner_OneDecodePending(TestVideoConfig::Large(codec_)); - EXPECT_CALL(decode_cb_, Run(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(decode_cb_, Run(HasStatusCode(DecoderStatus::Codes::kAborted))); DoReset(); testing::Mock::VerifyAndClearExpectations(&decode_cb_); } @@ -620,7 +620,8 @@ codec->AcceptOneInput(MockMediaCodecBridge::kEos); PumpCodec(); - EXPECT_CALL(eos_decode_cb, Run(HasStatusCode(StatusCode::kAborted))); + EXPECT_CALL(eos_decode_cb, + Run(HasStatusCode(DecoderStatus::Codes::kAborted))); DoReset(); // Should be run before |mcvd_| is destroyed. testing::Mock::VerifyAndClearExpectations(&eos_decode_cb);
diff --git a/media/gpu/chromeos/decoder_buffer_transcryptor.cc b/media/gpu/chromeos/decoder_buffer_transcryptor.cc index 29f3bc8..e3cd31d 100644 --- a/media/gpu/chromeos/decoder_buffer_transcryptor.cc +++ b/media/gpu/chromeos/decoder_buffer_transcryptor.cc
@@ -36,7 +36,7 @@ DecoderBufferTranscryptor::~DecoderBufferTranscryptor() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - Reset(DecodeStatus::ABORTED); + Reset(DecoderStatus::Codes::kAborted); } void DecoderBufferTranscryptor::EnqueueBuffer( @@ -47,7 +47,7 @@ DecryptPendingBuffer(); } -void DecoderBufferTranscryptor::Reset(DecodeStatus status) { +void DecoderBufferTranscryptor::Reset(DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (current_transcrypt_task_) { std::move(current_transcrypt_task_->decode_done_cb).Run(status); @@ -150,4 +150,4 @@ DecryptPendingBuffer(); } -} // namespace media \ No newline at end of file +} // namespace media
diff --git a/media/gpu/chromeos/decoder_buffer_transcryptor.h b/media/gpu/chromeos/decoder_buffer_transcryptor.h index 9bb1a85..f5c157b3c 100644 --- a/media/gpu/chromeos/decoder_buffer_transcryptor.h +++ b/media/gpu/chromeos/decoder_buffer_transcryptor.h
@@ -13,8 +13,8 @@ #include "base/sequence_checker.h" #include "media/base/callback_registry.h" #include "media/base/cdm_context.h" -#include "media/base/decode_status.h" #include "media/base/decoder_buffer.h" +#include "media/base/decoder_status.h" #include "media/base/decryptor.h" #include "media/base/video_decoder.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -48,7 +48,7 @@ // Removes all pending tasks and invokes all pending VideoDecoder::DecodeCB // callbacks with the passed in |status|. - void Reset(DecodeStatus status); + void Reset(DecoderStatus status); private: // Transcrypt task holding single transcrypt request.
diff --git a/media/gpu/chromeos/vd_video_decode_accelerator.cc b/media/gpu/chromeos/vd_video_decode_accelerator.cc index 7799dffb..f777cad 100644 --- a/media/gpu/chromeos/vd_video_decode_accelerator.cc +++ b/media/gpu/chromeos/vd_video_decode_accelerator.cc
@@ -270,7 +270,7 @@ return true; } -void VdVideoDecodeAccelerator::OnInitializeDone(Status status) { +void VdVideoDecodeAccelerator::OnInitializeDone(DecoderStatus status) { DVLOGF(3) << "success: " << status.is_ok(); DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); DCHECK(client_); @@ -313,12 +313,13 @@ } void VdVideoDecodeAccelerator::OnDecodeDone(int32_t bitstream_buffer_id, - Status status) { - DVLOGF(4) << "status: " << status.code(); + DecoderStatus status) { + DVLOGF(4) << "status: " << status.group() << ":" + << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); DCHECK(client_); - if (!status.is_ok() && status.code() != StatusCode::kAborted) { + if (!status.is_ok() && status.code() != DecoderStatus::Codes::kAborted) { OnError(FROM_HERE, PLATFORM_FAILURE); return; } @@ -364,16 +365,16 @@ base::BindOnce(&VdVideoDecodeAccelerator::OnFlushDone, weak_this_)); } -void VdVideoDecodeAccelerator::OnFlushDone(Status status) { - DVLOGF(3) << "status: " << status.code(); +void VdVideoDecodeAccelerator::OnFlushDone(DecoderStatus status) { + DVLOGF(3) << "status: " << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); DCHECK(client_); switch (status.code()) { - case StatusCode::kOk: + case DecoderStatus::Codes::kOk: client_->NotifyFlushDone(); break; - case StatusCode::kAborted: + case DecoderStatus::Codes::kAborted: // Do nothing. break; default:
diff --git a/media/gpu/chromeos/vd_video_decode_accelerator.h b/media/gpu/chromeos/vd_video_decode_accelerator.h index 7aa2470a..79f0da64 100644 --- a/media/gpu/chromeos/vd_video_decode_accelerator.h +++ b/media/gpu/chromeos/vd_video_decode_accelerator.h
@@ -93,10 +93,10 @@ scoped_refptr<base::SequencedTaskRunner> task_runner); // Callback methods of |vd_|. - void OnInitializeDone(Status status); - void OnDecodeDone(int32_t bitstream_buffer_id, Status status); + void OnInitializeDone(DecoderStatus status); + void OnDecodeDone(int32_t bitstream_buffer_id, DecoderStatus status); void OnFrameReady(scoped_refptr<VideoFrame> frame); - void OnFlushDone(Status status); + void OnFlushDone(DecoderStatus status); void OnResetDone(); // Get Picture instance that represents the same buffer as |frame|. Return
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc index 33a7f5b..cd002a24a 100644 --- a/media/gpu/chromeos/video_decoder_pipeline.cc +++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -265,24 +265,24 @@ if (!config.IsValidConfig()) { VLOGF(1) << "config is not valid"; - std::move(init_cb).Run(StatusCode::kDecoderUnsupportedConfig); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedConfig); return; } #if BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA) if (config.is_encrypted() && !cdm_context) { VLOGF(1) << "Encrypted streams require a CdmContext"; - std::move(init_cb).Run(StatusCode::kDecoderUnsupportedConfig); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedConfig); return; } #else // BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA) if (config.is_encrypted() && !allow_encrypted_content_for_testing_) { VLOGF(1) << "Encrypted streams are not supported for this VD"; - std::move(init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } if (cdm_context && !allow_encrypted_content_for_testing_) { VLOGF(1) << "cdm_context is not supported."; - std::move(init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } #endif // !BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA) @@ -320,7 +320,8 @@ OnError("|decoder_| creation failed."); client_task_runner_->PostTask( FROM_HERE, - base::BindOnce(std::move(init_cb), StatusCode::kDecoderFailedCreation)); + base::BindOnce(std::move(init_cb), + DecoderStatus::Codes::kFailedToCreateDecoder)); return; } @@ -336,14 +337,14 @@ void VideoDecoderPipeline::OnInitializeDone(InitCB init_cb, CdmContext* cdm_context, - Status status) { + DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); - DVLOGF(4) << "Initialization status = " << status.code(); + DVLOGF(4) << "Initialization status = " << static_cast<int>(status.code()); if (!status.is_ok()) { MEDIA_LOG(ERROR, media_log_) << "VideoDecoderPipeline |decoder_| Initialize() failed, status: " - << status.code(); + << static_cast<int>(status.code()); decoder_ = nullptr; } MEDIA_LOG(INFO, media_log_) @@ -354,7 +355,7 @@ if (!cdm_context) { VLOGF(1) << "CdmContext required for transcryption"; decoder_ = nullptr; - status = Status(StatusCode::kDecoderMissingCdmForEncryptedContent); + status = DecoderStatus::Codes::kUnsupportedEncryptionMode; } else { // We need to enable transcryption for protected content. buffer_transcryptor_ = std::make_unique<DecoderBufferTranscryptor>( @@ -402,10 +403,10 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) if (buffer_transcryptor_) - buffer_transcryptor_->Reset(DecodeStatus::ABORTED); + buffer_transcryptor_->Reset(DecoderStatus::Codes::kAborted); #endif // BUILDFLAG(IS_CHROMEOS_ASH) - CallFlushCbIfNeeded(DecodeStatus::ABORTED); + CallFlushCbIfNeeded(DecoderStatus::Codes::kAborted); if (need_frame_pool_rebuild_) { need_frame_pool_rebuild_ = false; @@ -437,8 +438,8 @@ if (has_error_) { client_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(decode_cb), - Status(DecodeStatus::DECODE_ERROR))); + FROM_HERE, + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kFailed)); return; } @@ -461,16 +462,17 @@ void VideoDecoderPipeline::OnDecodeDone(bool is_flush, DecodeCB decode_cb, - Status status) { + DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); - DVLOGF(4) << "is_flush: " << is_flush << ", status: " << status.code(); + DVLOGF(4) << "is_flush: " << is_flush + << ", status: " << static_cast<int>(status.code()); if (has_error_) - status = Status(DecodeStatus::DECODE_ERROR); + status = DecoderStatus::Codes::kFailed; if (is_flush && status.is_ok()) { client_flush_cb_ = std::move(decode_cb); - CallFlushCbIfNeeded(DecodeStatus::OK); + CallFlushCbIfNeeded(DecoderStatus::Codes::kOk); return; } @@ -526,7 +528,7 @@ FROM_HERE, base::BindOnce(client_output_cb_, std::move(frame))); // After outputting a frame, flush might be completed. - CallFlushCbIfNeeded(DecodeStatus::OK); + CallFlushCbIfNeeded(DecoderStatus::Codes::kOk); CallApplyResolutionChangeIfNeeded(); } @@ -555,20 +557,20 @@ has_error_ = true; #if BUILDFLAG(IS_CHROMEOS_ASH) if (buffer_transcryptor_) - buffer_transcryptor_->Reset(DecodeStatus::DECODE_ERROR); + buffer_transcryptor_->Reset(DecoderStatus::Codes::kFailed); #endif // BUILDFLAG(IS_CHROMEOS_ASH) - CallFlushCbIfNeeded(DecodeStatus::DECODE_ERROR); + CallFlushCbIfNeeded(DecoderStatus::Codes::kFailed); } -void VideoDecoderPipeline::CallFlushCbIfNeeded(DecodeStatus status) { +void VideoDecoderPipeline::CallFlushCbIfNeeded(DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); - DVLOGF(3) << "status: " << status; + DVLOGF(3) << "status: " << static_cast<int>(status.code()); if (!client_flush_cb_) return; // Flush is not completed yet. - if (status == DecodeStatus::OK && HasPendingFrames()) + if (status == DecoderStatus::Codes::kOk && HasPendingFrames()) return; client_task_runner_->PostTask( @@ -782,7 +784,7 @@ DCHECK(!has_error_); if (!transcrypted_buffer) { OnError("Error in buffer transcryption"); - std::move(decode_callback).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_callback).Run(DecoderStatus::Codes::kFailed); return; }
diff --git a/media/gpu/chromeos/video_decoder_pipeline.h b/media/gpu/chromeos/video_decoder_pipeline.h index f798c98..61560d3 100644 --- a/media/gpu/chromeos/video_decoder_pipeline.h +++ b/media/gpu/chromeos/video_decoder_pipeline.h
@@ -198,9 +198,11 @@ void ResetTask(base::OnceClosure reset_cb); void DecodeTask(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb); - void OnInitializeDone(InitCB init_cb, CdmContext* cdm_context, Status status); + void OnInitializeDone(InitCB init_cb, + CdmContext* cdm_context, + DecoderStatus status); - void OnDecodeDone(bool eos_buffer, DecodeCB decode_cb, Status status); + void OnDecodeDone(bool eos_buffer, DecodeCB decode_cb, DecoderStatus status); void OnResetDone(base::OnceClosure reset_cb); void OnError(const std::string& msg); @@ -222,7 +224,7 @@ void CallApplyResolutionChangeIfNeeded(); // Call |client_flush_cb_| with |status|. - void CallFlushCbIfNeeded(DecodeStatus status); + void CallFlushCbIfNeeded(DecoderStatus status); #if BUILDFLAG(IS_CHROMEOS_ASH) // Callback for when transcryption of a buffer completes.
diff --git a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc index 87514407..40b6e510 100644 --- a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc +++ b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
@@ -144,7 +144,7 @@ using RepeatingCreateDecoderFunctionCB = base::RepeatingCallback< VideoDecoderPipeline::CreateDecoderFunctionCB::RunType>; RepeatingCreateDecoderFunctionCB create_decoder_function_cb; - StatusCode status_code; + DecoderStatus::Codes status_code; }; class VideoDecoderPipelineTest @@ -176,10 +176,10 @@ VideoDecoderPipeline::DestroyAsync(std::move(decoder_)); task_environment_.RunUntilIdle(); } - MOCK_METHOD1(OnInit, void(Status)); + MOCK_METHOD1(OnInit, void(DecoderStatus)); MOCK_METHOD1(OnOutput, void(scoped_refptr<VideoFrame>)); MOCK_METHOD0(OnResetDone, void()); - MOCK_METHOD1(OnDecodeDone, void(Status)); + MOCK_METHOD1(OnDecodeDone, void(DecoderStatus)); MOCK_METHOD1(OnWaiting, void(WaitingReason)); void SetCreateDecoderFunctionCB(VideoDecoderPipeline::CreateDecoderFunctionCB @@ -197,7 +197,7 @@ // verifying |status_code| is received back in OnInit(). void InitializeDecoder( VideoDecoderPipeline::CreateDecoderFunctionCB create_decoder_function_cb, - StatusCode status_code, + DecoderStatus::Codes status_code, CdmContext* cdm_context = nullptr) { SetCreateDecoderFunctionCB(std::move(create_decoder_function_cb)); @@ -234,7 +234,7 @@ InitializeDecoder( base::BindOnce( &VideoDecoderPipelineTest::CreateGoodMockTranscryptDecoder), - StatusCode::kOk, &cdm_context_); + DecoderStatus::Codes::kOk, &cdm_context_); testing::Mock::VerifyAndClearExpectations(&chromeos_cdm_context_); testing::Mock::VerifyAndClearExpectations(&cdm_context_); // GetDecryptor() will be called again, so set that expectation. @@ -262,7 +262,7 @@ std::unique_ptr<MockDecoder> decoder(new MockDecoder()); EXPECT_CALL(*decoder, Initialize(_, _, _, _, _, _)) .WillOnce(::testing::WithArgs<3>([](VideoDecoder::InitCB init_cb) { - std::move(init_cb).Run(OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); })); EXPECT_CALL(*decoder, NeedsTranscryption()).WillRepeatedly(Return(false)); return std::move(decoder); @@ -277,7 +277,7 @@ std::unique_ptr<MockDecoder> decoder(new MockDecoder()); EXPECT_CALL(*decoder, Initialize(_, _, _, _, _, _)) .WillOnce(::testing::WithArgs<3>([](VideoDecoder::InitCB init_cb) { - std::move(init_cb).Run(OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); })); EXPECT_CALL(*decoder, NeedsTranscryption()).WillRepeatedly(Return(true)); return std::move(decoder); @@ -291,7 +291,7 @@ std::unique_ptr<MockDecoder> decoder(new MockDecoder()); EXPECT_CALL(*decoder, Initialize(_, _, _, _, _, _)) .WillOnce(::testing::WithArgs<3>([](VideoDecoder::InitCB init_cb) { - std::move(init_cb).Run(StatusCode::kDecoderInitializationFailed); + std::move(init_cb).Run(DecoderStatus::Codes::kFailed); })); EXPECT_CALL(*decoder, NeedsTranscryption()).WillRepeatedly(Return(false)); return std::move(decoder); @@ -355,7 +355,7 @@ InitializeDecoder(base::BindOnce(GetParam().create_decoder_function_cb), GetParam().status_code); - EXPECT_EQ(GetParam().status_code == StatusCode::kOk, + EXPECT_EQ(GetParam().status_code == DecoderStatus::Codes::kOk, !!GetUnderlyingDecoder()); } @@ -363,12 +363,12 @@ // A CreateDecoderFunctionCB that fails to Create() (i.e. returns a // null Decoder) {base::BindRepeating(&VideoDecoderPipelineTest::CreateNullMockDecoder), - StatusCode::kDecoderFailedCreation}, + DecoderStatus::Codes::kFailedToCreateDecoder}, // A CreateDecoderFunctionCB that works fine, i.e. Create()s and // Initialize()s correctly. {base::BindRepeating(&VideoDecoderPipelineTest::CreateGoodMockDecoder), - StatusCode::kOk}, + DecoderStatus::Codes::kOk}, // A CreateDecoderFunctionCB for transcryption, where Create() is ok, and // the decoder will Initialize OK, but then the pipeline will not create the @@ -376,12 +376,12 @@ // through InitializeForTranscrypt where a CdmContext is set. {base::BindRepeating( &VideoDecoderPipelineTest::CreateGoodMockTranscryptDecoder), - StatusCode::kDecoderMissingCdmForEncryptedContent}, + DecoderStatus::Codes::kUnsupportedEncryptionMode}, // A CreateDecoderFunctionCB that Create()s ok but fails to Initialize() // correctly. {base::BindRepeating(&VideoDecoderPipelineTest::CreateBadMockDecoder), - StatusCode::kDecoderInitializationFailed}, + DecoderStatus::Codes::kFailed}, }; INSTANTIATE_TEST_SUITE_P(All, @@ -392,7 +392,7 @@ TEST_F(VideoDecoderPipelineTest, Reset) { InitializeDecoder( base::BindOnce(&VideoDecoderPipelineTest::CreateGoodMockDecoder), - StatusCode::kOk); + DecoderStatus::Codes::kOk); // When we call Reset(), we expect GetUnderlyingDecoder()'s Reset() method to // be called, and when that method Run()s its argument closure, then @@ -427,9 +427,10 @@ Decode(transcrypted_buffer_, _)) .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted, VideoDecoderMixin::DecodeCB decode_cb) { - std::move(decode_cb).Run(OkStatus()); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); }); - EXPECT_CALL(*this, OnDecodeDone(MatchesStatusCode(StatusCode::kOk))); + EXPECT_CALL(*this, + OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk))); } decoder_->Decode(encrypted_buffer_, base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone, @@ -449,9 +450,10 @@ Decode(eos_buffer, _)) .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted, VideoDecoderMixin::DecodeCB decode_cb) { - std::move(decode_cb).Run(OkStatus()); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); }); - EXPECT_CALL(*this, OnDecodeDone(MatchesStatusCode(StatusCode::kOk))); + EXPECT_CALL(*this, + OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk))); } decoder_->Decode(eos_buffer, base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone, @@ -486,7 +488,8 @@ EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()), Reset(_)) .WillOnce([](base::OnceClosure closure) { std::move(closure).Run(); }); - EXPECT_CALL(*this, OnDecodeDone(MatchesStatusCode(DecodeStatus::ABORTED))) + EXPECT_CALL(*this, + OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kAborted))) .Times(3); EXPECT_CALL(*this, OnResetDone()).Times(1); } @@ -533,9 +536,10 @@ Decode(transcrypted_buffer_, _)) .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted, VideoDecoderMixin::DecodeCB decode_cb) { - std::move(decode_cb).Run(OkStatus()); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); }); - EXPECT_CALL(*this, OnDecodeDone(MatchesStatusCode(StatusCode::kOk))); + EXPECT_CALL(*this, + OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk))); } EXPECT_CALL(*this, OnWaiting(_)).Times(0); std::move(saved_decrypt_cb).Run(Decryptor::kNoKey, nullptr); @@ -580,9 +584,10 @@ Decode(transcrypted_buffer_, _)) .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted, VideoDecoderMixin::DecodeCB decode_cb) { - std::move(decode_cb).Run(OkStatus()); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); }); - EXPECT_CALL(*this, OnDecodeDone(MatchesStatusCode(StatusCode::kOk))); + EXPECT_CALL(*this, + OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk))); } event_callbacks_.Notify(CdmContext::Event::kHasAdditionalUsableKey); task_environment_.RunUntilIdle(); @@ -599,7 +604,7 @@ std::move(decrypt_cb).Run(Decryptor::kError, nullptr); }); EXPECT_CALL(*this, - OnDecodeDone(MatchesStatusCode(StatusCode::DECODE_ERROR))); + OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kFailed))); } decoder_->Decode(encrypted_buffer_, base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone, @@ -771,7 +776,7 @@ TEST_F(VideoDecoderPipelineTest, RebuildFramePoolsOnStateLost) { InitializeDecoder( base::BindOnce(&VideoDecoderPipelineTest::CreateGoodMockDecoder), - StatusCode::kOk); + DecoderStatus::Codes::kOk); // Simulate the waiting callback from the decoder for kDecoderStateLost. EXPECT_CALL(*this, OnWaiting(media::WaitingReason::kDecoderStateLost));
diff --git a/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc b/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc index fa668ac..bdbbd77c 100644 --- a/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc +++ b/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc
@@ -172,7 +172,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (client_) { client_->NotifyInitializationComplete( - success ? OkStatus() : StatusCode::kInitializationUnspecifiedFailure); + success ? DecoderStatus::Codes::kOk : DecoderStatus::Codes::kFailed); } }
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc index 4ac2f6a..3ab9547 100644 --- a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc +++ b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc
@@ -312,7 +312,8 @@ gpu_preferences, workarounds); } -void GpuVideoDecodeAccelerator::NotifyInitializationComplete(Status status) { +void GpuVideoDecodeAccelerator::NotifyInitializationComplete( + DecoderStatus status) { decoder_client_->OnInitializationComplete(status.is_ok()); }
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.h b/media/gpu/ipc/service/gpu_video_decode_accelerator.h index d37bc17f..683939e 100644 --- a/media/gpu/ipc/service/gpu_video_decode_accelerator.h +++ b/media/gpu/ipc/service/gpu_video_decode_accelerator.h
@@ -60,7 +60,7 @@ const gpu::GpuDriverBugWorkarounds& workarounds); // VideoDecodeAccelerator::Client implementation. - void NotifyInitializationComplete(Status status) override; + void NotifyInitializationComplete(DecoderStatus status) override; void ProvidePictureBuffers(uint32_t requested_num_of_buffers, VideoPixelFormat format, uint32_t textures_per_buffer,
diff --git a/media/gpu/ipc/service/vda_video_decoder.cc b/media/gpu/ipc/service/vda_video_decoder.cc index 90a26a2..ccf7b1f 100644 --- a/media/gpu/ipc/service/vda_video_decoder.cc +++ b/media/gpu/ipc/service/vda_video_decoder.cc
@@ -232,10 +232,9 @@ DCHECK(decode_cbs_.empty()); if (has_error_) { - // TODO(tmathmeyer) generic error, please remove. parent_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(init_cb), - StatusCode::kGenericErrorPleaseRemove)); + FROM_HERE, + base::BindOnce(std::move(init_cb), DecoderStatus::Codes::kFailed)); return; } @@ -306,8 +305,9 @@ gpu_weak_this_)); } else { parent_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&VdaVideoDecoder::InitializeDone, - parent_weak_this_, OkStatus())); + FROM_HERE, + base::BindOnce(&VdaVideoDecoder::InitializeDone, parent_weak_this_, + DecoderStatus::Codes::kOk)); } return; } @@ -344,7 +344,7 @@ parent_task_runner_->PostTask( FROM_HERE, base::BindOnce(&VdaVideoDecoder::InitializeDone, parent_weak_this_, - StatusCode::kDecoderInitializeNeverCompleted)); + DecoderStatus::Codes::kFailed)); return; } @@ -375,7 +375,7 @@ parent_task_runner_->PostTask( FROM_HERE, base::BindOnce(&VdaVideoDecoder::InitializeDone, parent_weak_this_, - StatusCode::kDecoderInitializeNeverCompleted)); + DecoderStatus::Codes::kFailedToCreateDecoder)); return; } @@ -388,13 +388,14 @@ decode_on_parent_thread_ = vda_->TryToSetupDecodeOnSeparateThread( parent_weak_this_, parent_task_runner_); - parent_task_runner_->PostTask(FROM_HERE, - base::BindOnce(&VdaVideoDecoder::InitializeDone, - parent_weak_this_, OkStatus())); + parent_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&VdaVideoDecoder::InitializeDone, + parent_weak_this_, DecoderStatus::Codes::kOk)); } -void VdaVideoDecoder::InitializeDone(Status status) { - DVLOG(1) << __func__ << " success = (" << status.code() << ")"; +void VdaVideoDecoder::InitializeDone(DecoderStatus status) { + DVLOG(1) << __func__ << " success = (" << static_cast<int>(status.code()) + << ")"; DCHECK(parent_task_runner_->BelongsToCurrentThread()); if (has_error_) @@ -422,7 +423,7 @@ if (has_error_) { parent_task_runner_->PostTask( FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kFailed)); return; } @@ -504,8 +505,8 @@ return 4; } -void VdaVideoDecoder::NotifyInitializationComplete(Status status) { - DVLOG(2) << __func__ << "(" << status.code() << ")"; +void VdaVideoDecoder::NotifyInitializationComplete(DecoderStatus status) { + DVLOG(2) << __func__ << "(" << static_cast<int>(status.code()) << ")"; DCHECK(gpu_task_runner_->BelongsToCurrentThread()); DCHECK(vda_initialized_); @@ -686,7 +687,7 @@ // Run a local copy in case the decode callback modifies |decode_cbs_|. DecodeCB decode_cb = std::move(decode_cb_it->second); decode_cbs_.erase(decode_cb_it); - std::move(decode_cb).Run(DecodeStatus::OK); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); } void VdaVideoDecoder::NotifyFlushDone() { @@ -711,7 +712,7 @@ return; DCHECK(decode_cbs_.empty()); - std::move(flush_cb_).Run(DecodeStatus::OK); + std::move(flush_cb_).Run(DecoderStatus::Codes::kOk); } void VdaVideoDecoder::NotifyResetDone() { @@ -744,13 +745,13 @@ std::map<int32_t, DecodeCB> local_decode_cbs = std::move(decode_cbs_); decode_cbs_.clear(); for (auto& it : local_decode_cbs) { - std::move(it.second).Run(DecodeStatus::ABORTED); + std::move(it.second).Run(DecoderStatus::Codes::kAborted); if (!weak_this) return; } if (weak_this && flush_cb_) - std::move(flush_cb_).Run(DecodeStatus::ABORTED); + std::move(flush_cb_).Run(DecoderStatus::Codes::kAborted); if (weak_this) std::move(reset_cb_).Run(); @@ -828,13 +829,13 @@ std::map<int32_t, DecodeCB> local_decode_cbs = std::move(decode_cbs_); decode_cbs_.clear(); for (auto& it : local_decode_cbs) { - std::move(it.second).Run(DecodeStatus::DECODE_ERROR); + std::move(it.second).Run(DecoderStatus::Codes::kFailed); if (!weak_this) return; } if (weak_this && flush_cb_) - std::move(flush_cb_).Run(DecodeStatus::DECODE_ERROR); + std::move(flush_cb_).Run(DecoderStatus::Codes::kFailed); // Note: |reset_cb_| cannot return failure, so the client won't actually find // out about the error until another operation is attempted. @@ -842,7 +843,7 @@ std::move(reset_cb_).Run(); if (weak_this && init_cb_) - std::move(init_cb_).Run(StatusCode::kDecoderInitializeNeverCompleted); + std::move(init_cb_).Run(DecoderStatus::Codes::kFailed); } } // namespace media
diff --git a/media/gpu/ipc/service/vda_video_decoder.h b/media/gpu/ipc/service/vda_video_decoder.h index a8afdf9..83b8653 100644 --- a/media/gpu/ipc/service/vda_video_decoder.h +++ b/media/gpu/ipc/service/vda_video_decoder.h
@@ -117,7 +117,7 @@ const VideoDecodeAccelerator::Capabilities& vda_capabilities); // media::VideoDecodeAccelerator::Client implementation. - void NotifyInitializationComplete(Status status) override; + void NotifyInitializationComplete(DecoderStatus status) override; void ProvidePictureBuffers(uint32_t requested_num_of_buffers, VideoPixelFormat format, uint32_t textures_per_buffer, @@ -136,7 +136,7 @@ static void CleanupOnGpuThread(std::unique_ptr<VdaVideoDecoder>); void InitializeOnGpuThread(); void ReinitializeOnGpuThread(); - void InitializeDone(Status status); + void InitializeDone(DecoderStatus status); void DecodeOnGpuThread(scoped_refptr<DecoderBuffer> buffer, int32_t bitstream_id); void DismissPictureBufferOnParentThread(int32_t picture_buffer_id);
diff --git a/media/gpu/ipc/service/vda_video_decoder_unittest.cc b/media/gpu/ipc/service/vda_video_decoder_unittest.cc index 656e8be..111ea51 100644 --- a/media/gpu/ipc/service/vda_video_decoder_unittest.cc +++ b/media/gpu/ipc/service/vda_video_decoder_unittest.cc
@@ -18,8 +18,8 @@ #include "base/time/time.h" #include "gpu/command_buffer/common/sync_token.h" #include "media/base/async_destroy_video_decoder.h" -#include "media/base/decode_status.h" #include "media/base/decoder_buffer.h" +#include "media/base/decoder_status.h" #include "media/base/media_util.h" #include "media/base/mock_media_log.h" #include "media/base/simple_sync_token_client.h" @@ -179,7 +179,7 @@ } void NotifyEndOfBitstreamBuffer(int32_t bitstream_id) { - EXPECT_CALL(decode_cb_, Run(HasStatusCode(DecodeStatus::OK))); + EXPECT_CALL(decode_cb_, Run(HasStatusCode(DecoderStatus::Codes::kOk))); if (GetParam()) { // TODO(sandersd): The VDA could notify on either thread. Test both. client_->NotifyEndOfBitstreamBuffer(bitstream_id); @@ -328,8 +328,7 @@ VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC601(), kNoTransformation, gfx::Size(320, 240), gfx::Rect(320, 240), gfx::Size(320, 240), EmptyExtraData(), EncryptionScheme::kUnencrypted)); - EXPECT_CALL(init_cb_, - Run(HasStatusCode(StatusCode::kDecoderInitializeNeverCompleted))); + EXPECT_CALL(init_cb_, Run(HasStatusCode(DecoderStatus::Codes::kFailed))); RunUntilIdle(); } @@ -339,8 +338,7 @@ VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), kNoTransformation, gfx::Size(1920, 1088), gfx::Rect(1920, 1080), gfx::Size(1920, 1080), EmptyExtraData(), EncryptionScheme::kUnencrypted)); - EXPECT_CALL(init_cb_, - Run(HasStatusCode(StatusCode::kDecoderInitializeNeverCompleted))); + EXPECT_CALL(init_cb_, Run(HasStatusCode(DecoderStatus::Codes::kFailed))); RunUntilIdle(); } @@ -351,8 +349,7 @@ VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), kNoTransformation, gfx::Size(1920, 1088), gfx::Rect(1920, 1080), gfx::Size(1920, 1080), EmptyExtraData(), EncryptionScheme::kUnencrypted)); - EXPECT_CALL(init_cb_, - Run(HasStatusCode(StatusCode::kDecoderInitializeNeverCompleted))); + EXPECT_CALL(init_cb_, Run(HasStatusCode(DecoderStatus::Codes::kFailed))); RunUntilIdle(); } @@ -376,7 +373,7 @@ vdavd_->Reset(reset_cb_.Get()); RunUntilIdle(); - EXPECT_CALL(decode_cb_, Run(HasStatusCode(DecodeStatus::ABORTED))); + EXPECT_CALL(decode_cb_, Run(HasStatusCode(DecoderStatus::Codes::kAborted))); EXPECT_CALL(reset_cb_, Run()); NotifyResetDone(); }
diff --git a/media/gpu/test/video.cc b/media/gpu/test/video.cc index bb9d23a7..2674443 100644 --- a/media/gpu/test/video.cc +++ b/media/gpu/test/video.cc
@@ -553,12 +553,12 @@ } // Setup the VP9 decoder. - media::Status init_result; + DecoderStatus init_result; VpxVideoDecoder decoder( media::OffloadableVideoDecoder::OffloadState::kOffloaded); media::VideoDecoder::InitCB init_cb = - base::BindOnce([](media::Status* save_to, - media::Status save_from) { *save_to = save_from; }, + base::BindOnce([](DecoderStatus* save_to, + DecoderStatus save_from) { *save_to = save_from; }, &init_result); decoder.Initialize(config, false, nullptr, std::move(init_cb), base::BindRepeating(&Video::OnFrameDecoded, resolution, @@ -576,7 +576,7 @@ num_decoded_frames < num_frames) { if (packet.stream_index == stream_index) { media::VideoDecoder::DecodeCB decode_cb = base::BindOnce( - [](bool* success, media::Status status) { + [](bool* success, DecoderStatus status) { *success = (status.is_ok()); }, success);
diff --git a/media/gpu/test/video_encoder/bitstream_validator.cc b/media/gpu/test/video_encoder/bitstream_validator.cc index 187148d..4a0c828 100644 --- a/media/gpu/test/video_encoder/bitstream_validator.cc +++ b/media/gpu/test/video_encoder/bitstream_validator.cc
@@ -87,7 +87,7 @@ bool success = false; base::WaitableEvent initialized; VideoDecoder::InitCB init_done = base::BindOnce( - [](bool* result, base::WaitableEvent* initialized, Status status) { + [](bool* result, base::WaitableEvent* initialized, DecoderStatus status) { *result = true; if (!status.is_ok()) { LOG(ERROR) << "Failed decoder initialization (" @@ -264,14 +264,14 @@ } } -void BitstreamValidator::DecodeDone(int64_t timestamp, Status status) { +void BitstreamValidator::DecodeDone(int64_t timestamp, DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(validator_thread_sequence_checker_); if (!status.is_ok()) { base::AutoLock lock(validator_lock_); if (!decode_error_) { decode_error_ = true; LOG(ERROR) << "DecodeStatus is not OK, status=" - << GetDecodeStatusString(status.code()); + << static_cast<int>(status.code()); } } if (timestamp == kEOSTimeStamp) {
diff --git a/media/gpu/test/video_encoder/bitstream_validator.h b/media/gpu/test/video_encoder/bitstream_validator.h index e589415..500aff53 100644 --- a/media/gpu/test/video_encoder/bitstream_validator.h +++ b/media/gpu/test/video_encoder/bitstream_validator.h
@@ -17,6 +17,7 @@ #include "base/thread_annotations.h" #include "base/threading/thread.h" #include "media/base/bitstream_buffer.h" +#include "media/base/decoder_status.h" #include "media/base/video_decoder.h" #include "media/gpu/test/bitstream_helpers.h" #include "media/gpu/test/video_frame_helpers.h" @@ -77,7 +78,7 @@ void OutputFrameProcessed(); // Functions for media::VideoDecoder. - void DecodeDone(int64_t timestamp, Status status); + void DecodeDone(int64_t timestamp, DecoderStatus status); void VerifyOutputFrame(scoped_refptr<VideoFrame> frame); // Construct the spatial index conversion table |original_spatial_indices_|
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.cc b/media/gpu/test/video_player/test_vda_video_decoder.cc index 140a58d..60cce08c 100644 --- a/media/gpu/test/video_player/test_vda_video_decoder.cc +++ b/media/gpu/test/video_player/test_vda_video_decoder.cc
@@ -110,7 +110,7 @@ if (!decoder_factory) { ASSERT_TRUE(decoder_) << "Failed to create VideoDecodeAccelerator factory"; - std::move(init_cb).Run(StatusCode::kCodeOnlyForTesting); + std::move(init_cb).Run(DecoderStatus::Codes::kFailed); return; } @@ -142,17 +142,17 @@ if (!decoder_) { ASSERT_TRUE(decoder_) << "Failed to create VideoDecodeAccelerator factory"; - std::move(init_cb).Run(StatusCode::kCodeOnlyForTesting); + std::move(init_cb).Run(DecoderStatus::Codes::kFailed); return; } if (!vda_config.is_deferred_initialization_allowed) - std::move(init_cb).Run(OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); else init_cb_ = std::move(init_cb); } -void TestVDAVideoDecoder::NotifyInitializationComplete(Status status) { +void TestVDAVideoDecoder::NotifyInitializationComplete(DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(vda_wrapper_sequence_checker_); DCHECK(init_cb_); @@ -373,7 +373,7 @@ << "Couldn't find decode callback for picture buffer with id " << bitstream_buffer_id; - std::move(it->second).Run(DecodeStatus::OK); + std::move(it->second).Run(DecoderStatus::Codes::kOk); decode_cbs_.erase(it); } @@ -381,7 +381,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(vda_wrapper_sequence_checker_); DCHECK(flush_cb_); - std::move(flush_cb_).Run(DecodeStatus::OK); + std::move(flush_cb_).Run(DecoderStatus::Codes::kOk); } void TestVDAVideoDecoder::NotifyResetDone() {
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.h b/media/gpu/test/video_player/test_vda_video_decoder.h index 362089dd..791b037a 100644 --- a/media/gpu/test/video_player/test_vda_video_decoder.h +++ b/media/gpu/test/video_player/test_vda_video_decoder.h
@@ -62,7 +62,7 @@ private: // media::VideoDecodeAccelerator::Client implementation - void NotifyInitializationComplete(Status status) override; + void NotifyInitializationComplete(DecoderStatus status) override; void ProvidePictureBuffers(uint32_t requested_num_of_buffers, VideoPixelFormat format, uint32_t textures_per_buffer,
diff --git a/media/gpu/test/video_player/video_decoder_client.cc b/media/gpu/test/video_player/video_decoder_client.cc index b2ea827..faa0abba 100644 --- a/media/gpu/test/video_player/video_decoder_client.cc +++ b/media/gpu/test/video_player/video_decoder_client.cc
@@ -234,7 +234,7 @@ VideoDecoder::InitCB init_cb = base::BindOnce( CallbackThunk<decltype(&VideoDecoderClient::DecoderInitializedTask), - Status>, + DecoderStatus>, weak_this_, decoder_client_thread_.task_runner(), &VideoDecoderClient::DecoderInitializedTask); VideoDecoder::OutputCB output_cb = base::BindRepeating( @@ -320,7 +320,7 @@ VideoDecoder::DecodeCB decode_cb = base::BindOnce( CallbackThunk<decltype(&VideoDecoderClient::DecodeDoneTask), - media::Status>, + DecoderStatus>, weak_this_, decoder_client_thread_.task_runner(), &VideoDecoderClient::DecodeDoneTask); decoder_->Decode(std::move(bitstream_buffer), std::move(decode_cb)); @@ -341,7 +341,7 @@ VideoDecoder::DecodeCB flush_done_cb = base::BindOnce(CallbackThunk<decltype(&VideoDecoderClient::FlushDoneTask), - media::Status>, + DecoderStatus>, weak_this_, decoder_client_thread_.task_runner(), &VideoDecoderClient::FlushDoneTask); decoder_->Decode(DecoderBuffer::CreateEOSBuffer(), std::move(flush_done_cb)); @@ -365,7 +365,7 @@ FireEvent(VideoPlayerEvent::kResetting); } -void VideoDecoderClient::DecoderInitializedTask(Status status) { +void VideoDecoderClient::DecoderInitializedTask(DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_client_sequence_checker_); DCHECK(decoder_client_state_ == VideoDecoderClientState::kUninitialized || decoder_client_state_ == VideoDecoderClientState::kIdle); @@ -375,10 +375,10 @@ FireEvent(VideoPlayerEvent::kInitialized); } -void VideoDecoderClient::DecodeDoneTask(media::Status status) { +void VideoDecoderClient::DecodeDoneTask(DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_client_sequence_checker_); DCHECK_NE(VideoDecoderClientState::kIdle, decoder_client_state_); - ASSERT_TRUE(status.code() != media::StatusCode::kAborted || + ASSERT_TRUE(status != DecoderStatus::Codes::kAborted || decoder_client_state_ == VideoDecoderClientState::kResetting); DVLOGF(4); @@ -407,7 +407,7 @@ current_frame_index_++; } -void VideoDecoderClient::FlushDoneTask(media::Status status) { +void VideoDecoderClient::FlushDoneTask(DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_client_sequence_checker_); DCHECK_EQ(0u, num_outstanding_decode_requests_);
diff --git a/media/gpu/test/video_player/video_decoder_client.h b/media/gpu/test/video_player/video_decoder_client.h index bc04c114..c0ee013 100644 --- a/media/gpu/test/video_player/video_decoder_client.h +++ b/media/gpu/test/video_player/video_decoder_client.h
@@ -14,7 +14,7 @@ #include "base/sequence_checker.h" #include "base/threading/thread.h" #include "gpu/ipc/service/gpu_memory_buffer_factory.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/video_decoder.h" #include "media/base/video_decoder_config.h" #include "media/gpu/test/video_player/video_player.h" @@ -142,13 +142,13 @@ // The below functions are callbacks provided to the video decoder. They are // all executed on the |decoder_client_thread_|. // Called by the decoder when initialization has completed. - void DecoderInitializedTask(Status status); + void DecoderInitializedTask(DecoderStatus status); // Called by the decoder when a fragment has been decoded. - void DecodeDoneTask(media::Status status); + void DecodeDoneTask(DecoderStatus status); // Called by the decoder when a video frame is ready. void FrameReadyTask(scoped_refptr<VideoFrame> video_frame); // Called by the decoder when flushing has completed. - void FlushDoneTask(media::Status status); + void FlushDoneTask(DecoderStatus status); // Called by the decoder when resetting has completed. void ResetDoneTask(); // Called by the decoder when a resolution change was requested, returns
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc index c75a914..fc5e58c9 100644 --- a/media/gpu/v4l2/v4l2_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -115,7 +115,7 @@ // Call all pending decode callback. if (backend_) { - backend_->ClearPendingRequests(DecodeStatus::ABORTED); + backend_->ClearPendingRequests(DecoderStatus::Codes::kAborted); backend_ = nullptr; } @@ -156,14 +156,13 @@ case State::kError: VLOGF(1) << "V4L2 decoder should not be initialized at state: " << static_cast<int>(state_); - std::move(init_cb).Run( - Status(Status::Codes::kDecoderInitializationFailed)); + std::move(init_cb).Run(DecoderStatus::Codes::kFailed); return; } if (cdm_context || config.is_encrypted()) { VLOGF(1) << "V4L2 decoder does not support encrypted stream"; - std::move(init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -176,7 +175,7 @@ // TODO(crbug/1103510): Make StopStreamV4L2Queue return a StatusOr, and // pipe that back instead. std::move(init_cb).Run( - Status(Status::Codes::kDecoderInitializeNeverCompleted) + DecoderStatus(DecoderStatus::Codes::kNotInitialized) .AddCause( V4L2Status(V4L2Status::Codes::kFailedToStopStreamQueue))); return; @@ -199,7 +198,7 @@ // TODO(crbug/1103510): Make V4L2Device::Create return a StatusOr, and // pipe that back instead. std::move(init_cb).Run( - Status(Status::Codes::kDecoderInitializeNeverCompleted) + DecoderStatus(DecoderStatus::Codes::kNotInitialized) .AddCause(V4L2Status(V4L2Status::Codes::kNoDevice))); return; } @@ -219,7 +218,7 @@ VLOGF(1) << "Unknown profile."; SetState(State::kError); std::move(init_cb).Run( - Status(Status::Codes::kDecoderInitializeNeverCompleted) + DecoderStatus(DecoderStatus::Codes::kNotInitialized) .AddCause(V4L2Status(V4L2Status::Codes::kNoProfile))); return; } @@ -227,7 +226,7 @@ // Call init_cb output_cb_ = std::move(output_cb); SetState(State::kInitialized); - std::move(init_cb).Run(::media::OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); } bool V4L2VideoDecoder::NeedsBitstreamConversion() const { @@ -524,7 +523,7 @@ } // Call all pending decode callback. - backend_->ClearPendingRequests(DecodeStatus::ABORTED); + backend_->ClearPendingRequests(DecoderStatus::Codes::kAborted); // Streamoff V4L2 queues to drop input and output buffers. // If the queues are streaming before reset, then we need to start streaming @@ -554,14 +553,14 @@ // VideoDecoder interface: |decode_cb| can't be called from within Decode(). auto trampoline_decode_cb = base::BindOnce( [](const scoped_refptr<base::SequencedTaskRunner>& this_sequence_runner, - DecodeCB decode_cb, Status status) { + DecodeCB decode_cb, DecoderStatus status) { this_sequence_runner->PostTask( FROM_HERE, base::BindOnce(std::move(decode_cb), status)); }, base::SequencedTaskRunnerHandle::Get(), std::move(decode_cb)); if (state_ == State::kError) { - std::move(trampoline_decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(trampoline_decode_cb).Run(DecoderStatus::Codes::kFailed); return; } @@ -570,7 +569,7 @@ if (status != V4L2Status::Codes::kOk) { SetState(State::kError); std::move(trampoline_decode_cb) - .Run(Status(Status::Codes::kDecoderFailedDecode) + .Run(DecoderStatus(DecoderStatus::Codes::kFailed) .AddCause(std::move(status))); return; } @@ -890,7 +889,7 @@ VLOGF(1) << "Error occurred, stopping queues."; StopStreamV4L2Queue(true); if (backend_) - backend_->ClearPendingRequests(DecodeStatus::DECODE_ERROR); + backend_->ClearPendingRequests(DecoderStatus::Codes::kFailed); return; } state_ = new_state;
diff --git a/media/gpu/v4l2/v4l2_video_decoder_backend.h b/media/gpu/v4l2/v4l2_video_decoder_backend.h index 4d8e1d8..d120ef1 100644 --- a/media/gpu/v4l2/v4l2_video_decoder_backend.h +++ b/media/gpu/v4l2/v4l2_video_decoder_backend.h
@@ -6,7 +6,7 @@ #define MEDIA_GPU_V4L2_V4L2_VIDEO_DECODER_BACKEND_H_ #include "base/memory/scoped_refptr.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/video_decoder.h" #include "media/gpu/chromeos/chromeos_status.h" #include "media/gpu/chromeos/dmabuf_video_frame_pool.h" @@ -94,7 +94,7 @@ virtual void OnChangeResolutionDone(CroStatus status) = 0; // Clear all pending decoding tasks and call all pending decode callbacks // with |status| as argument. - virtual void ClearPendingRequests(DecodeStatus status) = 0; + virtual void ClearPendingRequests(DecoderStatus status) = 0; // Whether we should stop the input queue when changing resolution. Stateless // decoders require this, but stateful ones need the input queue to keep
diff --git a/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc b/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc index 892f522c..b98f92f 100644 --- a/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc +++ b/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.cc
@@ -199,7 +199,7 @@ if (!frame_splitter_->AdvanceFrameFragment(data, data_size, &bytes_to_copy)) { VLOGF(1) << "Invalid H.264 stream detected."; std::move(current_decode_request_->decode_cb) - .Run(DecodeStatus::DECODE_ERROR); + .Run(DecoderStatus::Codes::kFailed); current_decode_request_.reset(); current_input_buffer_.reset(); client_->OnBackendError(); @@ -210,7 +210,7 @@ if (bytes_used + bytes_to_copy > current_input_buffer_->GetPlaneSize(0)) { VLOGF(1) << "V4L2 buffer size is too small to contain a whole frame."; std::move(current_decode_request_->decode_cb) - .Run(DecodeStatus::DECODE_ERROR); + .Run(DecoderStatus::Codes::kFailed); current_decode_request_.reset(); current_input_buffer_.reset(); client_->OnBackendError(); @@ -226,7 +226,8 @@ // Release current_input_request_ if we reached its end. if (current_decode_request_->IsCompleted()) { - std::move(current_decode_request_->decode_cb).Run(DecodeStatus::OK); + std::move(current_decode_request_->decode_cb) + .Run(DecoderStatus::Codes::kOk); current_decode_request_.reset(); } @@ -520,7 +521,7 @@ DCHECK(flush_cb_); // Signal that flush has properly been completed. - std::move(flush_cb_).Run(DecodeStatus::OK); + std::move(flush_cb_).Run(DecoderStatus::Codes::kOk); // If CAPTURE queue is streaming, send the START command to the V4L2 device // to signal that we are resuming decoding with the same state. @@ -530,7 +531,7 @@ cmd.cmd = V4L2_DEC_CMD_START; if (device_->Ioctl(VIDIOC_DECODER_CMD, &cmd) != 0) { LOG(ERROR) << "Failed to issue START command"; - std::move(flush_cb_).Run(DecodeStatus::DECODE_ERROR); + std::move(flush_cb_).Run(DecoderStatus::Codes::kFailed); client_->OnBackendError(); return false; } @@ -661,7 +662,7 @@ } void V4L2StatefulVideoDecoderBackend::ClearPendingRequests( - DecodeStatus status) { + DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOGF(3);
diff --git a/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h b/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h index deaec95c..70205b6f 100644 --- a/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h +++ b/media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h
@@ -49,7 +49,7 @@ const gfx::Rect& visible_rect, const size_t num_output_frames) override; void OnChangeResolutionDone(CroStatus status) override; - void ClearPendingRequests(DecodeStatus status) override; + void ClearPendingRequests(DecoderStatus status) override; bool StopInputQueueOnResChange() const override; private:
diff --git a/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc b/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc index 99905806..fc6ad774 100644 --- a/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc +++ b/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.cc
@@ -18,7 +18,7 @@ #include "base/posix/eintr_wrapper.h" #include "base/task/sequenced_task_runner.h" #include "base/trace_event/trace_event.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/video_codecs.h" #include "media/base/video_frame.h" #include "media/gpu/accelerated_video_decoder.h" @@ -422,7 +422,8 @@ enqueuing_timestamps_[current_decode_request_->buffer->timestamp() .InMilliseconds()] = base::TimeTicks::Now(); - std::move(current_decode_request_->decode_cb).Run(DecodeStatus::OK); + std::move(current_decode_request_->decode_cb) + .Run(DecoderStatus::Codes::kOk); current_decode_request_ = absl::nullopt; } @@ -498,7 +499,7 @@ case OutputRequest::kFlushFence: DCHECK(output_request_queue_.empty()); DVLOGF(2) << "Flush finished."; - std::move(flush_cb_).Run(DecodeStatus::OK); + std::move(flush_cb_).Run(DecoderStatus::Codes::kOk); resume_decode = true; client_->CompleteFlush(); break; @@ -617,7 +618,7 @@ } void V4L2StatelessVideoDecoderBackend::ClearPendingRequests( - DecodeStatus status) { + DecoderStatus status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOGF(3);
diff --git a/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h b/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h index 58c6478..1f77bbb6 100644 --- a/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h +++ b/media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h
@@ -11,7 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/task/sequenced_task_runner.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/video_decoder.h" #include "media/gpu/chromeos/dmabuf_video_frame_pool.h" #include "media/gpu/v4l2/v4l2_decode_surface_handler.h" @@ -54,7 +54,7 @@ const gfx::Rect& visible_rect, const size_t num_output_frames) override; void OnChangeResolutionDone(CroStatus status) override; - void ClearPendingRequests(DecodeStatus status) override; + void ClearPendingRequests(DecoderStatus status) override; bool StopInputQueueOnResChange() const override; // V4L2DecodeSurfaceHandler implementation.
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc index cc8a347c0..b6ea013 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
@@ -380,7 +380,7 @@ } // VideoDecodeAccelerator::Client methods. - MOCK_METHOD1(NotifyInitializationComplete, void(Status)); + MOCK_METHOD1(NotifyInitializationComplete, void(DecoderStatus)); MOCK_METHOD5( ProvidePictureBuffers, void(uint32_t, VideoPixelFormat, uint32_t, const gfx::Size&, uint32_t));
diff --git a/media/gpu/vaapi/vaapi_video_decoder.cc b/media/gpu/vaapi/vaapi_video_decoder.cc index 548fcdb..4a94baa4 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.cc +++ b/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -152,7 +152,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Abort all currently scheduled decode tasks. - ClearDecodeTaskQueue(DecodeStatus::ABORTED); + ClearDecodeTaskQueue(DecoderStatus::Codes::kAborted); weak_this_factory_.InvalidateWeakPtrs(); @@ -192,7 +192,7 @@ state_ == State::kExpectingReset) { LOG(ERROR) << "Don't call Initialize() while there are pending decode tasks"; - std::move(init_cb).Run(StatusCode::kDecoderInitializationFailed); + std::move(init_cb).Run(DecoderStatus::Codes::kFailed); return; } @@ -239,12 +239,12 @@ if (config.is_encrypted()) { #if !BUILDFLAG(IS_CHROMEOS_ASH) SetErrorState("encrypted content is not supported"); - std::move(init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; #else if (!cdm_context || !cdm_context->GetChromeOsCdmContext()) { SetErrorState("cannot support encrypted stream w/out ChromeOsCdmContext"); - std::move(init_cb).Run(StatusCode::kDecoderMissingCdmForEncryptedContent); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } bool encrypted_av1_support = false; @@ -261,7 +261,7 @@ SetErrorState( base::StringPrintf("%s is not supported for encrypted content", GetCodecName(config.codec()).c_str())); - std::move(init_cb).Run(StatusCode::kEncryptedContentUnsupported); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } cdm_event_cb_registration_ = cdm_context->RegisterEventCB( @@ -278,7 +278,7 @@ !base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableClearHevcForTesting)) { SetErrorState("clear HEVC content is not supported"); - std::move(init_cb).Run(StatusCode::kClearContentUnsupported); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; #endif } @@ -303,7 +303,7 @@ SetErrorState( base::StringPrintf("failed initializing VaapiWrapper for profile %s, ", GetProfileName(profile).c_str())); - std::move(init_cb).Run(StatusCode::kDecoderUnsupportedProfile); + std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedProfile); return; } @@ -315,7 +315,7 @@ auto accel_status = CreateAcceleratedVideoDecoder(); if (!accel_status.is_ok()) { SetErrorState("failed to create decoder delegate"); - std::move(init_cb).Run(Status(Status::Codes::kDecoderInitializationFailed) + std::move(init_cb).Run(DecoderStatus(DecoderStatus::Codes::kFailed) .AddCause(std::move(accel_status))); return; } @@ -327,7 +327,7 @@ SetState(State::kWaitingForInput); // Notify client initialization was successful. - std::move(init_cb).Run(OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); } void VaapiVideoDecoder::OnCdmContextEvent(CdmContext::Event event) { @@ -352,7 +352,7 @@ // VideoDecoder interface: |decode_cb| can't be called from within Decode(). base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kFailed)); return; } @@ -417,7 +417,8 @@ case AcceleratedVideoDecoder::kRanOutOfStreamData: // Decoding was successful, notify client and try to schedule the next // task. Switch to the idle state if we ran out of buffers to decode. - std::move(current_decode_task_->decode_done_cb_).Run(DecodeStatus::OK); + std::move(current_decode_task_->decode_done_cb_) + .Run(DecoderStatus::Codes::kOk); current_decode_task_ = absl::nullopt; if (!decode_task_queue_.empty()) { ScheduleNextDecodeTask(); @@ -458,7 +459,7 @@ } } -void VaapiVideoDecoder::ClearDecodeTaskQueue(DecodeStatus status) { +void VaapiVideoDecoder::ClearDecodeTaskQueue(DecoderStatus status) { DVLOGF(4); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -1033,7 +1034,8 @@ DCHECK(output_frames_.empty()); // Notify the client flushing is done. - std::move(current_decode_task_->decode_done_cb_).Run(DecodeStatus::OK); + std::move(current_decode_task_->decode_done_cb_) + .Run(DecoderStatus::Codes::kOk); current_decode_task_ = absl::nullopt; // Wait for new decodes, no decode tasks should be queued while flushing. @@ -1192,7 +1194,7 @@ state_ == State::kWaitingForProtected || state_ == State::kChangingResolution || state_ == State::kExpectingReset); - ClearDecodeTaskQueue(DecodeStatus::ABORTED); + ClearDecodeTaskQueue(DecoderStatus::Codes::kAborted); break; case State::kChangingResolution: DCHECK_EQ(state_, State::kDecoding); @@ -1201,7 +1203,7 @@ DCHECK_EQ(state_, State::kChangingResolution); break; case State::kError: - ClearDecodeTaskQueue(DecodeStatus::DECODE_ERROR); + ClearDecodeTaskQueue(DecoderStatus::Codes::kFailed); break; }
diff --git a/media/gpu/vaapi/vaapi_video_decoder.h b/media/gpu/vaapi/vaapi_video_decoder.h index d6bdb19..d58d2845 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.h +++ b/media/gpu/vaapi/vaapi_video_decoder.h
@@ -134,7 +134,7 @@ void HandleDecodeTask(); // Clear the decode task queue. This is done when resetting or destroying the // decoder, or encountering an error. - void ClearDecodeTaskQueue(DecodeStatus status); + void ClearDecodeTaskQueue(DecoderStatus status); // Releases the local reference to the VideoFrame associated with the // specified |surface_id| on the decoder thread. This is called when
diff --git a/media/gpu/video_decode_accelerator_tests.cc b/media/gpu/video_decode_accelerator_tests.cc index 9ea3b77..bce49fb 100644 --- a/media/gpu/video_decode_accelerator_tests.cc +++ b/media/gpu/video_decode_accelerator_tests.cc
@@ -214,7 +214,7 @@ bool init_success = false; VideoDecoder::InitCB init_cb = base::BindOnce( - [](bool* init_success, media::Status result) { + [](bool* init_success, DecoderStatus result) { *init_success = result.is_ok(); }, &init_success); @@ -231,7 +231,7 @@ while (!encoded_data_helper->ReachEndOfStream()) { bool decode_success = false; media::VideoDecoder::DecodeCB decode_cb = base::BindOnce( - [](bool* decode_success, media::Status status) { + [](bool* decode_success, DecoderStatus status) { *decode_success = status.is_ok(); }, &decode_success); @@ -247,7 +247,7 @@ } bool flush_success = false; media::VideoDecoder::DecodeCB flush_cb = base::BindOnce( - [](bool* flush_success, media::Status status) { + [](bool* flush_success, DecoderStatus status) { *flush_success = status.is_ok(); }, &flush_success);
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index 34a8c9d..2c624f3e 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -497,7 +497,7 @@ release_mailbox_cb_ = std::move(release_mailbox_cb); state_ = State::kRunning; - std::move(init_cb_).Run(OkStatus()); + std::move(init_cb_).Run(DecoderStatus::Codes::kOk); } void D3D11VideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, @@ -512,7 +512,7 @@ if (state_ == State::kError) { // TODO(liberato): consider posting, though it likely doesn't matter. - std::move(decode_cb).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb).Run(DecoderStatus::Codes::kInterrupted); return; } @@ -558,7 +558,7 @@ } // Pictures out output synchronously during Flush. Signal the decode // cb now. - std::move(current_decode_cb_).Run(DecodeStatus::OK); + std::move(current_decode_cb_).Run(DecoderStatus::Codes::kOk); return; } // This must be after checking for EOS because there is no timestamp for an @@ -601,7 +601,7 @@ // TODO(liberato): switch + class enum. if (result == media::AcceleratedVideoDecoder::kRanOutOfStreamData) { current_buffer_ = nullptr; - std::move(current_decode_cb_).Run(DecodeStatus::OK); + std::move(current_decode_cb_).Run(DecoderStatus::Codes::kOk); break; } else if (result == media::AcceleratedVideoDecoder::kRanOutOfSurfaces) { // At this point, we know the picture size. @@ -673,10 +673,10 @@ current_buffer_ = nullptr; if (current_decode_cb_) - std::move(current_decode_cb_).Run(DecodeStatus::ABORTED); + std::move(current_decode_cb_).Run(DecoderStatus::Codes::kAborted); for (auto& queue_pair : input_buffer_queue_) - std::move(queue_pair.second).Run(DecodeStatus::ABORTED); + std::move(queue_pair.second).Run(DecoderStatus::Codes::kAborted); input_buffer_queue_.clear(); // TODO(liberato): how do we signal an error? @@ -908,9 +908,8 @@ // TODO(liberato): VideoDecoder::InitCB should have either its own status // codes, or should use a common one that has "succeeded / didn't succeed" // as its only options. - std::move(init_cb_).Run( - Status(Status::Codes::kDecoderInitializeNeverCompleted) - .AddCause(std::move(reason))); + std::move(init_cb_).Run(DecoderStatus(DecoderStatus::Codes::kFailed) + .AddCause(std::move(reason))); } else { // TODO(tmathmeyer) - Remove this after plumbing Status through the // decode_cb and input_buffer_queue cb's. @@ -922,10 +921,10 @@ current_buffer_ = nullptr; if (current_decode_cb_) - std::move(current_decode_cb_).Run(DecodeStatus::DECODE_ERROR); + std::move(current_decode_cb_).Run(DecoderStatus::Codes::kFailed); for (auto& queue_pair : input_buffer_queue_) - std::move(queue_pair.second).Run(DecodeStatus::DECODE_ERROR); + std::move(queue_pair.second).Run(DecoderStatus::Codes::kFailed); input_buffer_queue_.clear(); }
diff --git a/media/gpu/windows/d3d11_video_decoder_unittest.cc b/media/gpu/windows/d3d11_video_decoder_unittest.cc index e540bc4..897ec02 100644 --- a/media/gpu/windows/d3d11_video_decoder_unittest.cc +++ b/media/gpu/windows/d3d11_video_decoder_unittest.cc
@@ -224,12 +224,12 @@ base::RunLoop().RunUntilIdle(); } - void CheckStatus(bool expectSuccess, Status actual) { + void CheckStatus(bool expectSuccess, DecoderStatus actual) { ASSERT_EQ(expectSuccess, actual.is_ok()); MockInitCB(actual); } - MOCK_METHOD1(MockInitCB, void(Status)); + MOCK_METHOD1(MockInitCB, void(DecoderStatus)); base::test::TaskEnvironment task_environment_;
diff --git a/media/mojo/clients/mojo_audio_decoder.cc b/media/mojo/clients/mojo_audio_decoder.cc index 4e50d022..22bdd2fc 100644 --- a/media/mojo/clients/mojo_audio_decoder.cc +++ b/media/mojo/clients/mojo_audio_decoder.cc
@@ -51,7 +51,7 @@ return decoder_type_; } -void MojoAudioDecoder::FailInit(InitCB init_cb, Status err) { +void MojoAudioDecoder::FailInit(InitCB init_cb, DecoderStatus err) { task_runner_->PostTask(FROM_HERE, base::BindOnce(std::move(init_cb), std::move(err))); } @@ -70,7 +70,7 @@ // This could happen during reinitialization. if (!remote_decoder_.is_connected()) { DVLOG(1) << __func__ << ": Connection error happened."; - FailInit(std::move(init_cb), StatusCode::kMojoDecoderNoConnection); + FailInit(std::move(init_cb), DecoderStatus::Codes::kFailedToCreateDecoder); return; } @@ -82,7 +82,7 @@ if (config.is_encrypted() && !cdm_id) { DVLOG(1) << __func__ << ": Invalid CdmContext."; FailInit(std::move(init_cb), - StatusCode::kDecoderMissingCdmForEncryptedContent); + DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -105,7 +105,7 @@ if (!remote_decoder_.is_connected()) { task_runner_->PostTask( FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kFailed)); return; } @@ -114,7 +114,7 @@ if (!buffer) { task_runner_->PostTask( FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kFailed)); return; } @@ -134,7 +134,7 @@ if (decode_cb_) { task_runner_->PostTask( FROM_HERE, - base::BindOnce(std::move(decode_cb_), DecodeStatus::DECODE_ERROR)); + base::BindOnce(std::move(decode_cb_), DecoderStatus::Codes::kFailed)); } task_runner_->PostTask(FROM_HERE, std::move(closure)); @@ -188,17 +188,17 @@ DCHECK(!remote_decoder_.is_connected()); if (init_cb_) { - FailInit(std::move(init_cb_), StatusCode::kMojoDecoderNoConnection); + FailInit(std::move(init_cb_), DecoderStatus::Codes::kFailedToCreateDecoder); return; } if (decode_cb_) - std::move(decode_cb_).Run(DecodeStatus::DECODE_ERROR); + std::move(decode_cb_).Run(DecoderStatus::Codes::kFailed); if (reset_cb_) std::move(reset_cb_).Run(); } -void MojoAudioDecoder::OnInitialized(const Status& status, +void MojoAudioDecoder::OnInitialized(const DecoderStatus& status, bool needs_bitstream_conversion, AudioDecoderType decoder_type) { DVLOG(1) << __func__ << ": success:" << status.is_ok(); @@ -219,8 +219,8 @@ std::move(init_cb_).Run(std::move(status)); } -void MojoAudioDecoder::OnDecodeStatus(const Status& status) { - DVLOG(1) << __func__ << ": status:" << status.code(); +void MojoAudioDecoder::OnDecodeStatus(const DecoderStatus& status) { + DVLOG(1) << __func__ << ": status:" << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(decode_cb_);
diff --git a/media/mojo/clients/mojo_audio_decoder.h b/media/mojo/clients/mojo_audio_decoder.h index 7d18d6e1..3097a9e1 100644 --- a/media/mojo/clients/mojo_audio_decoder.h +++ b/media/mojo/clients/mojo_audio_decoder.h
@@ -66,15 +66,15 @@ void OnConnectionError(); // Fail an initialization with a Status. - void FailInit(InitCB init_cb, Status err); + void FailInit(InitCB init_cb, DecoderStatus err); // Called when |remote_decoder_| finished initialization. - void OnInitialized(const Status& status, + void OnInitialized(const DecoderStatus& status, bool needs_bitstream_conversion, AudioDecoderType decoder_type); // Called when |remote_decoder_| accepted or rejected DecoderBuffer. - void OnDecodeStatus(const Status& decode_status); + void OnDecodeStatus(const DecoderStatus& decode_status); // called when |remote_decoder_| finished Reset() sequence. void OnResetDone();
diff --git a/media/mojo/clients/mojo_audio_decoder_unittest.cc b/media/mojo/clients/mojo_audio_decoder_unittest.cc index ed0266a..710f556 100644 --- a/media/mojo/clients/mojo_audio_decoder_unittest.cc +++ b/media/mojo/clients/mojo_audio_decoder_unittest.cc
@@ -83,10 +83,10 @@ } // Completion callbacks. - MOCK_METHOD1(OnInitialized, void(Status)); + MOCK_METHOD1(OnInitialized, void(DecoderStatus)); MOCK_METHOD1(OnOutput, void(scoped_refptr<AudioBuffer>)); MOCK_METHOD1(OnWaiting, void(WaitingReason)); - MOCK_METHOD1(OnDecoded, void(Status)); + MOCK_METHOD1(OnDecoded, void(DecoderStatus)); MOCK_METHOD0(OnReset, void()); // Always create a new RunLoop (and destroy the old loop if it exists) before @@ -118,12 +118,12 @@ EXPECT_CALL(*mock_audio_decoder_, Initialize_(_, _, _, _, _)) .WillRepeatedly(DoAll(SaveArg<3>(&output_cb_), SaveArg<4>(&waiting_cb_), - RunOnceCallback<2>(OkStatus()))); + RunOnceCallback<2>(DecoderStatus::Codes::kOk))); EXPECT_CALL(*mock_audio_decoder_, Decode(_, _)) .WillRepeatedly([&](scoped_refptr<DecoderBuffer> buffer, AudioDecoder::DecodeCB decode_cb) { ReturnOutput(); - std::move(decode_cb).Run(DecodeStatus::OK); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); }); EXPECT_CALL(*mock_audio_decoder_, Reset_(_)) .WillRepeatedly(RunOnceCallback<0>()); @@ -138,8 +138,8 @@ mojo_audio_decoder_->set_writer_capacity_for_testing(capacity); } - void InitializeAndExpect(Status status) { - DVLOG(1) << __func__ << ": success=" << status.code(); + void InitializeAndExpect(DecoderStatus status) { + DVLOG(1) << __func__ << ": success=" << static_cast<int>(status.code()); EXPECT_CALL(*this, OnInitialized(SameStatusCode(status))) .WillOnce(InvokeWithoutArgs(this, &MojoAudioDecoderTest::QuitLoop)); @@ -159,7 +159,7 @@ RunLoop(); } - void Initialize() { InitializeAndExpect(OkStatus()); } + void Initialize() { InitializeAndExpect(DecoderStatus::Codes::kOk); } void Decode() { scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(100)); @@ -294,7 +294,7 @@ .WillOnce([&](scoped_refptr<DecoderBuffer> buffer, AudioDecoder::DecodeCB decode_cb) { WaitForKey(); - std::move(decode_cb).Run(DecodeStatus::OK); + std::move(decode_cb).Run(DecoderStatus::Codes::kOk); }); EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey)).Times(1); EXPECT_CALL(*this, OnDecoded(IsOkStatus()))
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc index 97add281..dddfd99 100644 --- a/media/mojo/clients/mojo_video_decoder.cc +++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -154,7 +154,7 @@ return decoder_type_; } -void MojoVideoDecoder::FailInit(InitCB init_cb, Status err) { +void MojoVideoDecoder::FailInit(InitCB init_cb, DecoderStatus err) { task_runner_->PostTask(FROM_HERE, base::BindOnce(std::move(init_cb), std::move(err))); } @@ -174,7 +174,7 @@ // Fail immediately if we know that the remote side cannot support |config|. if (gpu_factories_ && gpu_factories_->IsDecoderConfigSupported(config) == GpuVideoAcceleratorFactories::Supported::kFalse) { - FailInit(std::move(init_cb), StatusCode::kDecoderUnsupportedConfig); + FailInit(std::move(init_cb), DecoderStatus::Codes::kUnsupportedConfig); return; } @@ -189,7 +189,7 @@ if (config.is_encrypted() && !cdm_id) { DVLOG(1) << __func__ << ": Invalid CdmContext."; FailInit(std::move(init_cb), - StatusCode::kDecoderMissingCdmForEncryptedContent); + DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -214,7 +214,7 @@ absl::optional<base::UnguessableToken> cdm_id) { if (has_connection_error_) { DCHECK(init_cb_); - FailInit(std::move(init_cb_), StatusCode::kMojoDecoderNoConnection); + FailInit(std::move(init_cb_), DecoderStatus::Codes::kFailedToCreateDecoder); return; } @@ -224,11 +224,12 @@ base::Unretained(this))); } -void MojoVideoDecoder::OnInitializeDone(const Status& status, +void MojoVideoDecoder::OnInitializeDone(const DecoderStatus& status, bool needs_bitstream_conversion, int32_t max_decode_requests, VideoDecoderType decoder_type) { - DVLOG(1) << __func__ << ": status = " << std::hex << status.code(); + DVLOG(1) << __func__ << ": status = " << status.group() << ":" + << static_cast<int>(status.code()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); initialized_ = status.is_ok(); needs_bitstream_conversion_ = needs_bitstream_conversion; @@ -244,8 +245,8 @@ if (has_connection_error_) { task_runner_->PostTask( - FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + FROM_HERE, base::BindOnce(std::move(decode_cb), + DecoderStatus::Codes::kNotInitialized)); return; } @@ -260,7 +261,8 @@ ReportInitialPlaybackErrorUMA(); task_runner_->PostTask( FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + base::BindOnce(std::move(decode_cb), + DecoderStatus::Codes::kFailedToGetDecoderBuffer)); return; } @@ -317,7 +319,8 @@ } } -void MojoVideoDecoder::OnDecodeDone(uint64_t decode_id, const Status& status) { +void MojoVideoDecoder::OnDecodeDone(uint64_t decode_id, + const DecoderStatus& status) { DVLOG(3) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -328,7 +331,7 @@ return; } - if (!status.is_ok() && status.code() != StatusCode::kAborted) + if (!status.is_ok() && status.code() != DecoderStatus::Codes::kAborted) ReportInitialPlaybackErrorUMA(); DecodeCB decode_cb = std::move(it->second); @@ -492,13 +495,14 @@ base::WeakPtr<MojoVideoDecoder> weak_this = weak_this_; if (init_cb_) - std::move(init_cb_).Run(StatusCode::kMojoDecoderStoppedBeforeInitDone); + std::move(init_cb_).Run(DecoderStatus::Codes::kFailedToCreateDecoder); if (!weak_this) return; for (auto& pending_decode : pending_decodes_) { - std::move(pending_decode.second).Run(DecodeStatus::DECODE_ERROR); + // It would be ideal if we could get a reason for the interruption. + std::move(pending_decode.second).Run(DecoderStatus::Codes::kInterrupted); if (!weak_this) return; }
diff --git a/media/mojo/clients/mojo_video_decoder.h b/media/mojo/clients/mojo_video_decoder.h index a5be6e7f..6f1df825 100644 --- a/media/mojo/clients/mojo_video_decoder.h +++ b/media/mojo/clients/mojo_video_decoder.h
@@ -91,12 +91,12 @@ } private: - void FailInit(InitCB init_cb, Status err); - void OnInitializeDone(const Status& status, + void FailInit(InitCB init_cb, DecoderStatus err); + void OnInitializeDone(const DecoderStatus& status, bool needs_bitstream_conversion, int32_t max_decode_requests, VideoDecoderType decoder_type); - void OnDecodeDone(uint64_t decode_id, const Status& status); + void OnDecodeDone(uint64_t decode_id, const DecoderStatus& status); void OnResetDone(); void InitAndBindRemoteDecoder(base::OnceClosure complete_cb);
diff --git a/media/mojo/mojom/BUILD.gn b/media/mojo/mojom/BUILD.gn index 16e65798..b0cd457e 100644 --- a/media/mojo/mojom/BUILD.gn +++ b/media/mojo/mojom/BUILD.gn
@@ -368,6 +368,10 @@ mojom = "media.mojom.EncoderStatus" cpp = "::media::EncoderStatus" }, + { + mojom = "media.mojom.DecoderStatus" + cpp = "::media::DecoderStatus" + }, ] traits_headers = [ "status_mojom_traits.h" ] traits_sources = [ "status_mojom_traits.cc" ]
diff --git a/media/mojo/mojom/audio_decoder.mojom b/media/mojo/mojom/audio_decoder.mojom index 25029a8..7c9fb8a 100644 --- a/media/mojo/mojom/audio_decoder.mojom +++ b/media/mojo/mojom/audio_decoder.mojom
@@ -20,7 +20,7 @@ // bitstream conversion. Initialize(AudioDecoderConfig config, mojo_base.mojom.UnguessableToken? cdm_id) - => (Status success, + => (DecoderStatus success, bool needs_bitstream_conversion, AudioDecoderType decoder_type); @@ -35,7 +35,7 @@ // pending buffers should be processed, the corresponding decoded buffers // should be returned to the proxy, and only then the service should return // DecoderStatus. - Decode(DecoderBuffer buffer) => (Status status); + Decode(DecoderBuffer buffer) => (DecoderStatus status); // Resets decoder state. Should be called only if Initialize() succeeds. // All pending Decode() requests will be finished or aborted, then the method
diff --git a/media/mojo/mojom/media_types.mojom b/media/mojo/mojom/media_types.mojom index 4020d63..2769288 100644 --- a/media/mojo/mojom/media_types.mojom +++ b/media/mojo/mojom/media_types.mojom
@@ -30,10 +30,6 @@ [Native] enum ChannelLayout; -// See media/base/decode_status.h for descriptions. -[Native] -enum DecodeStatus; - // See media/base/status_codes.h for descriptions. [Native] enum StatusCode; @@ -506,6 +502,10 @@ StatusData? internal; }; +struct DecoderStatus { + StatusData? internal; +}; + // Types of media stream, categorised by the media stream's source. // The enum values are emitted to metrics. Do not reorder. enum MediaStreamType {
diff --git a/media/mojo/mojom/status_mojom_traits.h b/media/mojo/mojom/status_mojom_traits.h index 116cf34..ed8bb28 100644 --- a/media/mojo/mojom/status_mojom_traits.h +++ b/media/mojo/mojom/status_mojom_traits.h
@@ -7,6 +7,7 @@ #include "base/containers/span.h" #include "base/values.h" +#include "media/base/decoder_status.h" #include "media/base/encoder_status.h" #include "media/base/ipc/media_param_traits.h" #include "media/base/status.h"
diff --git a/media/mojo/mojom/video_decoder.mojom b/media/mojo/mojom/video_decoder.mojom index 3cfe796..46867aa 100644 --- a/media/mojo/mojom/video_decoder.mojom +++ b/media/mojo/mojom/video_decoder.mojom
@@ -119,7 +119,7 @@ // used for unencrypted streams. Initialize(VideoDecoderConfig config, bool low_delay, mojo_base.mojom.UnguessableToken? cdm_id) - => (Status status, + => (DecoderStatus status, bool needs_bitstream_conversion, int32 max_decode_requests, VideoDecoderType decoder_type); @@ -136,7 +136,7 @@ // If |buffer| is an EOS buffer, implementations must execute all other // pending Decode() callbacks and output all pending frames before executing // the Decode(EOS) callback. (That is, they must flush.) - Decode(DecoderBuffer buffer) => (Status status); + Decode(DecoderBuffer buffer) => (DecoderStatus status); // Reset the decoder. All ongoing Decode() requests must be completed or // aborted before executing the callback. This must not be called while there
diff --git a/media/mojo/services/mojo_audio_decoder_service.cc b/media/mojo/services/mojo_audio_decoder_service.cc index 9cf0a5e..654c3c3d0 100644 --- a/media/mojo/services/mojo_audio_decoder_service.cc +++ b/media/mojo/services/mojo_audio_decoder_service.cc
@@ -54,7 +54,7 @@ // TODO(xhwang): Replace with mojo::ReportBadMessage(). NOTREACHED() << "The caller should not switch CDM"; OnInitialized(std::move(callback), - StatusCode::kDecoderMissingCdmForEncryptedContent); + DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } } @@ -68,7 +68,7 @@ << CdmContext::CdmIdToString(base::OptionalOrNullptr(cdm_id)) << " not found for encrypted audio"; OnInitialized(std::move(callback), - StatusCode::kDecoderMissingCdmForEncryptedContent); + DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -107,7 +107,7 @@ } void MojoAudioDecoderService::OnInitialized(InitializeCallback callback, - Status status) { + DecoderStatus status) { DVLOG(1) << __func__ << " success:" << status.is_ok(); if (!status.is_ok()) { @@ -132,7 +132,7 @@ DVLOG(3) << __func__ << " success:" << !!buffer; if (!buffer) { - std::move(callback).Run(DecodeStatus::DECODE_ERROR); + std::move(callback).Run(DecoderStatus::Codes::kFailedToGetDecoderBuffer); return; } @@ -147,8 +147,9 @@ } void MojoAudioDecoderService::OnDecodeStatus(DecodeCallback callback, - const Status status) { - DVLOG(3) << __func__ << " status:" << status.code(); + const DecoderStatus status) { + DVLOG(3) << __func__ << " status=" << status.group() << ":" + << static_cast<int>(status.code()); std::move(callback).Run(std::move(status)); }
diff --git a/media/mojo/services/mojo_audio_decoder_service.h b/media/mojo/services/mojo_audio_decoder_service.h index 4a2a3d2..ab0c9af4 100644 --- a/media/mojo/services/mojo_audio_decoder_service.h +++ b/media/mojo/services/mojo_audio_decoder_service.h
@@ -51,7 +51,7 @@ private: // Called by |decoder_| upon finishing initialization. - void OnInitialized(InitializeCallback callback, Status status); + void OnInitialized(InitializeCallback callback, DecoderStatus status); // Called by |mojo_decoder_buffer_reader_| when read is finished. void OnReadDone(DecodeCallback callback, scoped_refptr<DecoderBuffer> buffer); @@ -60,7 +60,7 @@ void OnReaderFlushDone(ResetCallback callback); // Called by |decoder_| when DecoderBuffer is accepted or rejected. - void OnDecodeStatus(DecodeCallback callback, media::Status status); + void OnDecodeStatus(DecodeCallback callback, DecoderStatus status); // Called by |decoder_| when reset sequence is finished. void OnResetDone(ResetCallback callback);
diff --git a/media/mojo/services/mojo_video_decoder_service.cc b/media/mojo/services/mojo_video_decoder_service.cc index 8f9a1b6..4369bc4 100644 --- a/media/mojo/services/mojo_video_decoder_service.cc +++ b/media/mojo/services/mojo_video_decoder_service.cc
@@ -112,9 +112,7 @@ DVLOG(1) << __func__; if (init_cb_) { - OnDecoderInitialized( - Status(StatusCode::kMojoDecoderDeletedWithoutInitialization) - .WithData("decoder", "MojoVideoDecoder")); + OnDecoderInitialized(DecoderStatus::Codes::kInterrupted); } if (reset_cb_) @@ -199,7 +197,7 @@ init_cb_ = std::move(callback); if (!decoder_) { - OnDecoderInitialized(StatusCode::kMojoDecoderNoWrappedDecoder); + OnDecoderInitialized(DecoderStatus::Codes::kFailedToCreateDecoder); return; } @@ -215,7 +213,7 @@ } else if (cdm_id != cdm_id_) { // TODO(xhwang): Replace with mojo::ReportBadMessage(). NOTREACHED() << "The caller should not switch CDM"; - OnDecoderInitialized(StatusCode::kDecoderMissingCdmForEncryptedContent); + OnDecoderInitialized(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } } @@ -228,7 +226,7 @@ DVLOG(1) << "CdmContext for " << CdmContext::CdmIdToString(base::OptionalOrNullptr(cdm_id)) << " not found for encrypted video"; - OnDecoderInitialized(StatusCode::kDecoderMissingCdmForEncryptedContent); + OnDecoderInitialized(DecoderStatus::Codes::kUnsupportedEncryptionMode); return; } @@ -267,7 +265,7 @@ if (!decoder_) { OnDecoderDecoded(std::move(callback), std::move(trace_event), - DecodeStatus::DECODE_ERROR); + DecoderStatus::Codes::kNotInitialized); return; } @@ -310,7 +308,7 @@ base::BindOnce(&MojoVideoDecoderService::OnReaderFlushed, weak_this_)); } -void MojoVideoDecoderService::OnDecoderInitialized(Status status) { +void MojoVideoDecoderService::OnDecoderInitialized(DecoderStatus status) { DVLOG(1) << __func__; DCHECK(!status.is_ok() || decoder_); DCHECK(init_cb_); @@ -341,7 +339,7 @@ if (!buffer) { OnDecoderDecoded(std::move(callback), std::move(trace_event), - DecodeStatus::DECODE_ERROR); + DecoderStatus::Codes::kFailedToGetDecoderBuffer); return; } @@ -359,7 +357,7 @@ void MojoVideoDecoderService::OnDecoderDecoded( DecodeCallback callback, std::unique_ptr<ScopedDecodeTrace> trace_event, - media::Status status) { + media::DecoderStatus status) { DVLOG(3) << __func__; if (trace_event) { TRACE_EVENT_ASYNC_STEP_PAST0("media", kDecodeTraceName, trace_event.get(),
diff --git a/media/mojo/services/mojo_video_decoder_service.h b/media/mojo/services/mojo_video_decoder_service.h index ddadc6d..df1820bf4 100644 --- a/media/mojo/services/mojo_video_decoder_service.h +++ b/media/mojo/services/mojo_video_decoder_service.h
@@ -13,7 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/unguessable_token.h" #include "media/base/cdm_context.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/overlay_info.h" #include "media/base/video_decoder.h" #include "media/mojo/mojom/video_decoder.mojom.h" @@ -70,13 +70,13 @@ // running mojom::VideoDecoder callbacks after connection error happens and // |this| is deleted. It's not safe to run the callbacks after a connection // error. - void OnDecoderInitialized(Status status); + void OnDecoderInitialized(DecoderStatus status); void OnReaderRead(DecodeCallback callback, std::unique_ptr<ScopedDecodeTrace> trace_event, scoped_refptr<DecoderBuffer> buffer); void OnDecoderDecoded(DecodeCallback callback, std::unique_ptr<ScopedDecodeTrace> trace_event, - media::Status status); + DecoderStatus status); // Called by |mojo_decoder_buffer_reader_| when reset is finished. void OnReaderFlushed();
diff --git a/media/mojo/test/mojo_video_decoder_integration_test.cc b/media/mojo/test/mojo_video_decoder_integration_test.cc index 6c45ea9..a6b6c45 100644 --- a/media/mojo/test/mojo_video_decoder_integration_test.cc +++ b/media/mojo/test/mojo_video_decoder_integration_test.cc
@@ -21,8 +21,8 @@ #include "base/test/task_environment.h" #include "base/time/time.h" #include "gpu/command_buffer/common/mailbox_holder.h" -#include "media/base/decode_status.h" #include "media/base/decoder_buffer.h" +#include "media/base/decoder_status.h" #include "media/base/decrypt_config.h" #include "media/base/media_log.h" #include "media/base/mock_media_log.h" @@ -133,8 +133,8 @@ // This size buffer indicates that decoder should return an error. // |decode_cb| must not be called from the same stack. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + FROM_HERE, base::BindOnce(std::move(decode_cb), + DecoderStatus::Codes::kFailed)); return; } if (buffer->decrypt_config()) { @@ -154,7 +154,8 @@ // |decode_cb| must not be called from the same stack. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(decode_cb), DecodeStatus::OK)); + FROM_HERE, + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kOk)); } void DoReset(base::OnceClosure& reset_cb) { @@ -249,9 +250,9 @@ CreateClient(); EXPECT_CALL(*decoder_, DoInitialize(_)) - .WillOnce(RunOnceCallback<0>(OkStatus())); + .WillOnce(RunOnceCallback<0>(DecoderStatus::Codes::kOk)); - Status result = OkStatus(); + DecoderStatus result = DecoderStatus::Codes::kOk; StrictMock<base::MockCallback<VideoDecoder::InitCB>> init_cb; EXPECT_CALL(init_cb, Run(_)).WillOnce(SaveArg<0>(&result)); @@ -263,10 +264,10 @@ return result.is_ok(); } - Status Decode(scoped_refptr<DecoderBuffer> buffer, - VideoFrame::ReleaseMailboxCB release_cb = - VideoFrame::ReleaseMailboxCB()) { - Status result(DecodeStatus::DECODE_ERROR); + DecoderStatus Decode(scoped_refptr<DecoderBuffer> buffer, + VideoFrame::ReleaseMailboxCB release_cb = + VideoFrame::ReleaseMailboxCB()) { + DecoderStatus result(DecoderStatus::Codes::kFailed); if (!buffer->end_of_stream()) { decoder_->release_mailbox_cb = std::move(release_cb); @@ -397,7 +398,7 @@ StrictMock<base::MockCallback<VideoDecoder::InitCB>> init_cb; EXPECT_CALL(init_cb, - Run(HasStatusCode(StatusCode::kMojoDecoderNoWrappedDecoder))); + Run(HasStatusCode(DecoderStatus::Codes::kFailedToCreateDecoder))); // Clear |decoder_| so that Initialize() should fail. decoder_owner_.reset(); @@ -412,7 +413,7 @@ StrictMock<base::MockCallback<VideoDecoder::InitCB>> init_cb; EXPECT_CALL( init_cb, - Run(HasStatusCode(StatusCode::kDecoderMissingCdmForEncryptedContent))); + Run(HasStatusCode(DecoderStatus::Codes::kUnsupportedEncryptionMode))); // CdmContext* (3rd parameter) is not provided but the VideoDecoderConfig // specifies encrypted video, so Initialize() should fail.
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc index b70d91be9..18497f98 100644 --- a/media/renderers/audio_renderer_impl.cc +++ b/media/renderers/audio_renderer_impl.cc
@@ -832,7 +832,7 @@ void AudioRendererImpl::DecodedAudioReady( AudioDecoderStream::ReadResult result) { - DVLOG(2) << __func__ << "(" << result.code() << ")"; + DVLOG(2) << __func__ << "(" << static_cast<int>(result.code()) << ")"; DCHECK(task_runner_->BelongsToCurrentThread()); base::AutoLock auto_lock(lock_); @@ -842,7 +842,8 @@ pending_read_ = false; if (result.has_error()) { - HandleAbortedReadOrDecodeError(result.code() == StatusCode::kAborted + HandleAbortedReadOrDecodeError(result.code() == + DecoderStatus::Codes::kAborted ? PIPELINE_OK : PIPELINE_ERROR_DECODE); return;
diff --git a/media/renderers/audio_renderer_impl.h b/media/renderers/audio_renderer_impl.h index fe6d6ba..e8ca040d 100644 --- a/media/renderers/audio_renderer_impl.h +++ b/media/renderers/audio_renderer_impl.h
@@ -116,7 +116,7 @@ bool was_unmuted_for_testing() const { return was_unmuted_; } void decoded_audio_ready_for_testing() { - DecodedAudioReady(StatusCode::kCodeOnlyForTesting); + DecodedAudioReady(DecoderStatus::Codes::kFailed); } private:
diff --git a/media/renderers/audio_renderer_impl_unittest.cc b/media/renderers/audio_renderer_impl_unittest.cc index ca882f7..d653a428 100644 --- a/media/renderers/audio_renderer_impl_unittest.cc +++ b/media/renderers/audio_renderer_impl_unittest.cc
@@ -96,11 +96,11 @@ auto decoder = std::make_unique<MockAudioDecoder>(); if (!enter_pending_decoder_init_) { EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _)) - .WillOnce(DoAll(SaveArg<3>(&output_cb_), - RunOnceCallback<2>( - expected_init_result_ - ? OkStatus() - : Status(StatusCode::kCodeOnlyForTesting)))); + .WillOnce( + DoAll(SaveArg<3>(&output_cb_), + RunOnceCallback<2>(expected_init_result_ + ? DecoderStatus::Codes::kOk + : DecoderStatus::Codes::kFailed))); } else { EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _)) .WillOnce(EnterPendingDecoderInitStateAction(this)); @@ -393,7 +393,7 @@ } next_timestamp_->AddFrames(frames.value); - DeliverBuffer(DecodeStatus::OK, std::move(buffer)); + DeliverBuffer(DecoderStatus::Codes::kOk, std::move(buffer)); } void DeliverEndOfStream() { @@ -406,12 +406,14 @@ // Satify pending |decode_cb_| to trigger a new DemuxerStream::Read(). main_thread_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(decode_cb_), DecodeStatus::OK)); + FROM_HERE, + base::BindOnce(std::move(decode_cb_), DecoderStatus::Codes::kOk)); WaitForPendingRead(); main_thread_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(decode_cb_), DecodeStatus::OK)); + FROM_HERE, + base::BindOnce(std::move(decode_cb_), DecoderStatus::Codes::kOk)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(last_statistics_.audio_memory_usage, @@ -566,7 +568,7 @@ main_thread_task_runner_->PostTask(FROM_HERE, std::move(reset_cb)); } - void DeliverBuffer(DecodeStatus status, scoped_refptr<AudioBuffer> buffer) { + void DeliverBuffer(DecoderStatus status, scoped_refptr<AudioBuffer> buffer) { CHECK(decode_cb_); if (buffer.get() && !buffer->end_of_stream()) @@ -914,7 +916,7 @@ scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>( kSampleFormat, hw_params.channel_layout(), hw_params.channels(), kInputSamplesPerSecond, 1.0f, 0.0f, kInputFramesChunk, base::TimeDelta()); - DeliverBuffer(DecodeStatus::OK, std::move(buffer)); + DeliverBuffer(DecoderStatus::Codes::kOk, std::move(buffer)); // All channels should now be enabled. mask = channel_mask();
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc index 39d1cd2..8caba70 100644 --- a/media/renderers/video_renderer_impl.cc +++ b/media/renderers/video_renderer_impl.cc
@@ -565,9 +565,9 @@ // Can happen when demuxers are preparing for a new Seek(). switch (result.code()) { - case StatusCode::kOk: + case DecoderStatus::Codes::kOk: break; - case StatusCode::kAborted: + case DecoderStatus::Codes::kAborted: // TODO(liberato): This used to check specifically for the value // DEMUXER_READ_ABORTED, which was more specific than |kAborted|. // However, since it's a dcheck, this seems okay.
diff --git a/media/renderers/video_renderer_impl_unittest.cc b/media/renderers/video_renderer_impl_unittest.cc index e3f19767..fc27abab 100644 --- a/media/renderers/video_renderer_impl_unittest.cc +++ b/media/renderers/video_renderer_impl_unittest.cc
@@ -65,11 +65,11 @@ std::vector<std::unique_ptr<VideoDecoder>> decoders; decoders.push_back(base::WrapUnique(decoder_.get())); ON_CALL(*decoder_, Initialize_(_, _, _, _, _, _)) - .WillByDefault(DoAll( - SaveArg<4>(&output_cb_), - RunOnceCallback<3>(expect_init_success_ - ? OkStatus() - : Status(StatusCode::kCodeOnlyForTesting)))); + .WillByDefault( + DoAll(SaveArg<4>(&output_cb_), + RunOnceCallback<3>(expect_init_success_ + ? DecoderStatus::Codes::kOk + : DecoderStatus::Codes::kFailed))); // Monitor decodes from the decoder. ON_CALL(*decoder_, Decode_(_, _)) .WillByDefault(Invoke(this, &VideoRendererImplTest::DecodeRequested)); @@ -220,13 +220,13 @@ base::SPLIT_WANT_ALL)) { if (token == "abort") { scoped_refptr<VideoFrame> null_frame; - QueueFrame(DecodeStatus::ABORTED, null_frame); + QueueFrame(DecoderStatus::Codes::kAborted, null_frame); continue; } if (token == "error") { scoped_refptr<VideoFrame> null_frame; - QueueFrame(DecodeStatus::DECODE_ERROR, null_frame); + QueueFrame(DecoderStatus::Codes::kFailed, null_frame); continue; } @@ -236,7 +236,7 @@ scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( PIXEL_FORMAT_I420, natural_size, gfx::Rect(natural_size), natural_size, base::Milliseconds(timestamp_in_ms)); - QueueFrame(DecodeStatus::OK, frame); + QueueFrame(DecoderStatus::Codes::kOk, frame); continue; } @@ -245,7 +245,7 @@ } // Queues video frames to be served by the decoder during rendering. - void QueueFrame(DecodeStatus status, scoped_refptr<VideoFrame> frame) { + void QueueFrame(DecoderStatus status, scoped_refptr<VideoFrame> frame) { decode_results_.push_back(std::make_pair(status, frame)); } @@ -312,12 +312,14 @@ // Satify pending |decode_cb_| to trigger a new DemuxerStream::Read(). task_environment_.GetMainThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(std::move(decode_cb_), DecodeStatus::OK)); + FROM_HERE, + base::BindOnce(std::move(decode_cb_), DecoderStatus::Codes::kOk)); WaitForPendingDecode(); task_environment_.GetMainThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(std::move(decode_cb_), DecodeStatus::OK)); + FROM_HERE, + base::BindOnce(std::move(decode_cb_), DecoderStatus::Codes::kOk)); } bool HasQueuedFrames() const { return decode_results_.size() > 0; } @@ -419,7 +421,7 @@ // Run during DecodeRequested() to unblock WaitForPendingDecode(). base::OnceClosure wait_for_pending_decode_cb_; - base::circular_deque<std::pair<DecodeStatus, scoped_refptr<VideoFrame>>> + base::circular_deque<std::pair<DecoderStatus, scoped_refptr<VideoFrame>>> decode_results_; }; @@ -476,7 +478,7 @@ Initialize(); StartPlayingFrom(10000); QueueFrames("0"); - QueueFrame(DecodeStatus::OK, VideoFrame::CreateEOSFrame()); + QueueFrame(DecoderStatus::Codes::kOk, VideoFrame::CreateEOSFrame()); WaitForPendingDecode(); { SCOPED_TRACE("Waiting for BUFFERING_HAVE_ENOUGH"); @@ -1015,19 +1017,19 @@ gfx::Size initial_size(8, 8); gfx::Size larger_size(16, 16); - QueueFrame(DecodeStatus::OK, + QueueFrame(DecoderStatus::Codes::kOk, VideoFrame::CreateFrame(PIXEL_FORMAT_I420, initial_size, gfx::Rect(initial_size), initial_size, base::Milliseconds(0))); - QueueFrame(DecodeStatus::OK, + QueueFrame(DecoderStatus::Codes::kOk, VideoFrame::CreateFrame(PIXEL_FORMAT_I420, larger_size, gfx::Rect(larger_size), larger_size, base::Milliseconds(10))); - QueueFrame(DecodeStatus::OK, + QueueFrame(DecoderStatus::Codes::kOk, VideoFrame::CreateFrame(PIXEL_FORMAT_I420, larger_size, gfx::Rect(larger_size), larger_size, base::Milliseconds(20))); - QueueFrame(DecodeStatus::OK, + QueueFrame(DecoderStatus::Codes::kOk, VideoFrame::CreateFrame(PIXEL_FORMAT_I420, initial_size, gfx::Rect(initial_size), initial_size, base::Milliseconds(30))); @@ -1081,20 +1083,20 @@ VideoPixelFormat opaque_format = PIXEL_FORMAT_I420; VideoPixelFormat non_opaque_format = PIXEL_FORMAT_I420A; - QueueFrame(DecodeStatus::OK, + QueueFrame(DecoderStatus::Codes::kOk, VideoFrame::CreateFrame(non_opaque_format, frame_size, gfx::Rect(frame_size), frame_size, base::Milliseconds(0))); - QueueFrame(DecodeStatus::OK, + QueueFrame(DecoderStatus::Codes::kOk, VideoFrame::CreateFrame(non_opaque_format, frame_size, gfx::Rect(frame_size), frame_size, base::Milliseconds(10))); QueueFrame( - DecodeStatus::OK, + DecoderStatus::Codes::kOk, VideoFrame::CreateFrame(opaque_format, frame_size, gfx::Rect(frame_size), frame_size, base::Milliseconds(20))); QueueFrame( - DecodeStatus::OK, + DecoderStatus::Codes::kOk, VideoFrame::CreateFrame(opaque_format, frame_size, gfx::Rect(frame_size), frame_size, base::Milliseconds(30)));
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc index 73f57b5..43f4a6d 100644 --- a/media/test/pipeline_integration_test.cc +++ b/media/test/pipeline_integration_test.cc
@@ -363,13 +363,13 @@ InitCB init_cb, const OutputCB& output_cb, const WaitingCB& waiting_cb) override { - std::move(init_cb).Run(OkStatus()); + std::move(init_cb).Run(DecoderStatus::Codes::kOk); } void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR)); + base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kFailed)); } void Reset(base::OnceClosure closure) override { std::move(closure).Run(); } bool NeedsBitstreamConversion() const override { return true; }
diff --git a/media/video/software_video_encoder_test.cc b/media/video/software_video_encoder_test.cc index 2041aa9..374323c 100644 --- a/media/video/software_video_encoder_test.cc +++ b/media/video/software_video_encoder_test.cc
@@ -219,10 +219,10 @@ auto enforcer = std::make_unique<CallEnforcer>(); enforcer->location = loc.ToString(); return base::BindLambdaForTesting( - [enforcer{std::move(enforcer)}](Status s) { - EXPECT_TRUE(s.is_ok()) - << " Callback created: " << enforcer->location - << " Code: " << s.code() << " Error: " << s.message(); + [enforcer{std::move(enforcer)}](DecoderStatus s) { + EXPECT_TRUE(s.is_ok()) << " Callback created: " << enforcer->location + << " Code: " << static_cast<int>(s.code()) + << " Error: " << s.message(); enforcer->called = true; }); } @@ -231,13 +231,14 @@ scoped_refptr<DecoderBuffer> buffer, const base::Location& location = base::Location::Current()) { base::RunLoop run_loop; - decoder_->Decode( - std::move(buffer), base::BindLambdaForTesting([&](Status status) { - EXPECT_TRUE(status.is_ok()) - << " Callback created: " << location.ToString() - << " Code: " << status.code() << " Error: " << status.message(); - run_loop.Quit(); - })); + decoder_->Decode(std::move(buffer), + base::BindLambdaForTesting([&](DecoderStatus status) { + EXPECT_TRUE(status.is_ok()) + << " Callback created: " << location.ToString() + << " Code: " << static_cast<int>(status.code()) + << " Error: " << status.message(); + run_loop.Quit(); + })); run_loop.Run(location); }
diff --git a/media/video/video_decode_accelerator.cc b/media/video/video_decode_accelerator.cc index 78171dc..c353138 100644 --- a/media/video/video_decode_accelerator.cc +++ b/media/video/video_decode_accelerator.cc
@@ -28,7 +28,7 @@ } void VideoDecodeAccelerator::Client::NotifyInitializationComplete( - Status status) { + DecoderStatus status) { NOTREACHED() << "By default deferred initialization is not supported."; }
diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index 12a0c37b..2ea21479 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h
@@ -16,9 +16,9 @@ #include "media/base/bitstream_buffer.h" #include "media/base/cdm_context.h" #include "media/base/decoder_buffer.h" +#include "media/base/decoder_status.h" #include "media/base/encryption_scheme.h" #include "media/base/overlay_info.h" -#include "media/base/status.h" #include "media/base/video_decoder_config.h" #include "media/video/picture.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -207,7 +207,7 @@ // call to VDA::Initialize returns true. // The default implementation is a NOTREACHED, since deferred initialization // is not supported by default. - virtual void NotifyInitializationComplete(Status status); + virtual void NotifyInitializationComplete(DecoderStatus status); // Callback to tell client how many and what size of buffers to provide. // Note that the actual count provided through AssignPictureBuffers() can be
diff --git a/mojo/core/node_channel.cc b/mojo/core/node_channel.cc index 88d74742..430dcb86 100644 --- a/mojo/core/node_channel.cc +++ b/mojo/core/node_channel.cc
@@ -251,7 +251,7 @@ Channel::HandlePolicy channel_handle_policy, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, const ProcessErrorCallback& process_error_callback) { -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) LOG(FATAL) << "Multi-process not yet supported on NaCl-SFI"; return nullptr; #else @@ -540,7 +540,7 @@ : base::RefCountedDeleteOnSequence<NodeChannel>(io_task_runner), delegate_(delegate), process_error_callback_(process_error_callback) -#if !defined(OS_NACL_SFI) +#if !defined(OS_NACL) , channel_(Channel::Create(this, std::move(connection_params),
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc index 2e770c6..31edf52 100644 --- a/mojo/core/node_controller.cc +++ b/mojo/core/node_controller.cc
@@ -232,7 +232,7 @@ ConnectionParams connection_params) { absl::optional<PlatformHandle> broker_host_handle; DCHECK(!GetConfiguration().is_broker_process); -#if !defined(OS_APPLE) && !defined(OS_NACL_SFI) && !defined(OS_FUCHSIA) +#if !defined(OS_APPLE) && !defined(OS_NACL) && !defined(OS_FUCHSIA) if (!connection_params.is_async()) { // Use the bootstrap channel for the broker and receive the node's channel // synchronously as the first message from the broker. @@ -342,7 +342,7 @@ base::WritableSharedMemoryRegion NodeController::CreateSharedBuffer( size_t num_bytes) { -#if !defined(OS_APPLE) && !defined(OS_NACL_SFI) && !defined(OS_FUCHSIA) +#if !defined(OS_APPLE) && !defined(OS_NACL) && !defined(OS_FUCHSIA) // Shared buffer creation failure is fatal, so always use the broker when we // have one; unless of course the embedder forces us not to. if (!GetConfiguration().force_direct_shared_memory_allocation && broker_)
diff --git a/mojo/core/node_controller.h b/mojo/core/node_controller.h index e49e5734..4df63bde 100644 --- a/mojo/core/node_controller.h +++ b/mojo/core/node_controller.h
@@ -361,7 +361,7 @@ // Must only be accessed from the IO thread. bool destroy_on_io_thread_shutdown_ = false; -#if !defined(OS_APPLE) && !defined(OS_NACL_SFI) && !defined(OS_FUCHSIA) +#if !defined(OS_APPLE) && !defined(OS_NACL) && !defined(OS_FUCHSIA) // Broker for sync shared buffer creation on behalf of broker clients. std::unique_ptr<Broker> broker_; #endif
diff --git a/mojo/public/cpp/platform/platform_channel.cc b/mojo/public/cpp/platform/platform_channel.cc index f72b1ed3a..bf619c9f 100644 --- a/mojo/public/cpp/platform/platform_channel.cc +++ b/mojo/public/cpp/platform/platform_channel.cc
@@ -44,9 +44,9 @@ #include "base/mac/scoped_mach_port.h" #endif -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) +#if defined(OS_POSIX) && !defined(OS_NACL) #include <sys/socket.h> -#elif defined(OS_NACL_SFI) +#elif defined(OS_NACL) #include "native_client/src/public/imc_syscalls.h" #endif @@ -143,7 +143,7 @@ void CreateChannel(PlatformHandle* local_endpoint, PlatformHandle* remote_endpoint) { int fds[2]; -#if defined(OS_NACL_SFI) +#if defined(OS_NACL) PCHECK(imc_socketpair(fds) == 0); #else PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); @@ -162,7 +162,7 @@ PCHECK(setsockopt(fds[1], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe)) == 0); #endif // defined(OS_APPLE) -#endif // defined(OS_NACL_SFI) +#endif // defined(OS_NACL) *local_endpoint = PlatformHandle(base::ScopedFD(fds[0])); *remote_endpoint = PlatformHandle(base::ScopedFD(fds[1]));
diff --git a/net/http/http_stream_factory_job_controller_unittest.cc b/net/http/http_stream_factory_job_controller_unittest.cc index ecb04564..73b8ac12 100644 --- a/net/http/http_stream_factory_job_controller_unittest.cc +++ b/net/http/http_stream_factory_job_controller_unittest.cc
@@ -78,23 +78,6 @@ const char kServerHostname[] = "www.example.com"; -// List of errors for which fallback is expected on an HTTPS proxy. -// -// We omit `ERR_CONNECTION_CLOSED` because it is largely unreachable. The -// HTTP/1.1 parser maps it to `ERR_EMPTY_RESPONSE` or -// `ERR_RESPONSE_HEADERS_TRUNCATED` in most cases. -// -// TODO(davidben): Is omitting `ERR_EMPTY_RESPONSE` a bug in proxy error -// handling? -const int proxy_test_mock_errors[] = { - ERR_PROXY_CONNECTION_FAILED, ERR_NAME_NOT_RESOLVED, - ERR_ADDRESS_UNREACHABLE, ERR_CONNECTION_TIMED_OUT, - ERR_CONNECTION_RESET, ERR_CONNECTION_REFUSED, - ERR_CONNECTION_ABORTED, ERR_TIMED_OUT, - ERR_SOCKS_CONNECTION_FAILED, ERR_PROXY_CERTIFICATE_INVALID, - ERR_SSL_PROTOCOL_ERROR, -}; - class FailingProxyResolverFactory : public ProxyResolverFactory { public: FailingProxyResolverFactory() : ProxyResolverFactory(false) {} @@ -205,6 +188,18 @@ : TestWithTaskEnvironment( base::test::TaskEnvironment::TimeSource::MOCK_TIME) { FLAGS_quic_enable_http3_grease_randomness = false; + CreateSessionDeps(); + } + + // Creates / re-creates `session_deps_`, and clears test fixture fields + // referencing it. + void CreateSessionDeps() { + factory_ = nullptr; + job_controller_ = nullptr; + session_.reset(); + + session_deps_ = SpdySessionDependencies( + ConfiguredProxyResolutionService::CreateDirect()); session_deps_.enable_quic = true; session_deps_.host_resolver->set_synchronous_mode(true); } @@ -338,8 +333,7 @@ TestJobFactory job_factory_; MockHttpStreamRequestDelegate request_delegate_; MockQuicContext quic_context_; - SpdySessionDependencies session_deps_{ - ConfiguredProxyResolutionService::CreateDirect()}; + SpdySessionDependencies session_deps_; std::unique_ptr<HttpNetworkSession> session_; raw_ptr<HttpStreamFactory> factory_ = nullptr; raw_ptr<HttpStreamFactory::JobController> job_controller_ = nullptr; @@ -470,8 +464,7 @@ } class JobControllerReconsiderProxyAfterErrorTest - : public HttpStreamFactoryJobControllerTest, - public ::testing::WithParamInterface<int> { + : public HttpStreamFactoryJobControllerTest { public: void Initialize( std::unique_ptr<ProxyResolutionService> proxy_resolution_service) { @@ -503,104 +496,546 @@ HttpStreamFactory::JobFactory default_job_factory_; }; -INSTANTIATE_TEST_SUITE_P(All, - JobControllerReconsiderProxyAfterErrorTest, - testing::ValuesIn(proxy_test_mock_errors)); - +// Test proxy fallback logic in the case connecting through an HTTP proxy. +// // TODO(eroman): The testing should be expanded to test cases where proxy // fallback is NOT supposed to occur, and also vary across all of // the proxy types. -TEST_P(JobControllerReconsiderProxyAfterErrorTest, ReconsiderProxyAfterError) { - const int mock_error = GetParam(); - std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( - "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT", - TRAFFIC_ANNOTATION_FOR_TESTS); - auto test_proxy_delegate = std::make_unique<TestProxyDelegate>(); +TEST_F(JobControllerReconsiderProxyAfterErrorTest, + ReconsiderProxyAfterErrorHttpProxy) { + enum class ErrorPhase { + kHostResolution, + kTcpConnect, + kTunnelRead, + }; - // Before starting the test, verify that there are no proxies marked as bad. - ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty()) - << mock_error; + const struct { + ErrorPhase phase; + net::Error error; + } kRetriableErrors[] = { + // These largely correspond to the list of errors in + // CanFalloverToNextProxy() which can occur with an HTTP proxy. + // + // We omit `ERR_CONNECTION_CLOSED` because it is largely unreachable. The + // HTTP/1.1 parser maps it to `ERR_EMPTY_RESPONSE` or + // `ERR_RESPONSE_HEADERS_TRUNCATED` in most cases. + // + // TODO(davidben): Is omitting `ERR_EMPTY_RESPONSE` a bug in proxy error + // handling? + {ErrorPhase::kHostResolution, ERR_NAME_NOT_RESOLVED}, + {ErrorPhase::kTcpConnect, ERR_ADDRESS_UNREACHABLE}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_TIMED_OUT}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_RESET}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_ABORTED}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_REFUSED}, + {ErrorPhase::kTunnelRead, ERR_TIMED_OUT}, + {ErrorPhase::kTunnelRead, ERR_SSL_PROTOCOL_ERROR}, + }; - // Configure the HTTP CONNECT to fail with `mock_error`. - // - // TODO(crbug.com/1279685): Test this more accurately. Errors like - // `ERR_PROXY_CONNECTION_FAILED` or `ERR_PROXY_CERTIFICATE_INVALID` are - // surfaced in response to other errors in TCP or TLS connection setup. - SSLSocketDataProvider ssl_data(ASYNC, OK); - static constexpr char kHttpConnect[] = - "CONNECT www.example.com:443 HTTP/1.1\r\n" - "Host: www.example.com:443\r\n" - "Proxy-Connection: keep-alive\r\n\r\n"; - const MockWrite kWrites[] = {{ASYNC, kHttpConnect}}; - const MockRead kReads[] = {{ASYNC, mock_error}}; + for (GURL dest_url : + {GURL("http://www.example.com"), GURL("https://www.example.com")}) { + SCOPED_TRACE(dest_url); - StaticSocketDataProvider socket_data_proxy_main_job(kReads, kWrites); - socket_data_proxy_main_job.set_connect_data(MockConnect(ASYNC, OK)); - session_deps_.socket_factory->AddSocketDataProvider( - &socket_data_proxy_main_job); - session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); + for (const auto& mock_error : kRetriableErrors) { + SCOPED_TRACE(ErrorToString(mock_error.error)); - // When retrying the job using the second proxy (badfallback:98), - // alternative job must not be created. So, socket data for only the - // main job is needed. - StaticSocketDataProvider socket_data_proxy_main_job_2(kReads, kWrites); - socket_data_proxy_main_job_2.set_connect_data(MockConnect(ASYNC, OK)); - session_deps_.socket_factory->AddSocketDataProvider( - &socket_data_proxy_main_job_2); - session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); + CreateSessionDeps(); - // First request would use DIRECT, and succeed. For this and the second - // request, `ssl_data` is a connection to the HTTPS origin. For the first two, - // it is a connection to the HTTPS proxy. - StaticSocketDataProvider socket_data_direct_first_request; - socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK)); - session_deps_.socket_factory->AddSocketDataProvider( - &socket_data_direct_first_request); - session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); + std::unique_ptr<ConfiguredProxyResolutionService> + proxy_resolution_service = + ConfiguredProxyResolutionService::CreateFixedFromPacResult( + "PROXY badproxy:99; PROXY badfallbackproxy:98; DIRECT", + TRAFFIC_ANNOTATION_FOR_TESTS); + auto test_proxy_delegate = std::make_unique<TestProxyDelegate>(); - // Second request would use DIRECT, and succeed. - StaticSocketDataProvider socket_data_direct_second_request; - socket_data_direct_second_request.set_connect_data(MockConnect(ASYNC, OK)); - session_deps_.socket_factory->AddSocketDataProvider( - &socket_data_direct_second_request); - session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); + // Before starting the test, verify that there are no proxies marked as + // bad. + ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty()); - // Now request a stream. It should succeed using the DIRECT. - HttpRequestInfo request_info; - request_info.method = "GET"; - request_info.url = GURL("https://www.example.com"); + constexpr char kTunnelRequest[] = + "CONNECT www.example.com:443 HTTP/1.1\r\n" + "Host: www.example.com:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"; + const MockWrite kTunnelWrites[] = {{ASYNC, kTunnelRequest}}; + std::vector<MockRead> reads; - proxy_resolution_service->SetProxyDelegate(test_proxy_delegate.get()); - Initialize(std::move(proxy_resolution_service)); + // Generate identical errors for both the main proxy and the fallback + // proxy. No alternative job is created for either, so only need one data + // provider for each, when the request makes it to the socket layer. + std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job; + std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job2; + switch (mock_error.phase) { + case ErrorPhase::kHostResolution: + // Only ERR_NAME_NOT_RESOLVED can be returned by the mock host + // resolver. + DCHECK_EQ(ERR_NAME_NOT_RESOLVED, mock_error.error); + session_deps_.host_resolver->rules()->AddSimulatedFailure("badproxy"); + session_deps_.host_resolver->rules()->AddSimulatedFailure( + "badfallbackproxy"); + break; + case ErrorPhase::kTcpConnect: + socket_data_proxy_main_job = + std::make_unique<StaticSocketDataProvider>(); + socket_data_proxy_main_job->set_connect_data( + MockConnect(ASYNC, mock_error.error)); + socket_data_proxy_main_job2 = + std::make_unique<StaticSocketDataProvider>(); + socket_data_proxy_main_job2->set_connect_data( + MockConnect(ASYNC, mock_error.error)); + break; + case ErrorPhase::kTunnelRead: + // Tunnels aren't established for HTTP destinations. + if (dest_url.SchemeIs(url::kHttpScheme)) + continue; + reads.emplace_back(MockRead(ASYNC, mock_error.error)); + socket_data_proxy_main_job = + std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites); + socket_data_proxy_main_job2 = + std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites); + break; + } - // Start two requests. The first request should consume data from - // |socket_data_proxy_main_job| and |socket_data_direct_first_request|. The - // second request should consume data from - // |socket_data_direct_second_request|. + if (socket_data_proxy_main_job) { + session_deps_.socket_factory->AddSocketDataProvider( + socket_data_proxy_main_job.get()); + session_deps_.socket_factory->AddSocketDataProvider( + socket_data_proxy_main_job2.get()); + } - for (size_t i = 0; i < 2; ++i) { - ProxyInfo used_proxy_info; - EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) - .Times(1) - .WillOnce(::testing::SaveArg<1>(&used_proxy_info)); + // After both proxies fail, the request should fall back to using DIRECT, + // and succeed. + SSLSocketDataProvider ssl_data_first_request(ASYNC, OK); + StaticSocketDataProvider socket_data_direct_first_request; + socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK)); + session_deps_.socket_factory->AddSocketDataProvider( + &socket_data_direct_first_request); + // Only used in the HTTPS destination case, but harmless in the HTTP case. + session_deps_.socket_factory->AddSSLSocketDataProvider( + &ssl_data_first_request); - std::unique_ptr<HttpStreamRequest> request = - CreateJobController(request_info); - base::RunLoop().RunUntilIdle(); + // Second request should use DIRECT, skipping the bad proxies, and + // succeed. + SSLSocketDataProvider ssl_data_second_request(ASYNC, OK); + StaticSocketDataProvider socket_data_direct_second_request; + socket_data_direct_second_request.set_connect_data( + MockConnect(ASYNC, OK)); + session_deps_.socket_factory->AddSocketDataProvider( + &socket_data_direct_second_request); + // Only used in the HTTPS destination case, but harmless in the HTTP case. + session_deps_.socket_factory->AddSSLSocketDataProvider( + &ssl_data_second_request); - // Verify that request was fetched without proxy. - EXPECT_TRUE(used_proxy_info.is_direct()); + // Now request a stream. It should succeed using the DIRECT fallback proxy + // option. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = dest_url; - // The proxies that failed should now be known to the proxy service as - // bad. - const ProxyRetryInfoMap& retry_info = - session_->proxy_resolution_service()->proxy_retry_info(); - ASSERT_THAT(retry_info, SizeIs(2)); - EXPECT_THAT(retry_info, Contains(Key("https://badproxy:99"))); - EXPECT_THAT(retry_info, Contains(Key("https://badfallbackproxy:98"))); + proxy_resolution_service->SetProxyDelegate(test_proxy_delegate.get()); + Initialize(std::move(proxy_resolution_service)); + + // Start two requests. The first request should consume data from + // |socket_data_proxy_main_job| and |socket_data_direct_first_request|. + // The second request should consume data from + // |socket_data_direct_second_request|. + + for (size_t i = 0; i < 2; ++i) { + ProxyInfo used_proxy_info; + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(::testing::SaveArg<1>(&used_proxy_info)); + + std::unique_ptr<HttpStreamRequest> request = + CreateJobController(request_info); + RunUntilIdle(); + + // Verify that request was fetched without proxy. + EXPECT_TRUE(used_proxy_info.is_direct()); + + // The proxies that failed should now be known to the proxy service as + // bad. + const ProxyRetryInfoMap& retry_info = + session_->proxy_resolution_service()->proxy_retry_info(); + ASSERT_THAT(retry_info, SizeIs(2)); + EXPECT_THAT(retry_info, Contains(Key("badproxy:99"))); + EXPECT_THAT(retry_info, Contains(Key("badfallbackproxy:98"))); + + // The idle socket should have been added back to the socket pool. Close + // it, so the next loop iteration creates a new socket instead of + // reusing the idle one. + auto* socket_pool = session_->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()); + EXPECT_EQ(1, socket_pool->IdleSocketCount()); + socket_pool->CloseIdleSockets("Close socket reason"); + } + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); + } } - EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +// Test proxy fallback logic in the case connecting through an HTTPS proxy. +TEST_F(JobControllerReconsiderProxyAfterErrorTest, + ReconsiderProxyAfterErrorHttpsProxy) { + enum class ErrorPhase { + kHostResolution, + kTcpConnect, + kProxySslHandshake, + kTunnelRead, + }; + + const struct { + ErrorPhase phase; + net::Error error; + // Each test case simulates a connection attempt through a proxy that fails + // twice, followed by two connection attempts that succeed. For most cases, + // this is done by having a connection attempt to the first proxy fail, + // triggering fallback to a second proxy, which also fails, and then + // fallback to the final (DIRECT) proxy option. However, SslConnectJobs have + // their own try logic in certain cases. This value is true for those cases, + // in which case there are two connection attempts to the first proxy, and + // then the requests fall back to the second (DIRECT) proxy. + bool triggers_ssl_connect_job_retry_logic = false; + } kRetriableErrors[] = { + // These largely correspond to the list of errors in + // CanFalloverToNextProxy() which can occur with an HTTPS proxy. + // + // We omit `ERR_CONNECTION_CLOSED` because it is largely unreachable. The + // HTTP/1.1 parser maps it to `ERR_EMPTY_RESPONSE` or + // `ERR_RESPONSE_HEADERS_TRUNCATED` in most cases. + // + // TODO(davidben): Is omitting `ERR_EMPTY_RESPONSE` a bug in proxy error + // handling? + {ErrorPhase::kHostResolution, ERR_NAME_NOT_RESOLVED}, + {ErrorPhase::kTcpConnect, ERR_ADDRESS_UNREACHABLE}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_TIMED_OUT}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_RESET}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_ABORTED}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_REFUSED}, + {ErrorPhase::kProxySslHandshake, ERR_CERT_COMMON_NAME_INVALID}, + {ErrorPhase::kProxySslHandshake, ERR_SSL_PROTOCOL_ERROR, + /*triggers_ssl_connect_job_retry_logic=*/true}, + {ErrorPhase::kTunnelRead, ERR_TIMED_OUT}, + {ErrorPhase::kTunnelRead, ERR_SSL_PROTOCOL_ERROR}, + }; + + for (GURL dest_url : + {GURL("http://www.example.com"), GURL("https://www.example.com")}) { + SCOPED_TRACE(dest_url); + + for (const auto& mock_error : kRetriableErrors) { + SCOPED_TRACE(ErrorToString(mock_error.error)); + + CreateSessionDeps(); + + std::unique_ptr<ConfiguredProxyResolutionService> + proxy_resolution_service = + ConfiguredProxyResolutionService::CreateFixedFromPacResult( + "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT", + TRAFFIC_ANNOTATION_FOR_TESTS); + if (mock_error.triggers_ssl_connect_job_retry_logic) { + proxy_resolution_service = + ConfiguredProxyResolutionService::CreateFixedFromPacResult( + "HTTPS badproxy:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); + } + auto test_proxy_delegate = std::make_unique<TestProxyDelegate>(); + + // Before starting the test, verify that there are no proxies marked as + // bad. + ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty()); + + constexpr char kTunnelRequest[] = + "CONNECT www.example.com:443 HTTP/1.1\r\n" + "Host: www.example.com:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"; + const MockWrite kTunnelWrites[] = {{ASYNC, kTunnelRequest}}; + std::vector<MockRead> reads; + + // Generate identical errors for both the main proxy and the fallback + // proxy. No alternative job is created for either, so only need one data + // provider for each, when the request makes it to the socket layer. + std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job; + std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job; + std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job2; + std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job2; + switch (mock_error.phase) { + case ErrorPhase::kHostResolution: + // Only ERR_NAME_NOT_RESOLVED can be returned by the mock host + // resolver. + DCHECK_EQ(ERR_NAME_NOT_RESOLVED, mock_error.error); + session_deps_.host_resolver->rules()->AddSimulatedFailure("badproxy"); + session_deps_.host_resolver->rules()->AddSimulatedFailure( + "badfallbackproxy"); + break; + case ErrorPhase::kTcpConnect: + socket_data_proxy_main_job = + std::make_unique<StaticSocketDataProvider>(); + socket_data_proxy_main_job->set_connect_data( + MockConnect(ASYNC, mock_error.error)); + socket_data_proxy_main_job2 = + std::make_unique<StaticSocketDataProvider>(); + socket_data_proxy_main_job2->set_connect_data( + MockConnect(ASYNC, mock_error.error)); + break; + case ErrorPhase::kProxySslHandshake: + socket_data_proxy_main_job = + std::make_unique<StaticSocketDataProvider>(); + ssl_data_proxy_main_job = + std::make_unique<SSLSocketDataProvider>(ASYNC, mock_error.error); + socket_data_proxy_main_job2 = + std::make_unique<StaticSocketDataProvider>(); + ssl_data_proxy_main_job2 = + std::make_unique<SSLSocketDataProvider>(ASYNC, mock_error.error); + break; + case ErrorPhase::kTunnelRead: + // Tunnels aren't established for HTTP destinations. + if (dest_url.SchemeIs(url::kHttpScheme)) + continue; + reads.emplace_back(MockRead(ASYNC, mock_error.error)); + socket_data_proxy_main_job = + std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites); + ssl_data_proxy_main_job = + std::make_unique<SSLSocketDataProvider>(ASYNC, OK); + socket_data_proxy_main_job2 = + std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites); + ssl_data_proxy_main_job2 = + std::make_unique<SSLSocketDataProvider>(ASYNC, OK); + break; + } + + if (socket_data_proxy_main_job) { + session_deps_.socket_factory->AddSocketDataProvider( + socket_data_proxy_main_job.get()); + session_deps_.socket_factory->AddSocketDataProvider( + socket_data_proxy_main_job2.get()); + } + if (ssl_data_proxy_main_job) { + session_deps_.socket_factory->AddSSLSocketDataProvider( + ssl_data_proxy_main_job.get()); + session_deps_.socket_factory->AddSSLSocketDataProvider( + ssl_data_proxy_main_job2.get()); + } + + // After both proxies fail, the request should fall back to using DIRECT, + // and succeed. + SSLSocketDataProvider ssl_data_first_request(ASYNC, OK); + StaticSocketDataProvider socket_data_direct_first_request; + socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK)); + session_deps_.socket_factory->AddSocketDataProvider( + &socket_data_direct_first_request); + // Only used in the HTTPS destination case, but harmless in the HTTP case. + session_deps_.socket_factory->AddSSLSocketDataProvider( + &ssl_data_first_request); + + // Second request should use DIRECT, skipping the bad proxies, and + // succeed. + SSLSocketDataProvider ssl_data_second_request(ASYNC, OK); + StaticSocketDataProvider socket_data_direct_second_request; + socket_data_direct_second_request.set_connect_data( + MockConnect(ASYNC, OK)); + session_deps_.socket_factory->AddSocketDataProvider( + &socket_data_direct_second_request); + // Only used in the HTTPS destination case, but harmless in the HTTP case. + session_deps_.socket_factory->AddSSLSocketDataProvider( + &ssl_data_second_request); + + // Now request a stream. It should succeed using the DIRECT fallback proxy + // option. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = dest_url; + + proxy_resolution_service->SetProxyDelegate(test_proxy_delegate.get()); + Initialize(std::move(proxy_resolution_service)); + + // Start two requests. The first request should consume data from + // |socket_data_proxy_main_job| and |socket_data_direct_first_request|. + // The second request should consume data from + // |socket_data_direct_second_request|. + + for (size_t i = 0; i < 2; ++i) { + ProxyInfo used_proxy_info; + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(::testing::SaveArg<1>(&used_proxy_info)); + + std::unique_ptr<HttpStreamRequest> request = + CreateJobController(request_info); + RunUntilIdle(); + + // Verify that request was fetched without proxy. + EXPECT_TRUE(used_proxy_info.is_direct()); + + // The proxies that failed should now be known to the proxy service as + // bad. + const ProxyRetryInfoMap& retry_info = + session_->proxy_resolution_service()->proxy_retry_info(); + if (!mock_error.triggers_ssl_connect_job_retry_logic) { + ASSERT_THAT(retry_info, SizeIs(2)); + EXPECT_THAT(retry_info, Contains(Key("https://badproxy:99"))); + EXPECT_THAT(retry_info, Contains(Key("https://badfallbackproxy:98"))); + } else { + ASSERT_THAT(retry_info, SizeIs(1)); + EXPECT_THAT(retry_info, Contains(Key("https://badproxy:99"))); + } + + // The idle socket should have been added back to the socket pool. Close + // it, so the next loop iteration creates a new socket instead of + // reusing the idle one. + auto* socket_pool = session_->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()); + EXPECT_EQ(1, socket_pool->IdleSocketCount()); + socket_pool->CloseIdleSockets("Close socket reason"); + } + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); + } + } +} + +// Test proxy fallback logic in the case connecting through socks5 proxy. +TEST_F(JobControllerReconsiderProxyAfterErrorTest, + ReconsiderProxyAfterErrorSocks5Proxy) { + enum class ErrorPhase { + kHostResolution, + kTcpConnect, + kTunnelRead, + }; + + const struct { + ErrorPhase phase; + net::Error error; + } kRetriableErrors[] = { + // These largely correspond to the list of errors in + // CanFalloverToNextProxy() which can occur with an HTTPS proxy. + // + // Unlike HTTP/HTTPS proxies, SOCKS proxies are retried in response to + // `ERR_CONNECTION_CLOSED`. + {ErrorPhase::kHostResolution, ERR_NAME_NOT_RESOLVED}, + {ErrorPhase::kTcpConnect, ERR_ADDRESS_UNREACHABLE}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_TIMED_OUT}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_RESET}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_ABORTED}, + {ErrorPhase::kTcpConnect, ERR_CONNECTION_REFUSED}, + {ErrorPhase::kTunnelRead, ERR_TIMED_OUT}, + {ErrorPhase::kTunnelRead, ERR_CONNECTION_CLOSED}, + }; + + // "host" on port 80 matches the kSOCK5GreetRequest. + const GURL kDestUrl = GURL("http://host:80/"); + + for (const auto& mock_error : kRetriableErrors) { + SCOPED_TRACE(ErrorToString(mock_error.error)); + + CreateSessionDeps(); + + std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service = + ConfiguredProxyResolutionService::CreateFixedFromPacResult( + "SOCKS5 badproxy:99; SOCKS5 badfallbackproxy:98; DIRECT", + TRAFFIC_ANNOTATION_FOR_TESTS); + auto test_proxy_delegate = std::make_unique<TestProxyDelegate>(); + + // Before starting the test, verify that there are no proxies marked as bad. + ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty()); + const MockWrite kTunnelWrites[] = { + {ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength}}; + std::vector<MockRead> reads; + + // Generate identical errors for both the main proxy and the fallback proxy. + // No alternative job is created for either, so only need one data provider + // for each, when the request makes it to the socket layer. + std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job; + std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job2; + switch (mock_error.phase) { + case ErrorPhase::kHostResolution: + // Only ERR_NAME_NOT_RESOLVED can be returned by the mock host resolver. + DCHECK_EQ(ERR_NAME_NOT_RESOLVED, mock_error.error); + session_deps_.host_resolver->rules()->AddSimulatedFailure("badproxy"); + session_deps_.host_resolver->rules()->AddSimulatedFailure( + "badfallbackproxy"); + break; + case ErrorPhase::kTcpConnect: + socket_data_proxy_main_job = + std::make_unique<StaticSocketDataProvider>(); + socket_data_proxy_main_job->set_connect_data( + MockConnect(ASYNC, mock_error.error)); + socket_data_proxy_main_job2 = + std::make_unique<StaticSocketDataProvider>(); + socket_data_proxy_main_job2->set_connect_data( + MockConnect(ASYNC, mock_error.error)); + break; + case ErrorPhase::kTunnelRead: + reads.emplace_back(MockRead(ASYNC, mock_error.error)); + socket_data_proxy_main_job = + std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites); + socket_data_proxy_main_job2 = + std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites); + break; + } + + if (socket_data_proxy_main_job) { + session_deps_.socket_factory->AddSocketDataProvider( + socket_data_proxy_main_job.get()); + session_deps_.socket_factory->AddSocketDataProvider( + socket_data_proxy_main_job2.get()); + } + + // After both proxies fail, the request should fall back to using DIRECT, + // and succeed. + StaticSocketDataProvider socket_data_direct_first_request; + socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK)); + session_deps_.socket_factory->AddSocketDataProvider( + &socket_data_direct_first_request); + + // Second request should use DIRECT, skipping the bad proxies, and succeed. + StaticSocketDataProvider socket_data_direct_second_request; + socket_data_direct_second_request.set_connect_data(MockConnect(ASYNC, OK)); + session_deps_.socket_factory->AddSocketDataProvider( + &socket_data_direct_second_request); + + // Now request a stream. It should succeed using the DIRECT fallback proxy + // option. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = kDestUrl; + + proxy_resolution_service->SetProxyDelegate(test_proxy_delegate.get()); + Initialize(std::move(proxy_resolution_service)); + + // Start two requests. The first request should consume data from + // |socket_data_proxy_main_job| and |socket_data_direct_first_request|. The + // second request should consume data from + // |socket_data_direct_second_request|. + + for (size_t i = 0; i < 2; ++i) { + ProxyInfo used_proxy_info; + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(::testing::SaveArg<1>(&used_proxy_info)); + + std::unique_ptr<HttpStreamRequest> request = + CreateJobController(request_info); + RunUntilIdle(); + + // Verify that request was fetched without proxy. + EXPECT_TRUE(used_proxy_info.is_direct()); + + // The proxies that failed should now be known to the proxy service as + // bad. + const ProxyRetryInfoMap& retry_info = + session_->proxy_resolution_service()->proxy_retry_info(); + ASSERT_THAT(retry_info, SizeIs(2)); + EXPECT_THAT(retry_info, Contains(Key("socks5://badproxy:99"))); + EXPECT_THAT(retry_info, Contains(Key("socks5://badfallbackproxy:98"))); + + // The idle socket should have been added back to the socket pool. Close + // it, so the next loop iteration creates a new socket instead of reusing + // the idle one. + auto* socket_pool = session_->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()); + EXPECT_EQ(1, socket_pool->IdleSocketCount()); + socket_pool->CloseIdleSockets("Close socket reason"); + } + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); + } } // Tests that ERR_MSG_TOO_BIG is retryable for QUIC proxy. @@ -622,7 +1057,7 @@ socket_data_direct.set_connect_data(MockConnect(ASYNC, OK)); session_deps_.socket_factory->AddSocketDataProvider(&socket_data_direct); - // Now request a stream. It should fallback to DIRECT on ERR_MSG_TOO_BIG. + // Now request a stream. It should fall back to DIRECT on ERR_MSG_TOO_BIG. HttpRequestInfo request_info; request_info.method = "GET"; request_info.url = GURL("http://www.example.com");
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc index c58c95e..130c9ecf 100644 --- a/net/spdy/spdy_test_util_common.cc +++ b/net/spdy/spdy_test_util_common.cc
@@ -328,8 +328,14 @@ kDefaultInitialWindowSize; } +SpdySessionDependencies::SpdySessionDependencies(SpdySessionDependencies&&) = + default; + SpdySessionDependencies::~SpdySessionDependencies() = default; +SpdySessionDependencies& SpdySessionDependencies::operator=( + SpdySessionDependencies&&) = default; + // static std::unique_ptr<HttpNetworkSession> SpdySessionDependencies::SpdyCreateSession( SpdySessionDependencies* session_deps) {
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h index fbf480e0..b1f2156 100644 --- a/net/spdy/spdy_test_util_common.h +++ b/net/spdy/spdy_test_util_common.h
@@ -152,8 +152,12 @@ explicit SpdySessionDependencies( std::unique_ptr<ProxyResolutionService> proxy_resolution_service); + SpdySessionDependencies(SpdySessionDependencies&&); + ~SpdySessionDependencies(); + SpdySessionDependencies& operator=(SpdySessionDependencies&&); + HostResolver* GetHostResolver() { return alternate_host_resolver ? alternate_host_resolver.get() : host_resolver.get();
diff --git a/printing/backend/printing_info_win.cc b/printing/backend/printing_info_win.cc index 6dd01ef..35e099ba 100644 --- a/printing/backend/printing_info_win.cc +++ b/printing/backend/printing_info_win.cc
@@ -12,36 +12,37 @@ namespace internal { -uint8_t* GetDriverInfo(HANDLE printer, int level) { +std::unique_ptr<uint8_t[]> GetDriverInfo(HANDLE printer, int level) { DWORD size = 0; - ::GetPrinterDriver(printer, NULL, level, NULL, 0, &size); - if (size == 0) { - return NULL; - } - std::unique_ptr<uint8_t[]> buffer(new uint8_t[size]); + ::GetPrinterDriver(printer, nullptr, level, nullptr, 0, &size); + if (size == 0) + return nullptr; + + auto buffer = std::make_unique<uint8_t[]>(size); memset(buffer.get(), 0, size); - if (!::GetPrinterDriver(printer, NULL, level, buffer.get(), size, &size)) { - return NULL; - } - return buffer.release(); + if (!::GetPrinterDriver(printer, nullptr, level, buffer.get(), size, &size)) + return nullptr; + + return buffer; } -uint8_t* GetPrinterInfo(HANDLE printer, int level) { +std::unique_ptr<uint8_t[]> GetPrinterInfo(HANDLE printer, int level) { DWORD size = 0; - ::GetPrinter(printer, level, NULL, 0, &size); + ::GetPrinter(printer, level, nullptr, 0, &size); if (size == 0) { LOG(WARNING) << "Failed to get size of PRINTER_INFO_" << level << ", error = " << GetLastError(); - return NULL; + return nullptr; } - std::unique_ptr<uint8_t[]> buffer(new uint8_t[size]); + + auto buffer = std::make_unique<uint8_t[]>(size); memset(buffer.get(), 0, size); if (!::GetPrinter(printer, level, buffer.get(), size, &size)) { LOG(WARNING) << "Failed to get PRINTER_INFO_" << level << ", error = " << GetLastError(); - return NULL; + return nullptr; } - return buffer.release(); + return buffer; } } // namespace internal
diff --git a/printing/backend/printing_info_win.h b/printing/backend/printing_info_win.h index 4aad87c..9b9298d 100644 --- a/printing/backend/printing_info_win.h +++ b/printing/backend/printing_info_win.h
@@ -18,9 +18,9 @@ namespace internal { COMPONENT_EXPORT(PRINT_BACKEND) -uint8_t* GetDriverInfo(HANDLE printer, int level); +std::unique_ptr<uint8_t[]> GetDriverInfo(HANDLE printer, int level); COMPONENT_EXPORT(PRINT_BACKEND) -uint8_t* GetPrinterInfo(HANDLE printer, int level); +std::unique_ptr<uint8_t[]> GetPrinterInfo(HANDLE printer, int level); // This class is designed to work with PRINTER_INFO_X structures // and calls GetPrinter internally with correctly allocated buffer. @@ -28,7 +28,7 @@ class PrinterInfo { public: bool Init(HANDLE printer) { - buffer_.reset(GetPrinterInfo(printer, level)); + buffer_ = GetPrinterInfo(printer, level); return buffer_ != nullptr; } @@ -46,7 +46,7 @@ class DriverInfo { public: bool Init(HANDLE printer) { - buffer_.reset(GetDriverInfo(printer, level)); + buffer_ = GetDriverInfo(printer, level); return buffer_ != nullptr; } @@ -60,10 +60,10 @@ } // namespace internal -typedef internal::PrinterInfo<PRINTER_INFO_2, 2> PrinterInfo2; -typedef internal::PrinterInfo<PRINTER_INFO_5, 5> PrinterInfo5; +using PrinterInfo2 = internal::PrinterInfo<PRINTER_INFO_2, 2>; +using PrinterInfo5 = internal::PrinterInfo<PRINTER_INFO_5, 5>; -typedef internal::DriverInfo<DRIVER_INFO_6, 6> DriverInfo6; +using DriverInfo6 = internal::DriverInfo<DRIVER_INFO_6, 6>; } // namespace printing
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn index 79727ee3..afe74a2 100644 --- a/remoting/host/BUILD.gn +++ b/remoting/host/BUILD.gn
@@ -258,6 +258,8 @@ "desktop_display_info.cc", "desktop_display_info.h", "desktop_display_info_loader.h", + "desktop_display_info_monitor.cc", + "desktop_display_info_monitor.h", "desktop_process.cc", "desktop_process.h", "desktop_resizer.h",
diff --git a/remoting/host/desktop_capturer_proxy.cc b/remoting/host/desktop_capturer_proxy.cc index 54c5f5d..f5b8698 100644 --- a/remoting/host/desktop_capturer_proxy.cc +++ b/remoting/host/desktop_capturer_proxy.cc
@@ -133,20 +133,13 @@ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, base::WeakPtr<ClientSessionControl> client_session_control) : capture_task_runner_(capture_task_runner), - ui_task_runner_(ui_task_runner), client_session_control_(client_session_control), - desktop_display_info_loader_(DesktopDisplayInfoLoader::Create()) { + desktop_display_info_monitor_(ui_task_runner, client_session_control) { core_ = std::make_unique<Core>(weak_factory_.GetWeakPtr()); - ui_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&DesktopDisplayInfoLoader::Init, - base::Unretained(desktop_display_info_loader_.get()))); } DesktopCapturerProxy::~DesktopCapturerProxy() { capture_task_runner_->DeleteSoon(FROM_HERE, core_.release()); - ui_task_runner_->DeleteSoon(FROM_HERE, - desktop_display_info_loader_.release()); } void DesktopCapturerProxy::CreateCapturer( @@ -201,11 +194,7 @@ bool DesktopCapturerProxy::SelectSource(SourceId id_index) { DCHECK(thread_checker_.CalledOnValidThread()); - const DisplayGeometry* display = - desktop_display_info_.GetDisplayInfo(id_index); - - SourceId id = (display ? display->id : webrtc::kFullDesktopScreenId); - + SourceId id = desktop_display_info_monitor_.SourceIdFromIndex(id_index); capture_task_runner_->PostTask( FROM_HERE, base::BindOnce(&Core::SelectSource, base::Unretained(core_.get()), id)); @@ -220,38 +209,8 @@ callback_->OnCaptureResult(result, std::move(frame)); if (client_session_control_) { - ui_task_runner_->PostTaskAndReplyWithResult( - FROM_HERE, - base::BindOnce(&DesktopDisplayInfoLoader::GetCurrentDisplayInfo, - base::Unretained(desktop_display_info_loader_.get())), - base::BindOnce(&DesktopCapturerProxy::OnDisplayInfoLoaded, - weak_factory_.GetWeakPtr())); + desktop_display_info_monitor_.QueryDisplayInfo(); } } -void DesktopCapturerProxy::OnDisplayInfoLoaded(DesktopDisplayInfo info) { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (!client_session_control_ || desktop_display_info_ == info) { - return; - } - - desktop_display_info_ = std::move(info); - - auto layout = std::make_unique<protocol::VideoLayout>(); - LOG(INFO) << "DCP::OnDisplayInfoLoaded"; - for (const auto& display : desktop_display_info_.displays()) { - protocol::VideoTrackLayout* track = layout->add_video_track(); - track->set_position_x(display.x); - track->set_position_y(display.y); - track->set_width(display.width); - track->set_height(display.height); - track->set_x_dpi(display.dpi); - track->set_y_dpi(display.dpi); - LOG(INFO) << " Display: " << display.x << "," << display.y << " " - << display.width << "x" << display.height << " @ " << display.dpi; - } - client_session_control_->OnDesktopDisplayChanged(std::move(layout)); -} - } // namespace remoting
diff --git a/remoting/host/desktop_capturer_proxy.h b/remoting/host/desktop_capturer_proxy.h index e17796d..d621432 100644 --- a/remoting/host/desktop_capturer_proxy.h +++ b/remoting/host/desktop_capturer_proxy.h
@@ -11,8 +11,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" -#include "remoting/host/desktop_display_info.h" -#include "remoting/host/desktop_display_info_loader.h" +#include "remoting/host/desktop_display_info_monitor.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" namespace base { @@ -63,13 +62,11 @@ void OnFrameCaptured(webrtc::DesktopCapturer::Result result, std::unique_ptr<webrtc::DesktopFrame> frame); - void OnDisplayInfoLoaded(DesktopDisplayInfo info); base::ThreadChecker thread_checker_; std::unique_ptr<Core> core_; scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; raw_ptr<webrtc::DesktopCapturer::Callback> callback_; @@ -78,11 +75,8 @@ // the same process as the DesktopCapturerProxy. base::WeakPtr<ClientSessionControl> client_session_control_; - // Contains the most recently gathered info about the desktop displays. - DesktopDisplayInfo desktop_display_info_; - - // Created on the calling thread, but accessed and destroyed on the UI thread. - std::unique_ptr<DesktopDisplayInfoLoader> desktop_display_info_loader_; + // Monitors and stores info about the desktop displays. + DesktopDisplayInfoMonitor desktop_display_info_monitor_; base::WeakPtrFactory<DesktopCapturerProxy> weak_factory_{this}; };
diff --git a/remoting/host/desktop_display_info_monitor.cc b/remoting/host/desktop_display_info_monitor.cc new file mode 100644 index 0000000..f3a7376 --- /dev/null +++ b/remoting/host/desktop_display_info_monitor.cc
@@ -0,0 +1,98 @@ +// Copyright 2021 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 "remoting/host/desktop_display_info_monitor.h" + +#include <utility> + +#include "base/bind.h" +#include "base/task/sequenced_task_runner.h" +#include "base/time/time.h" +#include "remoting/base/logging.h" +#include "remoting/host/client_session_control.h" + +namespace remoting { + +namespace { + +// Polling interval for querying the OS for changes to the multi-monitor +// configuration. Before this class was written, the DesktopCapturerProxy would +// poll after each captured frame, which could occur up to 30x per second. The +// value chosen here is slower than this (to reduce the load on the OS), but +// still fast enough to be responsive to any changes. +constexpr base::TimeDelta kPollingInterval = base::Milliseconds(100); + +} // namespace + +DesktopDisplayInfoMonitor::DesktopDisplayInfoMonitor( + scoped_refptr<base::SequencedTaskRunner> ui_task_runner, + base::WeakPtr<ClientSessionControl> client_session_control) + : ui_task_runner_(ui_task_runner), + client_session_control_(client_session_control), + desktop_display_info_loader_(DesktopDisplayInfoLoader::Create()) { + // The loader must be initialized and used on the UI thread (though it can be + // created on any thread). + ui_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&DesktopDisplayInfoLoader::Init, + base::Unretained(desktop_display_info_loader_.get()))); +} + +DesktopDisplayInfoMonitor::~DesktopDisplayInfoMonitor() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + ui_task_runner_->DeleteSoon(FROM_HERE, + desktop_display_info_loader_.release()); +} + +void DesktopDisplayInfoMonitor::Start() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + timer_.Start(FROM_HERE, kPollingInterval, this, + &DesktopDisplayInfoMonitor::QueryDisplayInfo); +} + +void DesktopDisplayInfoMonitor::QueryDisplayInfo() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (client_session_control_) { + ui_task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&DesktopDisplayInfoLoader::GetCurrentDisplayInfo, + base::Unretained(desktop_display_info_loader_.get())), + base::BindOnce(&DesktopDisplayInfoMonitor::OnDisplayInfoLoaded, + weak_factory_.GetWeakPtr())); + } +} + +webrtc::DesktopCapturer::SourceId DesktopDisplayInfoMonitor::SourceIdFromIndex( + int index) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + const DisplayGeometry* display = desktop_display_info_.GetDisplayInfo(index); + return (display ? display->id : webrtc::kFullDesktopScreenId); +} + +void DesktopDisplayInfoMonitor::OnDisplayInfoLoaded(DesktopDisplayInfo info) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!client_session_control_ || desktop_display_info_ == info) { + return; + } + + desktop_display_info_ = std::move(info); + + auto layout = std::make_unique<protocol::VideoLayout>(); + HOST_LOG << "DDIM::OnDisplayInfoLoaded"; + for (const auto& display : desktop_display_info_.displays()) { + protocol::VideoTrackLayout* track = layout->add_video_track(); + track->set_position_x(display.x); + track->set_position_y(display.y); + track->set_width(display.width); + track->set_height(display.height); + track->set_x_dpi(display.dpi); + track->set_y_dpi(display.dpi); + HOST_LOG << " Display: " << display.x << "," << display.y << " " + << display.width << "x" << display.height << " @ " << display.dpi; + } + client_session_control_->OnDesktopDisplayChanged(std::move(layout)); +} + +} // namespace remoting
diff --git a/remoting/host/desktop_display_info_monitor.h b/remoting/host/desktop_display_info_monitor.h new file mode 100644 index 0000000..28515a24 --- /dev/null +++ b/remoting/host/desktop_display_info_monitor.h
@@ -0,0 +1,88 @@ +// Copyright 2021 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 REMOTING_HOST_DESKTOP_DISPLAY_INFO_MONITOR_H_ +#define REMOTING_HOST_DESKTOP_DISPLAY_INFO_MONITOR_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/timer/timer.h" +#include "remoting/host/desktop_display_info.h" +#include "remoting/host/desktop_display_info_loader.h" + +namespace base { +class SequencedTaskRunner; +} // namespace base + +namespace remoting { + +class ClientSessionControl; + +// This class regularly queries the OS for any changes to the multi-monitor +// display configuration, and reports any changes to the ClientSession. +// This class ensures that the DisplayInfo is fetched on the UI thread, which +// may be different from the calling thread. This is helpful on platforms where +// REMOTING_MULTI_PROCESS == false, allowing this class to be used on the +// network thread. When REMOTING_MULTI_PROCESS == true, this instance lives in +// the Desktop process. +class DesktopDisplayInfoMonitor { + public: + DesktopDisplayInfoMonitor( + scoped_refptr<base::SequencedTaskRunner> ui_task_runner, + base::WeakPtr<ClientSessionControl> client_session_control); + + DesktopDisplayInfoMonitor(const DesktopDisplayInfoMonitor&) = delete; + DesktopDisplayInfoMonitor& operator=(const DesktopDisplayInfoMonitor&) = + delete; + + virtual ~DesktopDisplayInfoMonitor(); + + // Begins continuous monitoring for changes. Any changes to the monitor layout + // will be reported to the ClientSessionControl. + void Start(); + + // Queries the OS immediately for the current monitor layout and reports any + // changed display info to the ClientSessionControl. If this instance is + // associated with a DesktopCapturerProxy, this method could be used to + // query the display info on each captured frame. + void QueryDisplayInfo(); + + // Needed by DesktopCapturerProxy to convert an index into the monitor-list + // to an ID that can be passed to the real capturer's SelectSource(). Returns + // webrtc::kFullDesktopScreenId if an out-of-bounds index is provided. + // TODO(lambroslambrou): Remove this method and fix + // DesktopCapturerProxy::SelectSource() to accept a monitor SourceId instead + // of an array-index. + webrtc::DesktopCapturer::SourceId SourceIdFromIndex(int index) const; + + private: + void OnDisplayInfoLoaded(DesktopDisplayInfo info); + + SEQUENCE_CHECKER(sequence_checker_); + + scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; + + // Object which receives DesktopDisplayInfo updates. + base::WeakPtr<ClientSessionControl> client_session_control_ + GUARDED_BY_CONTEXT(sequence_checker_); + + // Contains the most recently gathered info about the desktop displays. + DesktopDisplayInfo desktop_display_info_ + GUARDED_BY_CONTEXT(sequence_checker_); + + // Created on the calling thread, but accessed and destroyed on the UI thread. + std::unique_ptr<DesktopDisplayInfoLoader> desktop_display_info_loader_; + + // Timer to regularly poll |desktop_display_info_loader_| for updates. + base::RepeatingTimer timer_ GUARDED_BY_CONTEXT(sequence_checker_); + + base::WeakPtrFactory<DesktopDisplayInfoMonitor> weak_factory_{this}; +}; + +} // namespace remoting + +#endif // REMOTING_HOST_DESKTOP_DISPLAY_INFO_MONITOR_H_
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index fa831b9..ba15360 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -809,6 +809,24 @@ ] } ], + "ArcLogdSizeConfig": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledGroup512K_20211210", + "params": { + "size": "512" + }, + "enable_features": [ + "ArcGuestLogdConfig" + ] + } + ] + } + ], "ArcVmBlockSize": [ { "platforms": [ @@ -1171,7 +1189,7 @@ ], "experiments": [ { - "name": "Enabled_2021-12-01", + "name": "Enabled", "enable_features": [ "AutofillEnableSupportForMoreStructureInAddresses" ] @@ -1208,7 +1226,7 @@ ], "experiments": [ { - "name": "Enabled_2021-12-01", + "name": "Enabled", "enable_features": [ "AutofillEnableSupportForMoreStructureInNames" ] @@ -2165,6 +2183,25 @@ ] } ], + "ChromeOSRawPSIMetrics": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledGroup10s_20220107", + "params": { + "period": "10" + }, + "enable_features": [ + "ArcVmMemoryPSIReports", + "MemoryPressureMetricsDetail" + ] + } + ] + } + ], "ChromeOSReinstallApps": [ { "platforms": [ @@ -8396,6 +8433,26 @@ ] } ], + "V8WasmDynamicTiering": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20211210", + "enable_features": [ + "WebAssemblyDynamicTiering" + ] + } + ] + } + ], "V8WasmMemoryProtection": [ { "platforms": [
diff --git a/third_party/blink/public/mojom/interest_group/ad_auction_service.mojom b/third_party/blink/public/mojom/interest_group/ad_auction_service.mojom index f4046a7..0217233d 100644 --- a/third_party/blink/public/mojom/interest_group/ad_auction_service.mojom +++ b/third_party/blink/public/mojom/interest_group/ad_auction_service.mojom
@@ -59,12 +59,4 @@ // response. The JSON `name`, `owner`, `userBiddingSignals` and other unknown // fields will be ignored. UpdateAdInterestGroups(); - - // Gets the true URL from a URN returned from RunAdAuction. This function - // will be removed once all FLEDGE auctions switch to using fenced frames. - // The uuid_url should have the format format - // "urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" as per RFC-4122. - // TODO(crbug.com/1253118): Remove this function when we remove support for - // showing FLEDGE ads in iframes. - DeprecatedGetURLFromURN(url.mojom.Url uuid_url) => (url.mojom.Url? decoded_url); };
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index df061b9..f8e75880 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3413,7 +3413,7 @@ kV8UDPSocket_Close_Method = 4104, kHTMLInputElementSimulatedClick = 4105, kRTCLocalSdpModificationIceUfragPwd = 4106, - kV8Navigator_DeprecatedURNToURL_Method = 4107, + kWebNfcNdefMakeReadOnly = 4107, // Add new features immediately above this line. Don't change assigned
diff --git a/third_party/blink/renderer/bindings/core/v8/script_function.cc b/third_party/blink/renderer/bindings/core/v8/script_function.cc index 3dd61e9..2203329 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_function.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_function.cc
@@ -30,45 +30,6 @@ } // namespace -void ScriptFunction::Trace(Visitor* visitor) const { - visitor->Trace(script_state_); - CustomWrappableAdapter::Trace(visitor); -} - -v8::Local<v8::Function> ScriptFunction::BindToV8Function(int length) { -#if DCHECK_IS_ON() - DCHECK(!bind_to_v8_function_already_called_); - bind_to_v8_function_already_called_ = true; -#endif - - v8::Local<v8::Object> wrapper = CreateAndInitializeWrapper(script_state_); - // The wrapper is held alive by the CallHandlerInfo internally in V8 as long - // as the function is alive. - return v8::Function::New(script_state_->GetContext(), CallCallback, wrapper, - length, v8::ConstructorBehavior::kThrow) - .ToLocalChecked(); -} - -ScriptValue ScriptFunction::Call(ScriptValue) { - NOTREACHED(); - return ScriptValue(); -} - -void ScriptFunction::CallRaw(const v8::FunctionCallbackInfo<v8::Value>& args) { - ScriptValue result = - Call(ScriptValue(GetScriptState()->GetIsolate(), args[0])); - V8SetReturnValue(args, result.V8Value()); -} - -void ScriptFunction::CallCallback( - const v8::FunctionCallbackInfo<v8::Value>& args) { - RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(args.GetIsolate(), - "Blink_CallCallback"); - ScriptFunction* script_function = static_cast<ScriptFunction*>( - ToCustomWrappable(v8::Local<v8::Object>::Cast(args.Data()))); - script_function->CallRaw(args); -} - ScriptValue NewScriptFunction::Callable::Call(ScriptState*, ScriptValue) { NOTREACHED(); return ScriptValue();
diff --git a/third_party/blink/renderer/bindings/core/v8/script_function.h b/third_party/blink/renderer/bindings/core/v8/script_function.h index 8c07471..1f39cdbb 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_function.h +++ b/third_party/blink/renderer/bindings/core/v8/script_function.h
@@ -42,43 +42,6 @@ namespace blink { -// DEPRECATED: Use NewScriptFunction. -class CORE_EXPORT ScriptFunction : public CustomWrappableAdapter { - public: - ~ScriptFunction() override = default; - - void Trace(Visitor*) const override; - - const char* NameInHeapSnapshot() const override { return "ScriptFunction"; } - - protected: - explicit ScriptFunction(ScriptState* script_state) - : script_state_(script_state) {} - - ScriptState* GetScriptState() const { return script_state_; } - - // It is not usually necessary to set |length| unless the function is exposed - // to JavaScript. - v8::Local<v8::Function> BindToV8Function(int length = 0); - - private: - // Subclasses should implement one of Call() or CallRaw(). Most will implement - // Call(). - virtual ScriptValue Call(ScriptValue); - - // To support more than one argument, or for low-level access to the V8 API, - // implement CallRaw(). The default implementation delegates to Call(). - virtual void CallRaw(const v8::FunctionCallbackInfo<v8::Value>&); - - static void CallCallback(const v8::FunctionCallbackInfo<v8::Value>&); - - Member<ScriptState> script_state_; -#if DCHECK_IS_ON() - // BindToV8Function() must not be called twice. - bool bind_to_v8_function_already_called_ = false; -#endif -}; - // A `NewScriptFunction` represents a function that can be called from scripts. // You can define a subclass of `Callable` and put arbitrary logic by // overriding `Call` or `CallRaw` methods.
diff --git a/third_party/blink/renderer/build/scripts/core/css/parser/make_proto.py b/third_party/blink/renderer/build/scripts/core/css/parser/make_proto.py new file mode 100644 index 0000000..1b84d3e --- /dev/null +++ b/third_party/blink/renderer/build/scripts/core/css/parser/make_proto.py
@@ -0,0 +1,80 @@ +# Copyright (c) 2022 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. + +from core.css import css_properties +import json5_generator +import template_expander + + +class CSSProtoWriter(json5_generator.Writer): + def __init__(self, json5_file_paths, output_dir): + super(CSSProtoWriter, self).__init__(None, output_dir) + assert len(json5_file_paths) == 4, \ + "Needs css_properties.json5, computed_style_field_aliases.json5," \ + " runtime_enabled_features.json5, and css_value_keywords.json5." + self._input_files = json5_file_paths + self._outputs = { + 'css.proto': self.generate_proto, + 'css_proto_converter_generated.h': self.generate_cc, + } + self._all_properties = css_properties.CSSProperties( + json5_file_paths[:3]).properties_including_aliases + self._keywords = sorted([ + keyword['name'] + for keyword in json5_generator.Json5File.load_from_files( + [json5_file_paths[3]]).name_dictionaries + ]) + + @template_expander.use_jinja( + 'core/css/parser/templates/css_proto_converter_generated.h.tmpl') + def generate_cc(self): + return { + 'input_files': + self._input_files, + 'property_names': + '\n'.join(' "%s",' % property['name'].original + for property in self._all_properties), + 'value_keywords': + '\n'.join(' "%s",' % keyword.original + for keyword in self._keywords), + } + + @template_expander.use_jinja('core/css/parser/templates/css.proto.tmpl') + def generate_proto(self): + property_symbols = [] + for i, property in enumerate(self._all_properties): + symbol = property['name'].to_macro_case() + if symbol == 'OVERFLOW': # Conflicts with a system header + symbol = 'OVERFLOW_' + property_symbols.append(' %s = %d;' % (symbol, i + 1)) + property_symbols.append(' INVALID_PROPERTY = %d;' % + (len(self._all_properties) + 1)) + + keyword_symbols = [] + for i, keyword in enumerate(self._keywords): + symbol = keyword.to_macro_case() + if keyword.original == '-infinity': + # Conflicts with a system header + symbol = 'NEGATIVE_INFINITY' + elif keyword.original == 'infinity': + # Conflicts with a system header + symbol = 'POSITIVE_INFINITY' + elif keyword.original == 'unset': + # Conflicts with PropertyAndValue::Prio::UNSET. + symbol = 'UNSET_' + elif keyword.original == 'nan': + # Conflicts with a system header + symbol = 'NOT_A_NUMBER' + keyword_symbols.append(' %s = %d;' % (symbol, i + 1)) + keyword_symbols.append(' INVALID_VALUE = %d;' % + (len(self._keywords) + 1)) + + return { + 'property_proto_enums': '\n'.join(property_symbols), + 'value_proto_enums': '\n'.join(keyword_symbols), + } + + +if __name__ == "__main__": + json5_generator.Maker(CSSProtoWriter).main()
diff --git a/third_party/blink/renderer/build/scripts/core/css/parser/templates/css.proto.tmpl b/third_party/blink/renderer/build/scripts/core/css/parser/templates/css.proto.tmpl new file mode 100644 index 0000000..f19ea1f2 --- /dev/null +++ b/third_party/blink/renderer/build/scripts/core/css/parser/templates/css.proto.tmpl
@@ -0,0 +1,1153 @@ +// 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. + +// Based on the grammar provided here: https://goo.gl/svLze7 +// Most top level definitions here (mostly messages, but also the enum "h", is +// named after a rule or token in the grammar. The messages that aren't were +// implemented to hack around shortcomings in the protobuf format (such as +// "StringCharOrQuote"). These can be identified because they are preceded by +// a comment that says "Not in grammar". + +syntax = "proto2"; + +package css_proto_converter; + +// Tokens +// TODO(metzman): Implement CDO, CDC, UNICODERANGE, and range. +// The following tokens are implmented in code and do not have their own +// message: INCLUDES, DASHMATCH, HASH, STRING IMPORT_SYM, PAGE_SYM, MEDIA_SYM, +// FONT_FACE_SYM, CHARSET_SYM, NAMESPACE_SYM, IMPORTANT_SYM, EMS, EXS, NUMBER, +// and PERCENTAGE. +// DIMEN not implemented since it isnt used in any production. + +// This is named "h" because it represents the "h" token in the grammar this is +// based off of. +enum H { + ZERO = 48; + ONE = 49; + TWO = 50; + THREE = 51; + FOUR = 52; + FIVE = 53; + SIX = 54; + SEVEN = 55; + EIGHT = 56; + NINE = 57; + A_UPPER = 65; + B_UPPER = 66; + C_UPPER = 67; + D_UPPER = 68; + E_UPPER = 69; + F_UPPER = 70; + A_LOWER = 97; + B_LOWER = 98; + C_LOWER = 99; + D_LOWER = 100; + E_LOWER = 101; + F_LOWER = 102; +} + +// TODO(metzman): Add "nonascii" token from grammar. + +message Unicode { + required H ascii_value_1 = 1; + optional H ascii_value_2 = 2; + optional H ascii_value_3 = 3; + optional H ascii_value_4 = 4; + optional H ascii_value_5 = 5; + optional H ascii_value_6 = 6; + optional UnrepeatedW unrepeated_w = 7; +} + +// unicode | '\' [#x20-#x7E#x80-#xD7FF#xE000-#xFFFD#x10000-#x10FFFF] +message Escape { + // #x20-#x7E + enum AsciiValue { + SPACE = 32; + EXCLAMATION_POINT = 33; + DOUBLE_QUOTE = 34; + HASH = 35; + DOLLAR = 36; + PERCENT = 37; + AMPERSAND = 38; + APOSTROPHE = 39; + OPEN_PAREN = 40; + CLOSE_PAREN = 41; + STAR = 42; + PLUS = 43; + COMMA = 44; + MINUS = 45; + DOT = 46; + SLASH = 47; + ZERO = 48; + ONE = 49; + TWO = 50; + THREE = 51; + FOUR = 52; + FIVE = 53; + SIX = 54; + SEVEN = 55; + EIGHT = 56; + NINE = 57; + COLON = 58; + SEMI_COLON = 59; + LESS_THAN = 60; + EQUAL = 61; + GREATER_THAN = 62; + QUESTION = 63; + AT_SIGN = 64; + A_UPPER = 65; + B_UPPER = 66; + C_UPPER = 67; + D_UPPER = 68; + E_UPPER = 69; + F_UPPER = 70; + G_UPPER = 71; + H_UPPER = 72; + I_UPPER = 73; + J_UPPER = 74; + K_UPPER = 75; + L_UPPER = 76; + M_UPPER = 77; + N_UPPER = 78; + O_UPPER = 79; + P_UPPER = 80; + Q_UPPER = 81; + R_UPPER = 82; + S_UPPER = 83; + T_UPPER = 84; + U_UPPER = 85; + V_UPPER = 86; + W_UPPER = 87; + X_UPPER = 88; + Y_UPPER = 89; + Z_UPPER = 90; + OPEN_BRACKET = 91; + BACKSLASH = 92; + CLOSE_BRACKET = 93; + CARET = 94; + UNDERSCORE = 95; + BACKTICK = 96; + A_LOWER = 97; + B_LOWER = 98; + C_LOWER = 99; + D_LOWER = 100; + E_LOWER = 101; + F_LOWER = 102; + G_LOWER = 103; + H_LOWER = 104; + I_LOWER = 105; + J_LOWER = 106; + K_LOWER = 107; + L_LOWER = 108; + M_LOWER = 109; + N_LOWER = 110; + O_LOWER = 111; + P_LOWER = 112; + Q_LOWER = 113; + R_LOWER = 114; + S_LOWER = 115; + T_LOWER = 116; + U_LOWER = 117; + V_LOWER = 118; + W_LOWER = 119; + X_LOWER = 120; + Y_LOWER = 121; + Z_LOWER = 122; + OPEN_CURLY_BRACE = 123; + PIPE = 124; + CLOSE_CURLY_BRACE_ = 125; + TILDE = 126; + } + + oneof rhs { + Unicode unicode = 1; + AsciiValue ascii_value = 2; + } + // TODO(metzman): Determine if we care about unicode points not covered here. +} + +message Nmstart { + enum AsciiValue { + A_UPPER = 65; + B_UPPER = 66; + C_UPPER = 67; + D_UPPER = 68; + E_UPPER = 69; + F_UPPER = 70; + G_UPPER = 71; + H_UPPER = 72; + I_UPPER = 73; + J_UPPER = 74; + K_UPPER = 75; + L_UPPER = 76; + M_UPPER = 77; + N_UPPER = 78; + O_UPPER = 79; + P_UPPER = 80; + Q_UPPER = 81; + R_UPPER = 82; + S_UPPER = 83; + T_UPPER = 84; + U_UPPER = 85; + V_UPPER = 86; + W_UPPER = 87; + X_UPPER = 88; + Y_UPPER = 89; + Z_UPPER = 90; + A_LOWER = 97; + B_LOWER = 98; + C_LOWER = 99; + D_LOWER = 100; + E_LOWER = 101; + F_LOWER = 102; + G_LOWER = 103; + H_LOWER = 104; + I_LOWER = 105; + J_LOWER = 106; + K_LOWER = 107; + L_LOWER = 108; + M_LOWER = 109; + N_LOWER = 110; + O_LOWER = 111; + P_LOWER = 112; + Q_LOWER = 113; + R_LOWER = 114; + S_LOWER = 115; + T_LOWER = 116; + U_LOWER = 117; + V_LOWER = 118; + W_LOWER = 119; + X_LOWER = 120; + Y_LOWER = 121; + Z_LOWER = 122; + } + + oneof rhs { + AsciiValue ascii_value = 1; + Escape escape = 2; + // TODO(metzman): Add nonascii token once (if) I implement it. + } +} + +message Nmchar { + enum AsciiValue { + MINUS = 45; + ZERO = 48; + ONE = 49; + TWO = 50; + THREE = 51; + FOUR = 52; + FIVE = 53; + SIX = 54; + SEVEN = 55; + EIGHT = 56; + NINE = 57; + A_UPPER = 65; + B_UPPER = 66; + C_UPPER = 67; + D_UPPER = 68; + E_UPPER = 69; + F_UPPER = 70; + G_UPPER = 71; + H_UPPER = 72; + I_UPPER = 73; + J_UPPER = 74; + K_UPPER = 75; + L_UPPER = 76; + M_UPPER = 77; + N_UPPER = 78; + O_UPPER = 79; + P_UPPER = 80; + Q_UPPER = 81; + R_UPPER = 82; + S_UPPER = 83; + T_UPPER = 84; + U_UPPER = 85; + V_UPPER = 86; + W_UPPER = 87; + X_UPPER = 88; + Y_UPPER = 89; + Z_UPPER = 90; + A_LOWER = 97; + B_LOWER = 98; + C_LOWER = 99; + D_LOWER = 100; + E_LOWER = 101; + F_LOWER = 102; + G_LOWER = 103; + H_LOWER = 104; + I_LOWER = 105; + J_LOWER = 106; + K_LOWER = 107; + L_LOWER = 108; + M_LOWER = 109; + N_LOWER = 110; + O_LOWER = 111; + P_LOWER = 112; + Q_LOWER = 113; + R_LOWER = 114; + S_LOWER = 115; + T_LOWER = 116; + U_LOWER = 117; + V_LOWER = 118; + W_LOWER = 119; + X_LOWER = 120; + Y_LOWER = 121; + Z_LOWER = 122; + } + oneof rhs { + AsciiValue ascii_value = 1; + Escape escape = 2; + // TODO(metzman): Add nonascii token once (if) I implement it. + } +} + +// string1, string2 and string +message String { + // TODO(metzman): determine if these hacks are more efficient than enforcing + // constraints on string types in the actual code. + required bool use_single_quotes = 1; + repeated StringCharOrQuote string_char_quotes = 2; +} + +// Not in grammar. +message StringCharOrQuote { + enum QuoteChar { + UNSET = 0; + IS_SET = 1; + } + oneof rhs { + StringChar string_char = 2; + QuoteChar quote_char = 1; + } +} + +message StringChar { + enum Space { + UNSET = 0; + IS_SET = 1; + } + oneof rhs { + UrlChar url_char = 1; + Space space = 2; + // '\' nl + Nl nl = 3; + } +} + +message Ident { + optional bool starting_minus = 1 [default = false]; // - + required Nmstart nmstart = 2; + repeated Nmchar nmchars = 3; +} + +message Num { + required sint64 signed_int_value = 1; + optional float float_value = 2; +} + +message UrlChar { + enum AsciiValue { + NUL = 0; + // #x9 + HT = 9; + + // #x21 + EXCLAMATION_POINT = 33; + + // #x23-#x26 + HASH = 35; + DOLLAR = 36; + PERCENT = 37; + AMPERSAND = 38; + + // #x26-#x27 + APOSTROPHE = 39; + OPEN_PAREN = 40; + CLOSE_PAREN = 41; + STAR = 42; + PLUS = 43; + COMMA = 44; + MINUS = 45; + DOT = 46; + SLASH = 47; + ZERO = 48; + ONE = 49; + TWO = 50; + THREE = 51; + FOUR = 52; + FIVE = 53; + SIX = 54; + SEVEN = 55; + EIGHT = 56; + NINE = 57; + COLON = 58; + SEMI_COLON = 59; + LESS_THAN = 60; + EQUAL = 61; + GREATER_THAN = 62; + QUESTION = 63; + AT_SIGN = 64; + A_UPPER = 65; + B_UPPER = 66; + C_UPPER = 67; + D_UPPER = 68; + E_UPPER = 69; + F_UPPER = 70; + G_UPPER = 71; + H_UPPER = 72; + I_UPPER = 73; + J_UPPER = 74; + K_UPPER = 75; + L_UPPER = 76; + M_UPPER = 77; + N_UPPER = 78; + O_UPPER = 79; + P_UPPER = 80; + Q_UPPER = 81; + R_UPPER = 82; + S_UPPER = 83; + T_UPPER = 84; + U_UPPER = 85; + V_UPPER = 86; + W_UPPER = 87; + X_UPPER = 88; + Y_UPPER = 89; + Z_UPPER = 90; + OPEN_BRACKET = 91; + BACKSLASH = 92; + CLOSE_BRACKET = 93; + CARET = 94; + UNDERSCORE = 95; + BACKTICK = 96; + A_LOWER = 97; + B_LOWER = 98; + C_LOWER = 99; + D_LOWER = 100; + E_LOWER = 101; + F_LOWER = 102; + G_LOWER = 103; + H_LOWER = 104; + I_LOWER = 105; + J_LOWER = 106; + K_LOWER = 107; + L_LOWER = 108; + M_LOWER = 109; + N_LOWER = 110; + O_LOWER = 111; + P_LOWER = 112; + Q_LOWER = 113; + R_LOWER = 114; + S_LOWER = 115; + T_LOWER = 116; + U_LOWER = 117; + V_LOWER = 118; + W_LOWER = 119; + X_LOWER = 120; + Y_LOWER = 121; + Z_LOWER = 122; + OPEN_CURLY_BRACE = 123; + PIPE = 124; + CLOSE_CURLY_BRACE_ = 125; + TILDE = 126; + } + oneof rhs { + AsciiValue ascii_value = 1; + Escape escape = 2; + // TODO(metzman): Support nonascii tokens. + } +} + +message W { + repeated UnrepeatedW unrepeated_w = 1; +} + +// Not in grammar +message UnrepeatedW { + enum AsciiValue { + // #x9 ('\t') + HT = 9; + // #xA ('\n') + LF = 10; + // #xC ('\f') + FF = 12; + // #xD ('\r') + CR = 13; + // #x20 (' ') + SPACE = 32; + } + required AsciiValue ascii_value = 1; +} + +message Nl { + enum NewlineKind { + // #xA ('\n') + LF = 10; + // #xD #xA ('\r\n') Pseudo value, since we don't need SOH + CR_LF = 1; + // #xD ('\r') + CR = 13; + // #xC ('\f') + FF = 12; + } + required NewlineKind newline_kind = 1; +} + +// {num}[px|cm|mm|in|pt|pc] +message Length { + enum Unit { + PX = 1; + CM = 2; + MM = 3; + IN = 4; + PT = 5; + PC = 6; + } + required Num num = 1; + required Unit unit = 2; +} + +// {num}[deg|rad|grad] +message Angle { + enum Unit { + DEG = 1; + RAD = 2; + GRAD = 3; + } + required Num num = 1; + required Unit unit = 2; +} + +// {num}[ms|s] +message Time { + enum Unit { + MS = 1; + S = 2; + } + required Num num = 1; + required Unit unit = 2; +} + +// {num}[Hz|kHz] +message Freq { + enum Unit { + // Hack around build bug since some system header #defines HZ. + _HZ = 1; + KHZ = 2; + } + required Num num = 1; + required Unit unit = 2; +} + +message Uri { + // "url(" w (string | url* ) w ")" + // TODO(metzman): Add url token once (if) I implement it. + // optional String value = 1; +} + +// FUNCTION. Not named Function to avoid conflict. +message FunctionToken { + required Ident ident = 1; +} +// end tokens + +// rules +// TODO(metzman): Add rules for @keyframes (including +// -webkit-keyframes), and @supports. +message StyleSheet { + optional CharsetDeclaration charset_declaration = 1; + repeated Import imports = 2; + repeated Namespace namespaces = 3; + repeated NestedAtRule nested_at_rules = 4; +} + +// Not in grammar. +message CharsetDeclaration { + enum EncodingId { + UTF_8 = 1; + UTF_16 = 2; + UTF_32 = 3; + } + required EncodingId encoding_id = 1; +} + +// Not in grammar. +message NestedAtRule { + oneof rhs { + Ruleset ruleset = 1; + Media media = 2; + Page page = 3; + FontFace font_face = 4; + Viewport viewport = 5; + SupportsRule supports_rule = 6; + } +} + +message SupportsRule { + required SupportsCondition supports_condition = 1; + repeated AtRuleOrRulesets at_rule_or_rulesets = 2; +} + +message AtRuleOrRulesets { + required AtRuleOrRuleset first = 1; + repeated AtRuleOrRuleset laters = 2; +} + +message AtRuleOrRuleset { + required Ruleset ruleset = 1; + optional NestedAtRule at_rule = 2; +} + +message SupportsCondition { + // Using PropertyAndValue rather than declaration means that there + // will always be a declaration. This is syntactically correct but + // means we may miss some error paths. + // TODO(metzman): Figure out what to do about generating invalid output that + // causes more coverage. Maybe doing so infrequently is the correct move. + required PropertyAndValue property_and_value = 1; // Default. + // TODO(metzman): Do functions also need to be supported? + required bool not_condition = 2; + oneof rhs { + BinarySupportsCondition and_supports_condition = 3; + BinarySupportsCondition or_supports_condition = 4; + } +} + +message BinarySupportsCondition { + required SupportsCondition condition_1 = 1; + required SupportsCondition condition_2 = 2; +} + +message Viewport { + repeated ViewportPropertyAndValue properties_and_values = 1; +} + +message ViewportPropertyAndValue { + required ViewportProperty property = 1; + required ViewportValue value = 2; +} + +message ViewportProperty { + enum PropertyId { + MIN_WIDTH = 1; + MAX_WIDTH = 2; + WIDTH = 3; + MIN_HEIGHT = 4; + MAX_HEIGHT = 5; + HEIGHT = 6; + ZOOM = 7; + MIN_ZOOM = 8; + USER_ZOOM = 9; + MAX_ZOOM = 10; + ORIENTATION = 11; + } + required PropertyId id = 1; +} + +message ViewportValue { + enum ValueId { + LANDSCAPE = 1; + PORTRAIT = 2; + AUTO = 3; + ZOOM = 4; + FIXED = 5; + NONE = 6; + } + required ValueId value_id = 1; + oneof rhs { + Length length = 2; + Num num = 3; + } +} + +message Import { + enum SrcId { + RELATIVE_STRING = 1; + FULL_URL = 2; + } + optional SrcId src_id = 1; + optional MediaQueryList media_query_list = 2; +} + +// Media based on https://developer.mozilla.org/en-US/docs/Web/CSS/@media +message MediaQueryList { + repeated MediaQuery media_queries = 1; +} + +message MediaQuery { + required MediaCondition media_condition = 1; + optional MediaQueryPartTwo media_query_part_two = 2; +} + +// Not in spec. +message MediaQueryPartTwo { + enum NotOrOnly { + NOT = 1; + ONLY = 2; + } + optional NotOrOnly not_or_only = 1; + required MediaType media_type = 2; + optional MediaConditionWithoutOr media_condition_without_or = 3; +} + +message MediaConditionWithoutOr { + required MediaNot media_not = 1; + oneof rhs { + MediaAnd media_and = 2; + MediaInParens media_in_parens = 3; + } +} + +message MediaCondition { + required MediaAnd media_and = 1; + oneof rhs { + MediaNot media_not = 2; + MediaOr media_or = 3; + MediaInParens media_in_parens = 4; + } +} + +message MediaType { + enum ValueId { + ALL = 1; + BRAILLE = 2; + EMBOSSED = 3; + HANDHELD = 4; + PRINT = 5; + PROJECTION = 6; + SCREEN = 7; + SPEECH = 8; + TTY = 9; + TV = 10; + INVALID_MEDIA_TYPE = 11; + } + required ValueId value_id = 1; +} + +message MediaNot { + required MediaInParens media_in_parens = 1; +} + +message MediaAnd { + required MediaInParens first_media_in_parens = 1; + required MediaInParens second_media_in_parens = 2; + repeated MediaInParens media_in_parens_list = 3; +} + +message MediaOr { + required MediaInParens first_media_in_parens = 1; + required MediaInParens second_media_in_parens = 2; + repeated MediaInParens media_in_parens_list = 3; +} + +message MediaInParens { + required MediaFeature media_feature = 1; + optional MediaCondition media_condition = 2; +} + +message MediaFeature { + required MfPlain mf_plain = 1; + optional MfBool mf_bool = 2; + // TODO(metzman): Implement <mf-range> +} + +// TODO(metzman): implement <general-enclosed> + +message MfPlain { + required MfName property = 1; + required MfValue value = 2; +} + +message MfBool { + required MfName mf_name = 1; +} + +message MfName { + enum ValueId { + ANY_HOVER = 1; + ANY_POINTER = 2; + COLOR = 3; + COLOR_INDEX = 4; + COLOR_GAMUT = 5; + GRID = 6; + MONOCHROME = 7; + HEIGHT = 8; + HOVER = 9; + WIDTH = 10; + ORIENTATION = 11; + ASPECT_RATIO = 12; + DEVICE_ASPECT_RATIO = 13; + _WEBKIT_DEVICE_PIXEL_RATIO = 14; + DEVICE_HEIGHT = 15; + DEVICE_WIDTH = 16; + DISPLAY_MODE = 17; + MAX_COLOR = 18; + MAX_COLOR_INDEX = 19; + MAX_ASPECT_RATIO = 20; + MAX_DEVICE_ASPECT_RATIO = 21; + _WEBKIT_MAX_DEVICE_PIXEL_RATIO = 22; + MAX_DEVICE_HEIGHT = 23; + MAX_DEVICE_WIDTH = 24; + MAX_HEIGHT = 25; + MAX_MONOCHROME = 26; + MAX_WIDTH = 27; + MAX_RESOLUTION = 28; + MIN_COLOR = 29; + MIN_COLOR_INDEX = 30; + MIN_ASPECT_RATIO = 31; + MIN_DEVICE_ASPECT_RATIO = 32; + _WEBKIT_MIN_DEVICE_PIXEL_RATIO = 33; + MIN_DEVICE_HEIGHT = 34; + MIN_DEVICE_WIDTH = 35; + MIN_HEIGHT = 36; + MIN_MONOCHROME = 37; + MIN_WIDTH = 38; + MIN_RESOLUTION = 39; + POINTER = 40; + RESOLUTION = 41; + _WEBKIT_TRANSFORM_3D = 42; + SCAN = 43; + SHAPE = 44; + IMMERSIVE = 45; + DYNAMIC_RANGE = 46; + VIDEO_DYNAMIC_RANGE = 47; + INVALID_NAME = 48; + } + required ValueId id = 1; +} + +message MfValue { + required Num num = 1; + oneof rhs { + Length length = 2; // Called <dimension> on developer.mozilla.org + Ident ident = 3; + // TODO(metzman) implement <mf-range> + } +} + +message Namespace { + optional NamespacePrefix namespace_prefix = 1; + oneof rhs { + String string = 2; + Uri uri = 3; + } +} + +// TODO(metzman): Determine if this is unnecessary. +message NamespacePrefix { + required Ident ident = 1; +} + +message Media { + required MediaQueryList media_query_list = 1; + repeated Ruleset rulesets = 2; +} + +message Page { + optional Ident ident = 1; + optional PseudoPage pseudo_page = 2; + required DeclarationList declaration_list = 3; +} + +// Not in grammar. +message DeclarationList { + required Declaration first_declaration = 1; + repeated Declaration later_declarations = 2; +} + +// TODO(metzman): Determine if this is unnecessary. +message PseudoPage { + required Ident ident = 1; +} + +message FontFace { + // required DeclarationList declaration_list = 1; + // https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face#Formal_syntax + // repeated FontFaceContents font_face_contents = 1; +} + +message Operator { + enum AsciiValue { + COMMA = 44; + SLASH = 47; + } + optional AsciiValue ascii_value = 1; +} + +message UnaryOperator { + enum AsciiValue { + PLUS = 43; + MINUS = 45; + } + required AsciiValue ascii_value = 1; +} + +// TODO(metzman): Determine if this is unnecessary. +message Property { + enum NameId { +{{property_proto_enums}} + } + required NameId name_id = 1; +} + +message Ruleset { + required SelectorList selector_list = 1; + required DeclarationList declaration_list = 2; +} + +// Not in grammar. +message SelectorList { + required Selector first_selector = 1; + repeated Selector later_selectors = 2; +} + +message Attr { + enum Type { + NONE = 1; + EQUAL = 6; + TILDE = 126; + PIPE = 124; + DOLLAR = 36; + STAR = 42; + } + required Type type = 1; + optional bool attr_i = 2; + // TODO(metzman): Allow values to be set instead of hardcoding. +} + +enum PseudoType { + CLASS = 1; + ELEMENT = 2; +} + +enum Combinator { + NONE = 1; + DOLLAR = 36; + COMMA = 44; + GREATER_THAN = 62; + PLUS = 43; + TILDE = 126; +} + +message Selector { + enum Type { + ELEMENT = 1; + CLASS = 2; + ID = 3; + // TODO(metzman): Support the different variations of universal selectors. + UNIVERSAL = 4; + ATTR = 5; + } + required Type type = 1; + required Attr attr = 2; + // TODO(metzman): Allow the selector value to be set by fuzzer. + required PseudoType pseudo_type = 3; + enum PseudoValueId { + _INTERNAL_AUTOFILL_PREVIEWED = 1; + _INTERNAL_AUTOFILL_SELECTED = 2; + _INTERNAL_IS_HTML = 3; + _INTERNAL_LIST_BOX = 4; + _INTERNAL_MEDIA_CONTROLS_OVERLAY_CAST_BUTTON = 5; + _INTERNAL_MULTI_SELECT_FOCUS = 6; + _INTERNAL_POPUP_OPEN = 7; + _INTERNAL_SHADOW_HOST_HAS_APPEARANCE = 8; + _INTERNAL_SPATIAL_NAVIGATION_FOCUS = 9; + _INTERNAL_VIDEO_PERSISTENT = 10; + _INTERNAL_VIDEO_PERSISTENT_ANCESTOR = 11; + _WEBKIT_ANY_LINK = 12; + _WEBKIT_AUTOFILL = 13; + _WEBKIT_DRAG = 14; + _WEBKIT_FULL_PAGE_MEDIA = 15; + _WEBKIT_FULL_SCREEN = 16; + _WEBKIT_FULL_SCREEN_ANCESTOR = 17; + _WEBKIT_RESIZER = 18; + _WEBKIT_SCROLLBAR = 19; + _WEBKIT_SCROLLBAR_BUTTON = 20; + _WEBKIT_SCROLLBAR_CORNER = 21; + _WEBKIT_SCROLLBAR_THUMB = 22; + _WEBKIT_SCROLLBAR_TRACK = 23; + _WEBKIT_SCROLLBAR_TRACK_PIECE = 24; + ACTIVE = 25; + AFTER = 26; + AUTOFILL = 27; + BACKDROP = 28; + BEFORE = 29; + CHECKED = 30; + CORNER_PRESENT = 31; + CUE = 32; + DECREMENT = 33; + DEFAULT = 34; + DEFINED = 35; + DISABLED = 36; + DOUBLE_BUTTON = 37; + EMPTY = 38; + ENABLED = 39; + END = 40; + FIRST = 41; + FIRST_CHILD = 42; + FIRST_LETTER = 43; + FIRST_LINE = 44; + FIRST_OF_TYPE = 45; + FOCUS = 46; + FOCUS_WITHIN = 47; + FULLSCREEN = 48; + FUTURE = 49; + HORIZONTAL = 50; + HOST = 51; + HOVER = 52; + IN_RANGE = 53; + INCREMENT = 54; + INDETERMINATE = 55; + INVALID = 56; + LAST_CHILD = 57; + LAST_OF_TYPE = 58; + LEFT = 59; + LINK = 60; + NO_BUTTON = 61; + ONLY_CHILD = 62; + ONLY_OF_TYPE = 63; + OPTIONAL = 64; + OUT_OF_RANGE = 65; + PAST = 66; + PLACEHOLDER = 67; + PLACEHOLDER_SHOWN = 68; + READ_ONLY = 69; + READ_WRITE = 70; + REQUIRED = 71; + RIGHT = 72; + ROOT = 73; + SCOPE = 74; + SELECTION = 75; + SINGLE_BUTTON = 76; + START = 77; + TARGET = 78; + VALID = 79; + VERTICAL = 80; + VISITED = 81; + WINDOW_INACTIVE = 82; + _WEBKIT_ANY = 83; + HOST_CONTEXT = 84; + LANG = 85; + NOT = 86; + NTH_CHILD = 87; + NTH_LAST_CHILD = 88; + NTH_LAST_OF_TYPE = 89; + NTH_OF_TYPE = 90; + SLOTTED = 91; + XR_OVERLAY = 92; + INVALID_PSEUDO_VALUE = 93; + } + optional PseudoValueId pseudo_value_id = 4; + required Combinator combinator = 5; +} + +message Pseudo { + oneof rhs { + Ident ident_1 = 1; + FunctionToken function_token = 2; + } + required Ident ident_2 = 3; +} + +message Declaration { + // property ':' S* expr prio? | /* empty */ + optional PropertyAndValue property_and_value = 1; +} + +message PropertyAndValue { + required Property property = 1; + required Expr expr = 2; + enum Prio { + UNSET = 0; + IS_SET = 1; + } + optional Prio prio = 3; + enum ValueId { +{{value_proto_enums}} + }; + + optional ValueId value_id = 4; +} + +message Expr { + required Term term = 1; + repeated OperatorTerm operator_terms = 2; +} + +// Not in grammar. +message OperatorTerm { + required Operator _operator = 1; + required Term term = 2; +} + +message Term { + optional UnaryOperator unary_operator = 1; + oneof rhs { + // [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | + // TIME S* | FREQ S* | function ] + TermPart term_part = 2; + // | STRING + String string = 3; + } + // S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor + optional Ident ident = 4; + optional Uri uri = 5; + // TODO(metzman): Add UNICODERANGE token once (if) I implement it. + optional Hexcolor hexcolor = 6; +} + +// Not in grammar. +message TermPart { + // NUMBER + required Num number = 1; + // S* | PERCENTAGE + optional Num percentage = 2; // num "%" + // S* | LENGTH + optional Length length = 3; + optional Num ems = 4; // {num}em + optional Num exs = 5; // {num}ex + optional Angle angle = 6; + optional Time time = 7; + optional Freq freq = 8; + optional Function function = 9; +} + +message Function { + required FunctionToken function_token = 1; + required Expr expr = 2; +} + +message Hexcolor { + required HexcolorThree first_three = 1; + optional HexcolorThree last_three = 2; +} + +// Not in grammar. +message HexcolorThree { + // 0-9A-Za-z + required H ascii_value_1 = 1; + required H ascii_value_2 = 2; + required H ascii_value_3 = 3; +} + +message Input { + enum CSSParserMode { + kHTMLStandardMode = 0; + kHTMLQuirksMode = 1; + kSVGAttributeMode = 2; + kCSSViewportRuleMode = 3; + kCSSFontFaceRuleMode = 4; + kUASheetMode = 5; + } + enum SecureContextMode { + kInsecureContext = 0; + kSecureContext = 1; + } + required CSSParserMode css_parser_mode = 1; + required bool defer_property_parsing = 2; + required StyleSheet style_sheet = 3; + required bool is_live_profile = 4; + required SecureContextMode secure_context_mode = 5; +}
diff --git a/third_party/blink/renderer/build/scripts/core/css/parser/templates/css_proto_converter_generated.h.tmpl b/third_party/blink/renderer/build/scripts/core/css/parser/templates/css_proto_converter_generated.h.tmpl new file mode 100644 index 0000000..4b1b342 --- /dev/null +++ b/third_party/blink/renderer/build/scripts/core/css/parser/templates/css_proto_converter_generated.h.tmpl
@@ -0,0 +1,16 @@ +{% from 'templates/macros.tmpl' import license, source_files_for_generated_file %} +{{license()}} + +{{source_files_for_generated_file(template_file, input_files)}} + +const std::string Converter::kValueLookupTable[] = { + "", // This is just to fill the zeroth spot. It should not be used. +{{value_keywords}} + "INVALID_VALUE", +}; + +const std::string Converter::kPropertyLookupTable[] = { + "", // This is just to fill the zeroth spot. It should not be used. +{{property_names}} + "INVALID_PROPERTY", +};
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 62eee2d8..a57477ed 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1770,6 +1770,19 @@ seed_corpus = "//testing/libfuzzer/fuzzers/content_security_policy_corpus" } +css_properties("make_css_proto") { + script = "../build/scripts/core/css/parser/make_proto.py" + in_files = [ "css/css_value_keywords.json5" ] + other_inputs = [ + "../build/scripts/core/css/parser/templates/css.proto.tmpl", + "../build/scripts/core/css/parser/templates/css_proto_converter_generated.h.tmpl", + ] + outputs = [ + "$blink_core_output_dir/css/parser/css.proto", + "$blink_core_output_dir/css/parser/css_proto_converter_generated.h", + ] +} + fuzzer_test("css_parser_proto_fuzzer") { sources = [ "css/parser/css_parser_proto_fuzzer.cc", @@ -1786,7 +1799,9 @@ } proto_library("css_proto") { - sources = [ "css/parser/css.proto" ] + sources = [ "$blink_core_output_dir/css/parser/css.proto" ] + proto_out_dir = "third_party/blink/renderer/core/css/parser" + deps = [ ":make_css_proto" ] } fuzzer_test("blink_html_tokenizer_fuzzer") {
diff --git a/third_party/blink/renderer/core/OWNERS b/third_party/blink/renderer/core/OWNERS index 042050c4..f260e1df2 100644 --- a/third_party/blink/renderer/core/OWNERS +++ b/third_party/blink/renderer/core/OWNERS
@@ -70,4 +70,3 @@ wangxianzhu@chromium.org yhirano@chromium.org yoavweiss@chromium.org -yutak@chromium.org
diff --git a/third_party/blink/renderer/core/css/parser/css.proto b/third_party/blink/renderer/core/css/parser/css.proto deleted file mode 100644 index 08320f97..0000000 --- a/third_party/blink/renderer/core/css/parser/css.proto +++ /dev/null
@@ -1,2479 +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. - -// Based on the grammar provided here: https://goo.gl/svLze7 -// Most top level definitions here (mostly messages, but also the enum "h", is -// named after a rule or token in the grammar. The messages that aren't were -// implemented to hack around shortcomings in the protobuf format (such as -// "StringCharOrQuote"). These can be identified because they are preceded by -// a comment that says "Not in grammar". - -syntax = "proto2"; - -package css_proto_converter; - -// Tokens -// TODO(metzman): Implement CDO, CDC, UNICODERANGE, and range. -// The following tokens are implmented in code and do not have their own -// message: INCLUDES, DASHMATCH, HASH, STRING IMPORT_SYM, PAGE_SYM, MEDIA_SYM, -// FONT_FACE_SYM, CHARSET_SYM, NAMESPACE_SYM, IMPORTANT_SYM, EMS, EXS, NUMBER, -// and PERCENTAGE. -// DIMEN not implemented since it isnt used in any production. - -// This is named "h" because it represents the "h" token in the grammar this is -// based off of. -enum H { - ZERO = 48; - ONE = 49; - TWO = 50; - THREE = 51; - FOUR = 52; - FIVE = 53; - SIX = 54; - SEVEN = 55; - EIGHT = 56; - NINE = 57; - A_UPPER = 65; - B_UPPER = 66; - C_UPPER = 67; - D_UPPER = 68; - E_UPPER = 69; - F_UPPER = 70; - A_LOWER = 97; - B_LOWER = 98; - C_LOWER = 99; - D_LOWER = 100; - E_LOWER = 101; - F_LOWER = 102; -} - -// TODO(metzman): Add "nonascii" token from grammar. - -message Unicode { - required H ascii_value_1 = 1; - optional H ascii_value_2 = 2; - optional H ascii_value_3 = 3; - optional H ascii_value_4 = 4; - optional H ascii_value_5 = 5; - optional H ascii_value_6 = 6; - optional UnrepeatedW unrepeated_w = 7; -} - -// unicode | '\' [#x20-#x7E#x80-#xD7FF#xE000-#xFFFD#x10000-#x10FFFF] -message Escape { - // #x20-#x7E - enum AsciiValue { - SPACE = 32; - EXCLAMATION_POINT = 33; - DOUBLE_QUOTE = 34; - HASH = 35; - DOLLAR = 36; - PERCENT = 37; - AMPERSAND = 38; - APOSTROPHE = 39; - OPEN_PAREN = 40; - CLOSE_PAREN = 41; - STAR = 42; - PLUS = 43; - COMMA = 44; - MINUS = 45; - DOT = 46; - SLASH = 47; - ZERO = 48; - ONE = 49; - TWO = 50; - THREE = 51; - FOUR = 52; - FIVE = 53; - SIX = 54; - SEVEN = 55; - EIGHT = 56; - NINE = 57; - COLON = 58; - SEMI_COLON = 59; - LESS_THAN = 60; - EQUAL = 61; - GREATER_THAN = 62; - QUESTION = 63; - AT_SIGN = 64; - A_UPPER = 65; - B_UPPER = 66; - C_UPPER = 67; - D_UPPER = 68; - E_UPPER = 69; - F_UPPER = 70; - G_UPPER = 71; - H_UPPER = 72; - I_UPPER = 73; - J_UPPER = 74; - K_UPPER = 75; - L_UPPER = 76; - M_UPPER = 77; - N_UPPER = 78; - O_UPPER = 79; - P_UPPER = 80; - Q_UPPER = 81; - R_UPPER = 82; - S_UPPER = 83; - T_UPPER = 84; - U_UPPER = 85; - V_UPPER = 86; - W_UPPER = 87; - X_UPPER = 88; - Y_UPPER = 89; - Z_UPPER = 90; - OPEN_BRACKET = 91; - BACKSLASH = 92; - CLOSE_BRACKET = 93; - CARET = 94; - UNDERSCORE = 95; - BACKTICK = 96; - A_LOWER = 97; - B_LOWER = 98; - C_LOWER = 99; - D_LOWER = 100; - E_LOWER = 101; - F_LOWER = 102; - G_LOWER = 103; - H_LOWER = 104; - I_LOWER = 105; - J_LOWER = 106; - K_LOWER = 107; - L_LOWER = 108; - M_LOWER = 109; - N_LOWER = 110; - O_LOWER = 111; - P_LOWER = 112; - Q_LOWER = 113; - R_LOWER = 114; - S_LOWER = 115; - T_LOWER = 116; - U_LOWER = 117; - V_LOWER = 118; - W_LOWER = 119; - X_LOWER = 120; - Y_LOWER = 121; - Z_LOWER = 122; - OPEN_CURLY_BRACE = 123; - PIPE = 124; - CLOSE_CURLY_BRACE_ = 125; - TILDE = 126; - } - - oneof rhs { - Unicode unicode = 1; - AsciiValue ascii_value = 2; - } - // TODO(metzman): Determine if we care about unicode points not covered here. -} - -message Nmstart { - enum AsciiValue { - A_UPPER = 65; - B_UPPER = 66; - C_UPPER = 67; - D_UPPER = 68; - E_UPPER = 69; - F_UPPER = 70; - G_UPPER = 71; - H_UPPER = 72; - I_UPPER = 73; - J_UPPER = 74; - K_UPPER = 75; - L_UPPER = 76; - M_UPPER = 77; - N_UPPER = 78; - O_UPPER = 79; - P_UPPER = 80; - Q_UPPER = 81; - R_UPPER = 82; - S_UPPER = 83; - T_UPPER = 84; - U_UPPER = 85; - V_UPPER = 86; - W_UPPER = 87; - X_UPPER = 88; - Y_UPPER = 89; - Z_UPPER = 90; - A_LOWER = 97; - B_LOWER = 98; - C_LOWER = 99; - D_LOWER = 100; - E_LOWER = 101; - F_LOWER = 102; - G_LOWER = 103; - H_LOWER = 104; - I_LOWER = 105; - J_LOWER = 106; - K_LOWER = 107; - L_LOWER = 108; - M_LOWER = 109; - N_LOWER = 110; - O_LOWER = 111; - P_LOWER = 112; - Q_LOWER = 113; - R_LOWER = 114; - S_LOWER = 115; - T_LOWER = 116; - U_LOWER = 117; - V_LOWER = 118; - W_LOWER = 119; - X_LOWER = 120; - Y_LOWER = 121; - Z_LOWER = 122; - } - - oneof rhs { - AsciiValue ascii_value = 1; - Escape escape = 2; - // TODO(metzman): Add nonascii token once (if) I implement it. - } -} - -message Nmchar { - enum AsciiValue { - MINUS = 45; - ZERO = 48; - ONE = 49; - TWO = 50; - THREE = 51; - FOUR = 52; - FIVE = 53; - SIX = 54; - SEVEN = 55; - EIGHT = 56; - NINE = 57; - A_UPPER = 65; - B_UPPER = 66; - C_UPPER = 67; - D_UPPER = 68; - E_UPPER = 69; - F_UPPER = 70; - G_UPPER = 71; - H_UPPER = 72; - I_UPPER = 73; - J_UPPER = 74; - K_UPPER = 75; - L_UPPER = 76; - M_UPPER = 77; - N_UPPER = 78; - O_UPPER = 79; - P_UPPER = 80; - Q_UPPER = 81; - R_UPPER = 82; - S_UPPER = 83; - T_UPPER = 84; - U_UPPER = 85; - V_UPPER = 86; - W_UPPER = 87; - X_UPPER = 88; - Y_UPPER = 89; - Z_UPPER = 90; - A_LOWER = 97; - B_LOWER = 98; - C_LOWER = 99; - D_LOWER = 100; - E_LOWER = 101; - F_LOWER = 102; - G_LOWER = 103; - H_LOWER = 104; - I_LOWER = 105; - J_LOWER = 106; - K_LOWER = 107; - L_LOWER = 108; - M_LOWER = 109; - N_LOWER = 110; - O_LOWER = 111; - P_LOWER = 112; - Q_LOWER = 113; - R_LOWER = 114; - S_LOWER = 115; - T_LOWER = 116; - U_LOWER = 117; - V_LOWER = 118; - W_LOWER = 119; - X_LOWER = 120; - Y_LOWER = 121; - Z_LOWER = 122; - } - oneof rhs { - AsciiValue ascii_value = 1; - Escape escape = 2; - // TODO(metzman): Add nonascii token once (if) I implement it. - } -} - -// string1, string2 and string -message String { - // TODO(metzman): determine if these hacks are more efficient than enforcing - // constraints on string types in the actual code. - required bool use_single_quotes = 1; - repeated StringCharOrQuote string_char_quotes = 2; -} - -// Not in grammar. -message StringCharOrQuote { - enum QuoteChar { - UNSET = 0; - IS_SET = 1; - } - oneof rhs { - StringChar string_char = 2; - QuoteChar quote_char = 1; - } -} - -message StringChar { - enum Space { - UNSET = 0; - IS_SET = 1; - } - oneof rhs { - UrlChar url_char = 1; - Space space = 2; - // '\' nl - Nl nl = 3; - } -} - -message Ident { - optional bool starting_minus = 1 [default = false]; // - - required Nmstart nmstart = 2; - repeated Nmchar nmchars = 3; -} - -message Num { - required sint64 signed_int_value = 1; - optional float float_value = 2; -} - -message UrlChar { - enum AsciiValue { - NUL = 0; - // #x9 - HT = 9; - - // #x21 - EXCLAMATION_POINT = 33; - - // #x23-#x26 - HASH = 35; - DOLLAR = 36; - PERCENT = 37; - AMPERSAND = 38; - - // #x26-#x27 - APOSTROPHE = 39; - OPEN_PAREN = 40; - CLOSE_PAREN = 41; - STAR = 42; - PLUS = 43; - COMMA = 44; - MINUS = 45; - DOT = 46; - SLASH = 47; - ZERO = 48; - ONE = 49; - TWO = 50; - THREE = 51; - FOUR = 52; - FIVE = 53; - SIX = 54; - SEVEN = 55; - EIGHT = 56; - NINE = 57; - COLON = 58; - SEMI_COLON = 59; - LESS_THAN = 60; - EQUAL = 61; - GREATER_THAN = 62; - QUESTION = 63; - AT_SIGN = 64; - A_UPPER = 65; - B_UPPER = 66; - C_UPPER = 67; - D_UPPER = 68; - E_UPPER = 69; - F_UPPER = 70; - G_UPPER = 71; - H_UPPER = 72; - I_UPPER = 73; - J_UPPER = 74; - K_UPPER = 75; - L_UPPER = 76; - M_UPPER = 77; - N_UPPER = 78; - O_UPPER = 79; - P_UPPER = 80; - Q_UPPER = 81; - R_UPPER = 82; - S_UPPER = 83; - T_UPPER = 84; - U_UPPER = 85; - V_UPPER = 86; - W_UPPER = 87; - X_UPPER = 88; - Y_UPPER = 89; - Z_UPPER = 90; - OPEN_BRACKET = 91; - BACKSLASH = 92; - CLOSE_BRACKET = 93; - CARET = 94; - UNDERSCORE = 95; - BACKTICK = 96; - A_LOWER = 97; - B_LOWER = 98; - C_LOWER = 99; - D_LOWER = 100; - E_LOWER = 101; - F_LOWER = 102; - G_LOWER = 103; - H_LOWER = 104; - I_LOWER = 105; - J_LOWER = 106; - K_LOWER = 107; - L_LOWER = 108; - M_LOWER = 109; - N_LOWER = 110; - O_LOWER = 111; - P_LOWER = 112; - Q_LOWER = 113; - R_LOWER = 114; - S_LOWER = 115; - T_LOWER = 116; - U_LOWER = 117; - V_LOWER = 118; - W_LOWER = 119; - X_LOWER = 120; - Y_LOWER = 121; - Z_LOWER = 122; - OPEN_CURLY_BRACE = 123; - PIPE = 124; - CLOSE_CURLY_BRACE_ = 125; - TILDE = 126; - } - oneof rhs { - AsciiValue ascii_value = 1; - Escape escape = 2; - // TODO(metzman): Support nonascii tokens. - } -} - -message W { - repeated UnrepeatedW unrepeated_w = 1; -} - -// Not in grammar -message UnrepeatedW { - enum AsciiValue { - // #x9 ('\t') - HT = 9; - // #xA ('\n') - LF = 10; - // #xC ('\f') - FF = 12; - // #xD ('\r') - CR = 13; - // #x20 (' ') - SPACE = 32; - } - required AsciiValue ascii_value = 1; -} - -message Nl { - enum NewlineKind { - // #xA ('\n') - LF = 10; - // #xD #xA ('\r\n') Pseudo value, since we don't need SOH - CR_LF = 1; - // #xD ('\r') - CR = 13; - // #xC ('\f') - FF = 12; - } - required NewlineKind newline_kind = 1; -} - -// {num}[px|cm|mm|in|pt|pc] -message Length { - enum Unit { - PX = 1; - CM = 2; - MM = 3; - IN = 4; - PT = 5; - PC = 6; - } - required Num num = 1; - required Unit unit = 2; -} - -// {num}[deg|rad|grad] -message Angle { - enum Unit { - DEG = 1; - RAD = 2; - GRAD = 3; - } - required Num num = 1; - required Unit unit = 2; -} - -// {num}[ms|s] -message Time { - enum Unit { - MS = 1; - S = 2; - } - required Num num = 1; - required Unit unit = 2; -} - -// {num}[Hz|kHz] -message Freq { - enum Unit { - // Hack around build bug since some system header #defines HZ. - _HZ = 1; - KHZ = 2; - } - required Num num = 1; - required Unit unit = 2; -} - -message Uri { - // "url(" w (string | url* ) w ")" - // TODO(metzman): Add url token once (if) I implement it. - // optional String value = 1; -} - -// FUNCTION. Not named Function to avoid conflict. -message FunctionToken { - required Ident ident = 1; -} -// end tokens - -// rules -// TODO(metzman): Add rules for @keyframes (including -// -webkit-keyframes), and @supports. -message StyleSheet { - optional CharsetDeclaration charset_declaration = 1; - repeated Import imports = 2; - repeated Namespace namespaces = 3; - repeated NestedAtRule nested_at_rules = 4; -} - -// Not in grammar. -message CharsetDeclaration { - enum EncodingId { - UTF_8 = 1; - UTF_16 = 2; - UTF_32 = 3; - } - required EncodingId encoding_id = 1; -} - -// Not in grammar. -message NestedAtRule { - oneof rhs { - Ruleset ruleset = 1; - Media media = 2; - Page page = 3; - FontFace font_face = 4; - Viewport viewport = 5; - SupportsRule supports_rule = 6; - } -} - -message SupportsRule { - required SupportsCondition supports_condition = 1; - repeated AtRuleOrRulesets at_rule_or_rulesets = 2; -} - -message AtRuleOrRulesets { - required AtRuleOrRuleset first = 1; - repeated AtRuleOrRuleset laters = 2; -} - -message AtRuleOrRuleset { - required Ruleset ruleset = 1; - optional NestedAtRule at_rule = 2; -} - -message SupportsCondition { - // Using PropertyAndValue rather than declaration means that there - // will always be a declaration. This is syntactically correct but - // means we may miss some error paths. - // TODO(metzman): Figure out what to do about generating invalid output that - // causes more coverage. Maybe doing so infrequently is the correct move. - required PropertyAndValue property_and_value = 1; // Default. - // TODO(metzman): Do functions also need to be supported? - required bool not_condition = 2; - oneof rhs { - BinarySupportsCondition and_supports_condition = 3; - BinarySupportsCondition or_supports_condition = 4; - } -} - -message BinarySupportsCondition { - required SupportsCondition condition_1 = 1; - required SupportsCondition condition_2 = 2; -} - -message Viewport { - repeated ViewportPropertyAndValue properties_and_values = 1; -} - -message ViewportPropertyAndValue { - required ViewportProperty property = 1; - required ViewportValue value = 2; -} - -message ViewportProperty { - enum PropertyId { - MIN_WIDTH = 1; - MAX_WIDTH = 2; - WIDTH = 3; - MIN_HEIGHT = 4; - MAX_HEIGHT = 5; - HEIGHT = 6; - ZOOM = 7; - MIN_ZOOM = 8; - USER_ZOOM = 9; - MAX_ZOOM = 10; - ORIENTATION = 11; - } - required PropertyId id = 1; -} - -message ViewportValue { - enum ValueId { - LANDSCAPE = 1; - PORTRAIT = 2; - AUTO = 3; - ZOOM = 4; - FIXED = 5; - NONE = 6; - } - required ValueId value_id = 1; - oneof rhs { - Length length = 2; - Num num = 3; - } -} - -message Import { - enum SrcId { - RELATIVE_STRING = 1; - FULL_URL = 2; - } - optional SrcId src_id = 1; - optional MediaQueryList media_query_list = 2; -} - -// Media based on https://developer.mozilla.org/en-US/docs/Web/CSS/@media -message MediaQueryList { - repeated MediaQuery media_queries = 1; -} - -message MediaQuery { - required MediaCondition media_condition = 1; - optional MediaQueryPartTwo media_query_part_two = 2; -} - -// Not in spec. -message MediaQueryPartTwo { - enum NotOrOnly { - NOT = 1; - ONLY = 2; - } - optional NotOrOnly not_or_only = 1; - required MediaType media_type = 2; - optional MediaConditionWithoutOr media_condition_without_or = 3; -} - -message MediaConditionWithoutOr { - required MediaNot media_not = 1; - oneof rhs { - MediaAnd media_and = 2; - MediaInParens media_in_parens = 3; - } -} - -message MediaCondition { - required MediaAnd media_and = 1; - oneof rhs { - MediaNot media_not = 2; - MediaOr media_or = 3; - MediaInParens media_in_parens = 4; - } -} - -message MediaType { - enum ValueId { - ALL = 1; - BRAILLE = 2; - EMBOSSED = 3; - HANDHELD = 4; - PRINT = 5; - PROJECTION = 6; - SCREEN = 7; - SPEECH = 8; - TTY = 9; - TV = 10; - INVALID_MEDIA_TYPE = 11; - } - required ValueId value_id = 1; -} - -message MediaNot { - required MediaInParens media_in_parens = 1; -} - -message MediaAnd { - required MediaInParens first_media_in_parens = 1; - required MediaInParens second_media_in_parens = 2; - repeated MediaInParens media_in_parens_list = 3; -} - -message MediaOr { - required MediaInParens first_media_in_parens = 1; - required MediaInParens second_media_in_parens = 2; - repeated MediaInParens media_in_parens_list = 3; -} - -message MediaInParens { - required MediaFeature media_feature = 1; - optional MediaCondition media_condition = 2; -} - -message MediaFeature { - required MfPlain mf_plain = 1; - optional MfBool mf_bool = 2; - // TODO(metzman): Implement <mf-range> -} - -// TODO(metzman): implement <general-enclosed> - -message MfPlain { - required MfName property = 1; - required MfValue value = 2; -} - -message MfBool { - required MfName mf_name = 1; -} - -message MfName { - enum ValueId { - ANY_HOVER = 1; - ANY_POINTER = 2; - COLOR = 3; - COLOR_INDEX = 4; - COLOR_GAMUT = 5; - GRID = 6; - MONOCHROME = 7; - HEIGHT = 8; - HOVER = 9; - WIDTH = 10; - ORIENTATION = 11; - ASPECT_RATIO = 12; - DEVICE_ASPECT_RATIO = 13; - _WEBKIT_DEVICE_PIXEL_RATIO = 14; - DEVICE_HEIGHT = 15; - DEVICE_WIDTH = 16; - DISPLAY_MODE = 17; - MAX_COLOR = 18; - MAX_COLOR_INDEX = 19; - MAX_ASPECT_RATIO = 20; - MAX_DEVICE_ASPECT_RATIO = 21; - _WEBKIT_MAX_DEVICE_PIXEL_RATIO = 22; - MAX_DEVICE_HEIGHT = 23; - MAX_DEVICE_WIDTH = 24; - MAX_HEIGHT = 25; - MAX_MONOCHROME = 26; - MAX_WIDTH = 27; - MAX_RESOLUTION = 28; - MIN_COLOR = 29; - MIN_COLOR_INDEX = 30; - MIN_ASPECT_RATIO = 31; - MIN_DEVICE_ASPECT_RATIO = 32; - _WEBKIT_MIN_DEVICE_PIXEL_RATIO = 33; - MIN_DEVICE_HEIGHT = 34; - MIN_DEVICE_WIDTH = 35; - MIN_HEIGHT = 36; - MIN_MONOCHROME = 37; - MIN_WIDTH = 38; - MIN_RESOLUTION = 39; - POINTER = 40; - RESOLUTION = 41; - _WEBKIT_TRANSFORM_3D = 42; - SCAN = 43; - SHAPE = 44; - IMMERSIVE = 45; - DYNAMIC_RANGE = 46; - VIDEO_DYNAMIC_RANGE = 47; - INVALID_NAME = 48; - } - required ValueId id = 1; -} - -message MfValue { - required Num num = 1; - oneof rhs { - Length length = 2; // Called <dimension> on developer.mozilla.org - Ident ident = 3; - // TODO(metzman) implement <mf-range> - } -} - -message Namespace { - optional NamespacePrefix namespace_prefix = 1; - oneof rhs { - String string = 2; - Uri uri = 3; - } -} - -// TODO(metzman): Determine if this is unnecessary. -message NamespacePrefix { - required Ident ident = 1; -} - -message Media { - required MediaQueryList media_query_list = 1; - repeated Ruleset rulesets = 2; -} - -message Page { - optional Ident ident = 1; - optional PseudoPage pseudo_page = 2; - required DeclarationList declaration_list = 3; -} - -// Not in grammar. -message DeclarationList { - required Declaration first_declaration = 1; - repeated Declaration later_declarations = 2; -} - -// TODO(metzman): Determine if this is unnecessary. -message PseudoPage { - required Ident ident = 1; -} - -message FontFace { - // required DeclarationList declaration_list = 1; - // https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face#Formal_syntax - // repeated FontFaceContents font_face_contents = 1; -} - -message Operator { - enum AsciiValue { - COMMA = 44; - SLASH = 47; - } - optional AsciiValue ascii_value = 1; -} - -message UnaryOperator { - enum AsciiValue { - PLUS = 43; - MINUS = 45; - } - required AsciiValue ascii_value = 1; -} - -// TODO(metzman): Determine if this is unnecessary. -message Property { - enum NameId { - ALL = 1; - _WEBKIT_ANIMATION_ITERATION_COUNT = 2; - FONT_FEATURE_SETTINGS = 3; - _WEBKIT_TEXT_EMPHASIS_POSITION = 4; - _WEBKIT_TEXT_EMPHASIS_STYLE = 5; - GRID_TEMPLATE_ROWS = 6; - TEXT_UNDERLINE_POSITION = 7; - _WEBKIT_FLEX_GROW = 8; - SCROLL_MARGIN_RIGHT = 9; - _WEBKIT_COLUMN_RULE = 10; - _WEBKIT_ORDER = 11; - GRID_ROW_GAP = 12; - ROW_GAP = 13; - BACKDROP_FILTER = 14; - FONT_VARIANT_EAST_ASIAN = 15; - BUFFERED_RENDERING = 16; - _WEBKIT_APPEARANCE = 17; - OUTLINE_WIDTH = 18; - ALIGNMENT_BASELINE = 19; - _WEBKIT_FLEX_FLOW = 20; - COLUMN_RULE = 21; - GRID_COLUMN_GAP = 22; - _WEBKIT_BORDER_AFTER = 23; - _WEBKIT_COLUMN_BREAK_INSIDE = 24; - _WEBKIT_SHAPE_OUTSIDE = 25; - _WEBKIT_PRINT_COLOR_ADJUST = 26; - LIST_STYLE_TYPE = 27; - PAGE_BREAK_BEFORE = 28; - FLOOD_COLOR = 29; - TEXT_ANCHOR = 30; - _WEBKIT_PADDING_START = 31; - _WEBKIT_USER_SELECT = 32; - _WEBKIT_COLUMN_RULE_COLOR = 33; - PADDING_LEFT = 34; - _WEBKIT_BACKFACE_VISIBILITY = 35; - _WEBKIT_MARGIN_BEFORE = 36; - BREAK_INSIDE = 37; - COLUMN_COUNT = 38; - _WEBKIT_LOGICAL_HEIGHT = 39; - PERSPECTIVE = 40; - MAX_BLOCK_SIZE = 41; - _WEBKIT_ANIMATION_PLAY_STATE = 42; - BORDER_IMAGE_REPEAT = 43; - _INTERNAL_FONT_SIZE_DELTA = 44; - SCROLL_PADDING_BOTTOM = 45; - BORDER_RIGHT_STYLE = 46; - BORDER_LEFT_STYLE = 47; - SCROLL_MARGIN_BLOCK = 48; - FLEX_FLOW = 49; - OUTLINE_COLOR = 50; - FLEX_GROW = 51; - MAX_WIDTH = 52; - GRID_COLUMN = 53; - IMAGE_ORIENTATION = 54; - ANIMATION_DURATION = 55; - _WEBKIT_COLUMNS = 56; - _WEBKIT_ANIMATION_DELAY = 57; - _EPUB_TEXT_EMPHASIS = 58; - FLEX_SHRINK = 59; - TEXT_RENDERING = 60; - ALIGN_ITEMS = 61; - BORDER_COLLAPSE = 62; - OFFSET = 63; - TEXT_COMBINE_UPRIGHT = 64; - _WEBKIT_MASK_POSITION_X = 65; - _WEBKIT_MASK_POSITION_Y = 66; - OUTLINE_STYLE = 67; - COLOR_INTERPOLATION_FILTERS = 68; - FONT_VARIANT = 69; - _WEBKIT_ANIMATION_FILL_MODE = 70; - BORDER_RIGHT = 71; - VISIBILITY = 72; - TRANSFORM_BOX = 73; - FONT_VARIANT_CAPS = 74; - _EPUB_TEXT_EMPHASIS_COLOR = 75; - _WEBKIT_BORDER_BEFORE_STYLE = 76; - RESIZE = 77; - _WEBKIT_RTL_ORDERING = 78; - _WEBKIT_BOX_ORDINAL_GROUP = 79; - PAINT_ORDER = 80; - STROKE_LINECAP = 81; - ANIMATION_DIRECTION = 82; - _WEBKIT_FONT_FEATURE_SETTINGS = 83; - BORDER_TOP_LEFT_RADIUS = 84; - _WEBKIT_COLUMN_WIDTH = 85; - _WEBKIT_BOX_ALIGN = 86; - _WEBKIT_PADDING_AFTER = 87; - COLUMN_WIDTH = 88; - LIST_STYLE = 89; - _WEBKIT_MASK_REPEAT_Y = 90; - STROKE = 91; - TEXT_DECORATION_LINE = 92; - _WEBKIT_BACKGROUND_SIZE = 93; - _WEBKIT_MASK_REPEAT_X = 94; - PADDING_BOTTOM = 95; - FONT_STYLE = 96; - _WEBKIT_TRANSITION_DELAY = 97; - BACKGROUND_REPEAT = 98; - FLEX_BASIS = 99; - BORDER_IMAGE_SLICE = 100; - _WEBKIT_TRANSFORM_ORIGIN = 101; - SCROLL_BOUNDARY_BEHAVIOR_X = 102; - SCROLL_BOUNDARY_BEHAVIOR_Y = 103; - VECTOR_EFFECT = 104; - _WEBKIT_ANIMATION_TIMING_FUNCTION = 105; - _WEBKIT_BORDER_AFTER_STYLE = 106; - _WEBKIT_PERSPECTIVE_ORIGIN_X = 107; - _WEBKIT_PERSPECTIVE_ORIGIN_Y = 108; - INLINE_SIZE = 109; - OUTLINE = 110; - FONT_DISPLAY = 111; - _WEBKIT_BORDER_BEFORE = 112; - BORDER_IMAGE_SOURCE = 113; - TRANSITION_DURATION = 114; - SCROLL_PADDING_TOP = 115; - ORDER = 116; - _WEBKIT_BOX_ORIENT = 117; - COUNTER_RESET = 118; - COLOR_RENDERING = 119; - FLEX_DIRECTION = 120; - _WEBKIT_TEXT_STROKE_WIDTH = 121; - FONT_VARIANT_NUMERIC = 122; - SCROLL_MARGIN_BLOCK_END = 123; - MIN_HEIGHT = 124; - SCROLL_PADDING_INLINE_START = 125; - _WEBKIT_MASK_BOX_IMAGE = 126; - LEFT = 127; - _WEBKIT_MASK = 128; - _WEBKIT_BORDER_AFTER_WIDTH = 129; - STROKE_WIDTH = 130; - _WEBKIT_BOX_DECORATION_BREAK = 131; - _WEBKIT_MASK_POSITION = 132; - BACKGROUND_ORIGIN = 133; - _WEBKIT_BORDER_START_COLOR = 134; - FONT_STRETCH = 135; - _WEBKIT_BACKGROUND_CLIP = 136; - SCROLL_MARGIN_TOP = 137; - _WEBKIT_BORDER_HORIZONTAL_SPACING = 138; - BORDER_RADIUS = 139; - FLEX = 140; - TEXT_INDENT = 141; - HYPHENS = 142; - COLUMN_RULE_WIDTH = 143; - _WEBKIT_MARGIN_AFTER = 144; - _EPUB_CAPTION_SIDE = 145; - BREAK_AFTER = 146; - TEXT_TRANSFORM = 147; - TOUCH_ACTION = 148; - FONT_SIZE = 149; - _WEBKIT_ANIMATION_NAME = 150; - SCROLL_PADDING_INLINE = 151; - OFFSET_PATH = 152; - SCROLL_MARGIN = 153; - PADDING_TOP = 154; - SCROLL_SNAP_ALIGN = 155; - _WEBKIT_TEXT_COMBINE = 156; - _WEBKIT_FLEX_SHRINK = 157; - RX = 158; - RY = 159; - CONTENT = 160; - PADDING_RIGHT = 161; - _WEBKIT_TRANSFORM = 162; - MARKER_MID = 163; - _WEBKIT_MIN_LOGICAL_WIDTH = 164; - CLIP_RULE = 165; - FONT_FAMILY = 166; - SCROLL_SNAP_TYPE = 167; - TEXT_DECORATION_SKIP_INK = 168; - TRANSITION = 169; - FILTER = 170; - BORDER_RIGHT_WIDTH = 171; - _WEBKIT_FLEX_DIRECTION = 172; - _WEBKIT_MASK_COMPOSITE = 173; - MIX_BLEND_MODE = 174; - COLOR_INTERPOLATION = 175; - BORDER_TOP_STYLE = 176; - FILL_OPACITY = 177; - MARKER_START = 178; - BORDER_BOTTOM_WIDTH = 179; - _WEBKIT_TEXT_EMPHASIS = 180; - GRID_AREA = 181; - SIZE = 182; - BACKGROUND_CLIP = 183; - _WEBKIT_TEXT_FILL_COLOR = 184; - TOP = 185; - _WEBKIT_BOX_REFLECT = 186; - BORDER_WIDTH = 187; - OFFSET_ANCHOR = 188; - MAX_INLINE_SIZE = 189; - _WEBKIT_COLUMN_RULE_STYLE = 190; - _WEBKIT_COLUMN_COUNT = 191; - ANIMATION_PLAY_STATE = 192; - PADDING = 193; - DOMINANT_BASELINE = 194; - BACKGROUND_ATTACHMENT = 195; - _WEBKIT_BOX_SIZING = 196; - _WEBKIT_BOX_FLEX = 197; - TEXT_ORIENTATION = 198; - BACKGROUND_POSITION = 199; - _WEBKIT_BORDER_START_WIDTH = 200; - _EPUB_TEXT_EMPHASIS_STYLE = 201; - ISOLATION = 202; - _EPUB_TEXT_ORIENTATION = 203; - _WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS = 204; - R = 205; - BORDER_LEFT_WIDTH = 206; - GRID_COLUMN_END = 207; - BACKGROUND_BLEND_MODE = 208; - VERTICAL_ALIGN = 209; - CLIP = 210; - GRID_AUTO_ROWS = 211; - OFFSET_ROTATE = 212; - MARGIN_LEFT = 213; - ANIMATION_NAME = 214; - TEXT_DECORATION = 215; - BORDER = 216; - _WEBKIT_TRANSITION_TIMING_FUNCTION = 217; - MARGIN_BOTTOM = 218; - UNICODE_RANGE = 219; - ANIMATION = 220; - _WEBKIT_SHAPE_MARGIN = 221; - FONT_WEIGHT = 222; - SHAPE_MARGIN = 223; - MASK_TYPE = 224; - SCROLL_PADDING = 225; - MIN_INLINE_SIZE = 226; - OBJECT_POSITION = 227; - PAGE_BREAK_AFTER = 228; - _WEBKIT_MASK_CLIP = 229; - WHITE_SPACE = 230; - _WEBKIT_BORDER_AFTER_COLOR = 231; - _WEBKIT_MAX_LOGICAL_WIDTH = 232; - _WEBKIT_BORDER_BEFORE_COLOR = 233; - FONT_KERNING = 234; - _EPUB_WORD_BREAK = 235; - CLEAR = 236; - ANIMATION_TIMING_FUNCTION = 237; - _WEBKIT_BORDER_RADIUS = 238; - SCROLL_PADDING_RIGHT = 239; - _WEBKIT_TEXT_DECORATIONS_IN_EFFECT = 240; - _WEBKIT_ANIMATION_DIRECTION = 241; - JUSTIFY_SELF = 242; - TRANSITION_TIMING_FUNCTION = 243; - SCROLL_SNAP_STOP = 244; - COUNTER_INCREMENT = 245; - _WEBKIT_TRANSFORM_STYLE = 246; - GRID_AUTO_COLUMNS = 247; - _WEBKIT_ALIGN_CONTENT = 248; - FONT = 249; - FLEX_WRAP = 250; - GRID_ROW_START = 251; - LIST_STYLE_IMAGE = 252; - _WEBKIT_TAP_HIGHLIGHT_COLOR = 253; - _WEBKIT_TEXT_EMPHASIS_COLOR = 254; - BORDER_LEFT = 255; - _WEBKIT_BORDER_END_COLOR = 256; - COLUMNS = 257; - BOX_SHADOW = 258; - _WEBKIT_FLEX_WRAP = 259; - ALIGN_SELF = 260; - BORDER_BOTTOM = 261; - BORDER_SPACING = 262; - _WEBKIT_COLUMN_SPAN = 263; - GRID_ROW_END = 264; - _WEBKIT_BORDER_END = 265; - PERSPECTIVE_ORIGIN = 266; - PAGE_BREAK_INSIDE = 267; - ORPHANS = 268; - _WEBKIT_BORDER_START_STYLE = 269; - SCROLL_BEHAVIOR = 270; - COLUMN_SPAN = 271; - _WEBKIT_HYPHENATE_CHARACTER = 272; - COLUMN_FILL = 273; - TAB_SIZE = 274; - CONTAIN = 275; - X = 276; - GRID_ROW = 277; - BORDER_BOTTOM_RIGHT_RADIUS = 278; - LINE_HEIGHT = 279; - STROKE_LINEJOIN = 280; - TEXT_ALIGN_LAST = 281; - OFFSET_POSITION = 282; - WORD_SPACING = 283; - TRANSFORM_STYLE = 284; - _WEBKIT_APP_REGION = 285; - _WEBKIT_BORDER_END_STYLE = 286; - _WEBKIT_TRANSFORM_ORIGIN_Z = 287; - _WEBKIT_TRANSFORM_ORIGIN_X = 288; - _WEBKIT_TRANSFORM_ORIGIN_Y = 289; - BACKGROUND_REPEAT_X = 290; - BACKGROUND_REPEAT_Y = 291; - BORDER_BOTTOM_COLOR = 292; - _WEBKIT_RUBY_POSITION = 293; - _WEBKIT_LOGICAL_WIDTH = 294; - TEXT_JUSTIFY = 295; - SCROLL_MARGIN_INLINE_START = 296; - CAPTION_SIDE = 297; - MASK_SOURCE_TYPE = 298; - _WEBKIT_MASK_BOX_IMAGE_SLICE = 299; - _WEBKIT_BORDER_IMAGE = 300; - TEXT_SIZE_ADJUST = 301; - _WEBKIT_TEXT_SECURITY = 302; - _EPUB_WRITING_MODE = 303; - GRID_TEMPLATE = 304; - _WEBKIT_MASK_BOX_IMAGE_REPEAT = 305; - _WEBKIT_MASK_REPEAT = 306; - _WEBKIT_JUSTIFY_CONTENT = 307; - BASELINE_SHIFT = 308; - BORDER_IMAGE = 309; - TEXT_DECORATION_COLOR = 310; - COLOR = 311; - SHAPE_IMAGE_THRESHOLD = 312; - SHAPE_RENDERING = 313; - CY = 314; - CX = 315; - _WEBKIT_USER_MODIFY = 316; - OFFSET_DISTANCE = 317; - _WEBKIT_BORDER_BOTTOM_LEFT_RADIUS = 318; - SPEAK = 319; - BORDER_BOTTOM_LEFT_RADIUS = 320; - _WEBKIT_COLUMN_BREAK_AFTER = 321; - _WEBKIT_FONT_SMOOTHING = 322; - _WEBKIT_MAX_LOGICAL_HEIGHT = 323; - _WEBKIT_LINE_BREAK = 324; - FILL_RULE = 325; - _WEBKIT_MARGIN_START = 326; - MIN_WIDTH = 327; - _EPUB_TEXT_COMBINE = 328; - BREAK_BEFORE = 329; - CARET_COLOR = 330; - EMPTY_CELLS = 331; - DIRECTION = 332; - CLIP_PATH = 333; - JUSTIFY_CONTENT = 334; - SCROLL_PADDING_BLOCK_END = 335; - Z_INDEX = 336; - BACKGROUND_POSITION_Y = 337; - TEXT_DECORATION_STYLE = 338; - GRID_TEMPLATE_AREAS = 339; - _WEBKIT_MIN_LOGICAL_HEIGHT = 340; - FONT_SIZE_ADJUST = 341; - SCROLL_PADDING_BLOCK = 342; - OVERFLOW_ANCHOR = 343; - CURSOR = 344; - SCROLL_MARGIN_BLOCK_START = 345; - _WEBKIT_MASK_BOX_IMAGE_SOURCE = 346; - MARGIN = 347; - _WEBKIT_ANIMATION = 348; - LETTER_SPACING = 349; - ORIENTATION = 350; - WILL_CHANGE = 351; - _WEBKIT_HIGHLIGHT = 352; - TRANSFORM_ORIGIN = 353; - FONT_VARIANT_LIGATURES = 354; - _WEBKIT_ANIMATION_DURATION = 355; - _WEBKIT_MASK_ORIGIN = 356; - _WEBKIT_CLIP_PATH = 357; - WORD_BREAK = 358; - TABLE_LAYOUT = 359; - TEXT_OVERFLOW = 360; - _WEBKIT_LOCALE = 361; - _WEBKIT_FLEX = 362; - GRID_AUTO_FLOW = 363; - BORDER_TOP_RIGHT_RADIUS = 364; - BORDER_IMAGE_OUTSET = 365; - PLACE_ITEMS = 366; - BORDER_LEFT_COLOR = 367; - FONT_VARIATION_SETTINGS = 368; - BORDER_RIGHT_COLOR = 369; - MIN_ZOOM = 370; - SCROLL_MARGIN_INLINE = 371; - _WEBKIT_BORDER_BEFORE_WIDTH = 372; - BACKFACE_VISIBILITY = 373; - BACKGROUND_IMAGE = 374; - _WEBKIT_TRANSITION_PROPERTY = 375; - WRITING_MODE = 376; - STROKE_OPACITY = 377; - BOX_SIZING = 378; - MARGIN_TOP = 379; - COLUMN_RULE_COLOR = 380; - Y = 381; - POSITION = 382; - SCROLL_MARGIN_BOTTOM = 383; - LIST_STYLE_POSITION = 384; - _WEBKIT_BOX_PACK = 385; - SCROLL_PADDING_INLINE_END = 386; - QUOTES = 387; - BORDER_TOP = 388; - SCROLL_PADDING_LEFT = 389; - _WEBKIT_TRANSITION = 390; - _WEBKIT_COLUMN_BREAK_BEFORE = 391; - LIGHTING_COLOR = 392; - BACKGROUND_SIZE = 393; - _WEBKIT_PADDING_BEFORE = 394; - _WEBKIT_BORDER_TOP_LEFT_RADIUS = 395; - FLOOD_OPACITY = 396; - LINE_HEIGHT_STEP = 397; - _WEBKIT_MASK_SIZE = 398; - TEXT_ALIGN = 399; - _WEBKIT_FILTER = 400; - WORD_WRAP = 401; - MAX_ZOOM = 402; - GRID = 403; - BACKGROUND = 404; - HEIGHT = 405; - GRID_COLUMN_START = 406; - ANIMATION_FILL_MODE = 407; - ROTATE = 408; - MARKER_END = 409; - D = 410; - JUSTIFY_ITEMS = 411; - ZOOM = 412; - SCROLL_PADDING_BLOCK_START = 413; - PAGE = 414; - RIGHT = 415; - USER_SELECT = 416; - MARGIN_RIGHT = 417; - MARKER = 418; - LINE_BREAK = 419; - _WEBKIT_MARGIN_END = 420; - _WEBKIT_TRANSITION_DURATION = 421; - _WEBKIT_WRITING_MODE = 422; - BORDER_TOP_WIDTH = 423; - BOTTOM = 424; - PLACE_CONTENT = 425; - _WEBKIT_SHAPE_IMAGE_THRESHOLD = 426; - _WEBKIT_USER_DRAG = 427; - _WEBKIT_BORDER_VERTICAL_SPACING = 428; - _WEBKIT_COLUMN_GAP = 429; - _WEBKIT_OPACITY = 430; - BACKGROUND_COLOR = 431; - COLUMN_GAP = 432; - SHAPE_OUTSIDE = 433; - _WEBKIT_PADDING_END = 434; - _WEBKIT_BORDER_START = 435; - ANIMATION_DELAY = 436; - UNICODE_BIDI = 437; - TEXT_SHADOW = 438; - _WEBKIT_BOX_DIRECTION = 439; - IMAGE_RENDERING = 440; - SRC = 441; - GAP = 442; - GRID_GAP = 443; - POINTER_EVENTS = 444; - BORDER_IMAGE_WIDTH = 445; - MIN_BLOCK_SIZE = 446; - TRANSITION_PROPERTY = 447; - _WEBKIT_MASK_IMAGE = 448; - FLOAT = 449; - MAX_HEIGHT = 450; - OUTLINE_OFFSET = 451; - _WEBKIT_BOX_SHADOW = 452; - OVERFLOW_WRAP = 453; - BLOCK_SIZE = 454; - TRANSFORM = 455; - PLACE_SELF = 456; - WIDTH = 457; - STROKE_MITERLIMIT = 458; - STOP_OPACITY = 459; - BORDER_TOP_COLOR = 460; - TRANSLATE = 461; - OBJECT_FIT = 462; - _WEBKIT_MASK_BOX_IMAGE_WIDTH = 463; - _WEBKIT_BACKGROUND_ORIGIN = 464; - _WEBKIT_ALIGN_ITEMS = 465; - TRANSITION_DELAY = 466; - SCROLL_MARGIN_LEFT = 467; - BORDER_STYLE = 468; - ANIMATION_ITERATION_COUNT = 469; - // Should be named OVERFLOW but can't because a macro uses this. Needs two - // underscores for Windows. - __OVERFLOW = 470; - USER_ZOOM = 471; - _WEBKIT_BORDER_TOP_RIGHT_RADIUS = 472; - GRID_TEMPLATE_COLUMNS = 473; - _WEBKIT_ALIGN_SELF = 474; - _WEBKIT_PERSPECTIVE_ORIGIN = 475; - COLUMN_RULE_STYLE = 476; - DISPLAY = 477; - _WEBKIT_COLUMN_RULE_WIDTH = 478; - BORDER_COLOR = 479; - _WEBKIT_FLEX_BASIS = 480; - STROKE_DASHOFFSET = 481; - _WEBKIT_TEXT_SIZE_ADJUST = 482; - SCROLL_BOUNDARY_BEHAVIOR = 483; - _WEBKIT_TEXT_STROKE = 484; - WIDOWS = 485; - FILL = 486; - OVERFLOW_Y = 487; - OVERFLOW_X = 488; - OPACITY = 489; - _WEBKIT_PERSPECTIVE = 490; - _WEBKIT_TEXT_STROKE_COLOR = 491; - SCROLL_MARGIN_INLINE_END = 492; - SCALE = 493; - _WEBKIT_TEXT_ORIENTATION = 494; - _WEBKIT_MASK_BOX_IMAGE_OUTSET = 495; - ALIGN_CONTENT = 496; - _WEBKIT_BORDER_END_WIDTH = 497; - BORDER_BOTTOM_STYLE = 498; - MASK = 499; - BACKGROUND_POSITION_X = 500; - _EPUB_TEXT_TRANSFORM = 501; - STOP_COLOR = 502; - STROKE_DASHARRAY = 503; - _WEBKIT_LINE_CLAMP = 504; - MARGIN_BLOCK_START = 505; - MARGIN_BLOCK_END = 506; - MARGIN_INLINE_START = 507; - MARGIN_INLINE_END = 508; - PADDING_BLOCK_START = 509; - PADDING_BLOCK_END = 510; - PADDING_INLINE_START = 511; - PADDING_INLINE_END = 512; - BORDER_BLOCK_START_WIDTH = 513; - BORDER_BLOCK_START_STYLE = 514; - BORDER_BLOCK_START_COLOR = 515; - BORDER_BLOCK_END_WIDTH = 516; - BORDER_BLOCK_END_STYLE = 517; - BORDER_BLOCK_END_COLOR = 518; - BORDER_INLINE_START_WIDTH = 519; - BORDER_INLINE_START_STYLE = 520; - BORDER_INLINE_START_COLOR = 521; - BORDER_INLINE_END_WIDTH = 522; - BORDER_INLINE_END_STYLE = 523; - BORDER_INLINE_END_COLOR = 524; - BORDER_BLOCK_START = 525; - BORDER_BLOCK_END = 526; - BORDER_INLINE_START = 527; - BORDER_INLINE_END = 528; - MARGIN_BLOCK = 529; - MARGIN_INLINE = 530; - PADDING_BLOCK = 531; - PADDING_INLINE = 532; - BORDER_BLOCK_WIDTH = 533; - BORDER_BLOCK_STYLE = 534; - BORDER_BLOCK_COLOR = 535; - BORDER_INLINE_WIDTH = 536; - BORDER_INLINE_STYLE = 537; - BORDER_INLINE_COLOR = 538; - BORDER_BLOCK = 539; - BORDER_INLINE = 540; - INSET_BLOCK_START = 541; - INSET_BLOCK_END = 542; - INSET_BLOCK = 543; - INSET_INLINE_START = 544; - INSET_INLINE_END = 545; - INSET_INLINE = 546; - INSET = 547; - OVERFLOW_BLOCK = 548; - OVERFLOW_INLINE = 549; - FORCED_COLOR_ADJUST = 550; - OVERSCROLL_BEHAVIOR_INLINE = 551; - OVERSCROLL_BEHAVIOR_BLOCK = 552; - OVERSCROLL_BEHAVIOR_X = 553; - OVERSCROLL_BEHAVIOR_Y = 554; - ANIMATION_TIMELINE = 555; - COUNTER_SET = 556; - BORDER_START_START_RADIUS = 557; - BORDER_START_END_RADIUS = 558; - BORDER_END_START_RADIUS = 559; - BORDER_END_END_RADIUS = 560; - INVALID_PROPERTY = 561; - } - required NameId name_id = 1; -} - -message Ruleset { - required SelectorList selector_list = 1; - required DeclarationList declaration_list = 2; -} - -// Not in grammar. -message SelectorList { - required Selector first_selector = 1; - repeated Selector later_selectors = 2; -} - -message Attr { - enum Type { - NONE = 1; - EQUAL = 6; - TILDE = 126; - PIPE = 124; - DOLLAR = 36; - STAR = 42; - } - required Type type = 1; - optional bool attr_i = 2; - // TODO(metzman): Allow values to be set instead of hardcoding. -} - -enum PseudoType { - CLASS = 1; - ELEMENT = 2; -} - -enum Combinator { - NONE = 1; - DOLLAR = 36; - COMMA = 44; - GREATER_THAN = 62; - PLUS = 43; - TILDE = 126; -} - -message Selector { - enum Type { - ELEMENT = 1; - CLASS = 2; - ID = 3; - // TODO(metzman): Support the different variations of universal selectors. - UNIVERSAL = 4; - ATTR = 5; - } - required Type type = 1; - required Attr attr = 2; - // TODO(metzman): Allow the selector value to be set by fuzzer. - required PseudoType pseudo_type = 3; - enum PseudoValueId { - _INTERNAL_AUTOFILL_PREVIEWED = 1; - _INTERNAL_AUTOFILL_SELECTED = 2; - _INTERNAL_IS_HTML = 3; - _INTERNAL_LIST_BOX = 4; - _INTERNAL_MEDIA_CONTROLS_OVERLAY_CAST_BUTTON = 5; - _INTERNAL_MULTI_SELECT_FOCUS = 6; - _INTERNAL_POPUP_OPEN = 7; - _INTERNAL_SHADOW_HOST_HAS_APPEARANCE = 8; - _INTERNAL_SPATIAL_NAVIGATION_FOCUS = 9; - _INTERNAL_VIDEO_PERSISTENT = 10; - _INTERNAL_VIDEO_PERSISTENT_ANCESTOR = 11; - _WEBKIT_ANY_LINK = 12; - _WEBKIT_AUTOFILL = 13; - _WEBKIT_DRAG = 14; - _WEBKIT_FULL_PAGE_MEDIA = 15; - _WEBKIT_FULL_SCREEN = 16; - _WEBKIT_FULL_SCREEN_ANCESTOR = 17; - _WEBKIT_RESIZER = 18; - _WEBKIT_SCROLLBAR = 19; - _WEBKIT_SCROLLBAR_BUTTON = 20; - _WEBKIT_SCROLLBAR_CORNER = 21; - _WEBKIT_SCROLLBAR_THUMB = 22; - _WEBKIT_SCROLLBAR_TRACK = 23; - _WEBKIT_SCROLLBAR_TRACK_PIECE = 24; - ACTIVE = 25; - AFTER = 26; - AUTOFILL = 27; - BACKDROP = 28; - BEFORE = 29; - CHECKED = 30; - CORNER_PRESENT = 31; - CUE = 32; - DECREMENT = 33; - DEFAULT = 34; - DEFINED = 35; - DISABLED = 36; - DOUBLE_BUTTON = 37; - EMPTY = 38; - ENABLED = 39; - END = 40; - FIRST = 41; - FIRST_CHILD = 42; - FIRST_LETTER = 43; - FIRST_LINE = 44; - FIRST_OF_TYPE = 45; - FOCUS = 46; - FOCUS_WITHIN = 47; - FULLSCREEN = 48; - FUTURE = 49; - HORIZONTAL = 50; - HOST = 51; - HOVER = 52; - IN_RANGE = 53; - INCREMENT = 54; - INDETERMINATE = 55; - INVALID = 56; - LAST_CHILD = 57; - LAST_OF_TYPE = 58; - LEFT = 59; - LINK = 60; - NO_BUTTON = 61; - ONLY_CHILD = 62; - ONLY_OF_TYPE = 63; - OPTIONAL = 64; - OUT_OF_RANGE = 65; - PAST = 66; - PLACEHOLDER = 67; - PLACEHOLDER_SHOWN = 68; - READ_ONLY = 69; - READ_WRITE = 70; - REQUIRED = 71; - RIGHT = 72; - ROOT = 73; - SCOPE = 74; - SELECTION = 75; - SINGLE_BUTTON = 76; - START = 77; - TARGET = 78; - VALID = 79; - VERTICAL = 80; - VISITED = 81; - WINDOW_INACTIVE = 82; - _WEBKIT_ANY = 83; - HOST_CONTEXT = 84; - LANG = 85; - NOT = 86; - NTH_CHILD = 87; - NTH_LAST_CHILD = 88; - NTH_LAST_OF_TYPE = 89; - NTH_OF_TYPE = 90; - SLOTTED = 91; - XR_OVERLAY = 92; - INVALID_PSEUDO_VALUE = 93; - } - optional PseudoValueId pseudo_value_id = 4; - required Combinator combinator = 5; -} - -message Pseudo { - oneof rhs { - Ident ident_1 = 1; - FunctionToken function_token = 2; - } - required Ident ident_2 = 3; -} - -message Declaration { - // property ':' S* expr prio? | /* empty */ - optional PropertyAndValue property_and_value = 1; -} - -message PropertyAndValue { - required Property property = 1; - required Expr expr = 2; - enum Prio { - UNSET = 0; - IS_SET = 1; - } - optional Prio prio = 3; - enum ValueId { - ALL = 1; - DYNAMIC = 2; - YELLOW = 3; - GRAYTEXT = 4; - COLOR_DODGE = 5; - DARKSEAGREEN = 6; - DISC = 7; - EXTRA_CONDENSED = 8; - HANGING = 9; - STEP_MIDDLE = 10; - MENULIST = 11; - ROW = 12; - PRE_WRAP = 13; - INLINE_BLOCK = 14; - STEP_START = 15; - ISOLATE_OVERRIDE = 16; - SWAP = 17; - RTL = 18; - CRIMSON = 19; - TB = 20; - COMMON_LIGATURES = 21; - _WEBKIT_MIN_CONTENT = 22; - BROWN = 23; - KHMER = 24; - INFINITE = 25; - TABLE_HEADER_GROUP = 26; - BEFORE_EDGE = 27; - READ_WRITE = 28; - RL = 29; - WAVY = 30; - PROPORTIONAL_WIDTH = 31; - NO_DROP = 32; - CYAN = 33; - DIFFERENCE = 34; - EXACT = 35; - SQUARE_BUTTON = 36; - SKYBLUE = 37; - _WEBKIT_ISOLATE_OVERRIDE = 38; - TABLE_ROW_GROUP = 39; - DARKGRAY = 40; - BUTTON = 41; - ETHIOPIC_HALEHAME_AM = 42; - LARGE = 43; - LIGHTPINK = 44; - CROSSHAIR = 45; - TEAL = 46; - FILL_BOX = 47; - SMALL = 48; - MEDIA_SLIDERTHUMB = 49; - ROUND = 50; - _INTERNAL_MEDIA_SUBTITLES_ICON = 51; - MEDIA_PLAY_BUTTON = 52; - SMALLER = 53; - JIS04 = 54; - LR_TB = 55; - LIGHTGOLDENRODYELLOW = 56; - LAVENDER = 57; - ULTRA_EXPANDED = 58; - DIMGREY = 59; - DIAGONAL_FRACTIONS = 60; - BLUE = 61; - XOR = 62; - SUB = 63; - TELUGU = 64; - CRISPEDGES = 65; - _WEBKIT_MINI_CONTROL = 66; - ZOOM_OUT = 67; - SEARCHFIELD = 68; - CELL = 69; - GUJARATI = 70; - ABOVE = 71; - NO_PUNCTUATION = 72; - NEW = 73; - FILLED = 74; - USE_SCRIPT = 75; - CONDENSED = 76; - LOOSE = 77; - SOURCE_OUT = 78; - OBJECTS = 79; - SLIDER_HORIZONTAL = 80; - ROW_RESIZE = 81; - BREAK_ALL = 82; - WAIT = 83; - MEDIA_EXIT_FULLSCREEN_BUTTON = 84; - KOREAN_HANGUL_FORMAL = 85; - FLORALWHITE = 86; - RESET_SIZE = 87; - ZOOM_IN = 88; - _WEBKIT_GRABBING = 89; - LARGER = 90; - MAX_CONTENT = 91; - SRGB = 92; - LITERAL_PUNCTUATION = 93; - WINDOWFRAME = 94; - SUBPIXEL_ANTIALIASED = 95; - BUTTONHIGHLIGHT = 96; - HUE = 97; - PIXELATED = 98; - STICKY = 99; - GREENYELLOW = 100; - LINEARRGB = 101; - LIGHTSEAGREEN = 102; - LOGICAL = 103; - _WEBKIT_RIGHT = 104; - SIENNA = 105; - FLOW_ROOT = 106; - OPTIMIZESPEED = 107; - KOREAN_HANJA_FORMAL = 108; - NOWRAP = 109; - X_SMALL = 110; - LANDSCAPE = 111; - LIME = 112; - X_LARGE = 113; - NS_RESIZE = 114; - APPWORKSPACE = 115; - PERU = 116; - ALL_PETITE_CAPS = 117; - BLACK = 118; - XX_SMALL = 119; - ALL_SCROLL = 120; - DARKSLATEGRAY = 121; - FLAT = 122; - GEORGIAN = 123; - UNDER = 124; - LEMONCHIFFON = 125; - CHOCOLATE = 126; - PRE_LINE = 127; - CONTEXT_MENU = 128; - DARKGREY = 129; - VIEW_BOX = 130; - OLIVE = 131; - _WEBKIT_PLAINTEXT = 132; - EXTRA_EXPANDED = 133; - ANTIQUEWHITE = 134; - NONE = 135; - MOCCASIN = 136; - LOCAL = 137; - STROKE = 138; - DARKSLATEBLUE = 139; - LIGHTSKYBLUE = 140; - CONTENT_BOX = 141; - THIN = 142; - DEEPPINK = 143; - SPELL_OUT = 144; - NON_SCALING_STROKE = 145; - SLIDER_VERTICAL = 146; - _WEBKIT_BOX = 147; - PLUM = 148; - _INTERNAL_MEDIA_OVERLAY_CAST_OFF_BUTTON = 149; - INACTIVECAPTIONTEXT = 150; - DODGERBLUE = 151; - THREEDSHADOW = 152; - PETITE_CAPS = 153; - PAUSED = 154; - _WEBKIT_LINK = 155; - MESSAGE_BOX = 156; - _INTERNAL_CENTER = 157; - TRIANGLE = 158; - MAGENTA = 159; - TAN = 160; - ABSOLUTE = 161; - PINK = 162; - HIRAGANA_IROHA = 163; - FARTHEST_SIDE = 164; - PALEVIOLETRED = 165; - CLOSE_QUOTE = 166; - THREEDLIGHTSHADOW = 167; - CAPTION = 168; - POWDERBLUE = 169; - TABLE_COLUMN = 170; - SOURCE_ATOP = 171; - HIRAGANA = 172; - UPPER_ARMENIAN = 173; - WINDOWTEXT = 174; - FULL_WIDTH = 175; - PROGRESS_BAR_VALUE = 176; - MIDNIGHTBLUE = 177; - INLINE_FLEX = 178; - ECONOMY = 179; - LAO = 180; - CLONE = 181; - AFTER = 182; - STATUS_BAR = 183; - LOWERCASE = 184; - MIXED = 185; - LINE_THROUGH = 186; - LIGHTSLATEGRAY = 187; - SMALL_CAPTION = 188; - INFOBACKGROUND = 189; - DISCARD = 190; - CAPTIONTEXT = 191; - END = 192; - _INTERNAL_INACTIVE_LIST_BOX_SELECTION_TEXT = 193; - CAPITALIZE = 194; - MEDIUMSEAGREEN = 195; - TOMATO = 196; - CADETBLUE = 197; - DECIMAL_LEADING_ZERO = 198; - SANS_SERIF = 199; - LINEN = 200; - GREEN = 201; - INACTIVEBORDER = 202; - INLINE = 203; - FALLBACK = 204; - PEACHPUFF = 205; - _WEBKIT_MAX_CONTENT = 206; - PLUS_LIGHTER = 207; - CHECKBOX = 208; - HELP = 209; - OBLIQUE = 210; - MOVE = 211; - METER = 212; - LEDGER = 213; - SLATEGREY = 214; - MEDIA_TIME_REMAINING_DISPLAY = 215; - URDU = 216; - POINTER = 217; - BEFORE = 218; - DARKSLATEGREY = 219; - _WEBKIT_CONTROL = 220; - _WEBKIT_INLINE_BOX = 221; - HARD_LIGHT = 222; - MITER = 223; - ORIYA = 224; - UPPER_LATIN = 225; - WINDOW = 226; - MEDIUMBLUE = 227; - LR = 228; - ORANGE = 229; - HIDDEN = 230; - _INTERNAL_ACTIVE_LIST_BOX_SELECTION = 231; - BOLDER = 232; - _WEBKIT_CENTER = 233; - SAFE = 234; - HIGHLIGHTTEXT = 235; - ACCUMULATE = 236; - FLEX_END = 237; - TRANSPARENT = 238; - _INTERNAL_MEDIA_REMOTING_CAST_ICON = 239; - GOLDENROD = 240; - HISTORICAL_LIGATURES = 241; - DARKVIOLET = 242; - ALWAYS = 243; - DECIMAL = 244; - BLOCK_AXIS = 245; - SCROLLBAR = 246; - EW_RESIZE = 247; - DARKMAGENTA = 248; - NOT_ALLOWED = 249; - EASE_IN = 250; - TABLE_COLUMN_GROUP = 251; - SQUARE = 252; - NO_CONTEXTUAL = 253; - _WEBKIT_FILL_AVAILABLE = 254; - FRAMES = 255; - PERSIAN = 256; - STATIC = 257; - NAVY = 258; - VISIBLEPAINTED = 259; - THICK = 260; - SIMP_CHINESE_FORMAL = 261; - GHOSTWHITE = 262; - SPACE = 263; - DARKKHAKI = 264; - KEEP_ALL = 265; - CONTENT = 266; - _INTERNAL_MEDIA_DOWNLOAD_BUTTON = 267; - UPPER_ROMAN = 268; - CORNSILK = 269; - RED = 270; - NO_CHANGE = 271; - LINEAR = 272; - _INTERNAL_MEDIA_CONTROL = 273; - SIDEWAYS = 274; - CONTAIN = 275; - KATAKANA_IROHA = 276; - STEELBLUE = 277; - DOUBLE_CIRCLE = 278; - ANTIALIASED = 279; - ALICEBLUE = 280; - LIGHTSLATEGREY = 281; - GEOMETRICPRECISION = 282; - GAINSBORO = 283; - INLINE_TABLE = 284; - LTR = 285; - BACKWARDS = 286; - S_RESIZE = 287; - LIGHTGREY = 288; - MEDIA_MUTE_BUTTON = 289; - LISTITEM = 290; - MISTYROSE = 291; - DARKSALMON = 292; - SIDEWAYS_RIGHT = 293; - JIS83 = 294; - MEDIUMSPRINGGREEN = 295; - CAPS_LOCK_INDICATOR = 296; - SLIDERTHUMB_HORIZONTAL = 297; - FORWARDS = 298; - UPPER_ALPHA = 299; - BLINK = 300; - FANTASY = 301; - SIMPLIFIED = 302; - ORANGERED = 303; - NAVAJOWHITE = 304; - OPEN = 305; - HORIZONTAL = 306; - SLATEGRAY = 307; - ACTIVECAPTION = 308; - KOREAN_HANJA_INFORMAL = 309; - STRICT = 310; - LIGHTCYAN = 311; - TOP = 312; - WHITE = 314; - TEXT_AFTER_EDGE = 315; - LIGHTGRAY = 316; - COLLAPSE = 317; - HOVER = 318; - _WEBKIT_OPTIMIZE_CONTRAST = 319; - PADDING = 320; - BUTT = 321; - OFF = 322; - THAI = 323; - COPY = 324; - HOTPINK = 325; - DOUBLE = 326; - LOWER_GREEK = 327; - GREY = 328; - MEDIA_VOLUME_SLIDER_CONTAINER = 329; - _WEBKIT_INLINE_FLEX = 330; - SPACE_EVENLY = 331; - ACTIVEBORDER = 332; - BROWSER = 333; - PRE = 334; - UNICASE = 335; - SIMP_CHINESE_INFORMAL = 336; - CLIP = 337; - CLOSEST_CORNER = 338; - PLAINTEXT = 339; - NO_REPEAT = 340; - TEXT_TOP = 341; - JIS78 = 342; - XX_LARGE = 343; - RL_TB = 344; - TABLE_ROW = 345; - MEDIUM = 346; - MONGOLIAN = 347; - KATAKANA = 348; - ELEMENT = 349; - BORDER = 350; - ROSYBROWN = 351; - PROGRESS_BAR = 352; - WHITESMOKE = 353; - LIGHTBLUE = 354; - _WEBKIT_LEFT = 355; - NO_COMMON_LIGATURES = 356; - LISTBOX = 357; - ISOLATE = 358; - SNOW = 359; - STEP_END = 360; - ETHIOPIC_HALEHAME_TI_ER = 361; - ETHIOPIC_HALEHAME_TI_ET = 362; - MULTIPLE = 363; - _INTERNAL_INACTIVE_LIST_BOX_SELECTION = 364; - NORMAL = 365; - BLUEVIOLET = 366; - SALMON = 367; - LOWER_ALPHA = 368; - OLDLACE = 369; - LETTER = 370; - BORDER_BOX = 371; - ALPHA = 372; - TIBETAN = 373; - ICON = 374; - FLEX_START = 375; - TEXTAREA = 376; - W_RESIZE = 377; - CLEAR = 378; - COVER = 379; - FARTHEST_CORNER = 380; - MENULIST_TEXTFIELD = 381; - TRADITIONAL = 382; - LEFT = 383; - DOT = 384; - LUMINANCE = 385; - GOLD = 386; - SHOW = 387; - TEXT = 388; - _WEBKIT_MATCH_PARENT = 389; - RADIO = 390; - CAMBODIAN = 391; - REPEAT_X = 392; - REPEAT_Y = 393; - FINE = 394; - TEXTFIELD = 395; - FROM_IMAGE = 396; - LINING_NUMS = 397; - MENU = 398; - PROPORTIONAL_NUMS = 399; - SOURCE_OVER = 400; - NE_RESIZE = 401; - PAPAYAWHIP = 402; - SOURCE_IN = 403; - SE_RESIZE = 404; - CIRCLE = 405; - DESTINATION_OUT = 406; - THREEDFACE = 407; - OVER = 408; - DISTRIBUTE = 409; - INACTIVECAPTION = 410; - LIGHTEN = 411; - _WEBKIT_FIT_CONTENT = 412; - LIGHTER = 413; - CONTEXTUAL = 414; - GRAY = 415; - DARKTURQUOISE = 416; - E_RESIZE = 417; - LUMINOSITY = 418; - LIST_ITEM = 419; - LIMEGREEN = 420; - FIXED = 421; - MIN_CONTENT = 422; - MEDIA_SLIDER = 423; - VISIBLESTROKE = 424; - CUBIC_BEZIER = 425; - CLOSEST_SIDE = 426; - RELATIVE = 427; - NO_OPEN_QUOTE = 428; - THISTLE = 429; - VIOLET = 430; - PORTRAIT = 431; - FULLSCREEN = 432; - HONEYDEW = 433; - ON_DEMAND = 434; - CORNFLOWERBLUE = 435; - DARKBLUE = 436; - OUTSIDE = 437; - PROGRESS = 438; - MEDIUMPURPLE = 439; - DARKCYAN = 440; - VERTICAL = 441; - MONOSPACE = 442; - BREAK_WORD = 443; - SCREEN = 444; - REBECCAPURPLE = 445; - DARKRED = 446; - VERTICAL_LR = 447; - OPTIMIZEQUALITY = 448; - ARMENIAN = 449; - NWSE_RESIZE = 450; - TEXT_BEFORE_EDGE = 451; - OPTIONAL = 452; - EXCLUSION = 453; - BOTH = 454; - MEDIUMTURQUOISE = 455; - LOWER_ROMAN = 456; - REVERSE = 457; - HANGUL_CONSONANT = 458; - SOFT_LIGHT = 459; - AQUA = 460; - BUTTON_BEVEL = 461; - GURMUKHI = 462; - LIGHTSTEELBLUE = 463; - SMALL_CAPS = 464; - N_RESIZE = 465; - TABLE_FOOTER_GROUP = 466; - DESTINATION_IN = 467; - OLIVEDRAB = 468; - READ_WRITE_PLAINTEXT_ONLY = 469; - PADDING_BOX = 470; - COL_RESIZE = 471; - _INTERNAL_MEDIA_TRACK_SELECTION_CHECKMARK = 472; - LOWER_LATIN = 473; - _WEBKIT_NOWRAP = 474; - TABLE = 475; - BUTTONSHADOW = 476; - PALEGREEN = 477; - JIS90 = 478; - FIT_CONTENT = 479; - STRETCH = 480; - SEASHELL = 481; - THREEDHIGHLIGHT = 482; - VISIBLEFILL = 483; - SPACE_AROUND = 484; - COARSE = 485; - AQUAMARINE = 486; - DIGITS = 487; - CURRENTCOLOR = 488; - PAINTED = 489; - TB_RL = 490; - BUTTONFACE = 491; - LAWNGREEN = 492; - BURLYWOOD = 493; - _WEBKIT_SMALL_CONTROL = 494; - SLATEBLUE = 495; - MINTCREAM = 496; - RUBY = 497; - SOLID = 498; - ULTRA_CONDENSED = 499; - EXPANDED = 500; - SADDLEBROWN = 501; - VERTICAL_RL = 502; - SESAME = 503; - _WEBKIT_BODY = 504; - DESTINATION_ATOP = 505; - MALAYALAM = 506; - WRAP_REVERSE = 507; - BALANCE = 508; - VERTICAL_RIGHT = 509; - NO_CLOSE_QUOTE = 510; - FLEX = 511; - PUSH_BUTTON = 512; - DARKGOLDENROD = 513; - SATURATION = 514; - MIDDLE = 515; - SANDYBROWN = 516; - HEBREW = 517; - MENUTEXT = 518; - INLINE_AXIS = 519; - BASELINE = 520; - _WEBKIT_GRAB = 521; - DARKORANGE = 522; - _WEBKIT_FLEX = 523; - NW_RESIZE = 524; - CONTENTS = 525; - AUTO = 526; - MARGIN_BOX = 527; - DOCUMENT = 528; - PALEGOLDENROD = 529; - ORDINAL = 530; - HAND = 531; - RUNNING = 532; - CJK_EARTHLY_BRANCH = 533; - TABLE_CAPTION = 534; - MEDIA_TOGGLE_CLOSED_CAPTIONS_BUTTON = 535; - AFTER_EDGE = 536; - SLIDERTHUMB_VERTICAL = 537; - CENTER = 538; - LIGHTYELLOW = 539; - LAVENDERBLUSH = 540; - _INTERNAL_MEDIA_CLOSED_CAPTIONS_ICON = 541; - INHERIT = 542; - MEDIA_CONTROLS_BACKGROUND = 543; - JUSTIFY = 544; - OPTIMIZELEGIBILITY = 545; - _WEBKIT_BASELINE_MIDDLE = 546; - INDIGO = 547; - MINIMAL_UI = 548; - FIREBRICK = 549; - INDIANRED = 550; - DARKOLIVEGREEN = 551; - SEMI_EXPANDED = 552; - UNDERLINE = 553; - MYANMAR = 554; - SPACE_BETWEEN = 555; - EASE = 556; - ALTERNATE = 557; - MEDIUMORCHID = 558; - SILVER = 559; - COLOR = 560; - CHARTREUSE = 561; - EASE_IN_OUT = 562; - SPRINGGREEN = 563; - LIGHTSALMON = 564; - TURQUOISE = 565; - HIDE = 566; - HORIZONTAL_TB = 567; - VERTICAL_TEXT = 568; - ALIAS = 569; - GRID = 570; - NO_DISCRETIONARY_LIGATURES = 571; - BACKGROUND = 572; - DEVANAGARI = 573; - TEXT_BOTTOM = 574; - DARKGREEN = 575; - VISIBLE = 576; - TABULAR_NUMS = 577; - MANUAL = 578; - ZOOM = 579; - CJK_HEAVENLY_STEM = 580; - STEPS = 581; - BOUNDING_BOX = 582; - ALPHABETIC = 583; - AFTER_WHITE_SPACE = 584; - ROW_REVERSE = 585; - MEDIA_CURRENT_TIME_DISPLAY = 586; - MATHEMATICAL = 587; - ETHIOPIC_HALEHAME = 588; - RIGHT = 589; - UPPERCASE = 590; - _WEBKIT_XXX_LARGE = 591; - B4 = 592; - B5 = 593; - YELLOWGREEN = 594; - MEDIA_CONTROLS_FULLSCREEN_BACKGROUND = 595; - LOWER_ARMENIAN = 596; - ORCHID = 597; - NONZERO = 598; - SLICE = 599; - DENSE = 600; - INTER_WORD = 601; - BOTTOM = 602; - PURPLE = 603; - AVOID = 604; - SEPARATE = 605; - HANGUL = 606; - LEGAL = 607; - ALTERNATE_REVERSE = 608; - PRESERVE_3D = 609; - READ_ONLY = 610; - ELLIPSIS = 611; - MEDIA_OVERLAY_PLAY_BUTTON = 612; - BISQUE = 613; - INFOTEXT = 614; - KHAKI = 615; - WHEAT = 616; - BOLD = 617; - NO_HISTORICAL_LIGATURES = 618; - BIDI_OVERRIDE = 619; - DEEPSKYBLUE = 620; - EASE_OUT = 621; - CJK_IDEOGRAPHIC = 622; - OLDSTYLE_NUMS = 623; - MEDIA_ENTER_FULLSCREEN_BUTTON = 624; - SUPER = 625; - CURSIVE = 626; - ON = 627; - CENTRAL = 628; - _INTERNAL_MEDIA_OVERFLOW_BUTTON = 629; - STANDALONE = 630; - COLUMN = 631; - CORAL = 632; - DESTINATION_OVER = 633; - DISCRETIONARY_LIGATURES = 634; - BEIGE = 635; - TABLE_CELL = 636; - AZURE = 637; - TRAD_CHINESE_INFORMAL = 638; - TITLING_CAPS = 639; - _WEBKIT_ZOOM_IN = 640; - BLOCK = 641; - OUTSET = 642; - MEDIUMVIOLETRED = 643; - ROYALBLUE = 644; - MENULIST_TEXT = 645; - SW_RESIZE = 646; - MULTIPLY = 647; - THREEDDARKSHADOW = 648; - WRAP = 649; - LIGHTCORAL = 650; - ELLIPSE = 651; - _INTERNAL_ACTIVE_LIST_BOX_SELECTION_TEXT = 652; - RIDGE = 653; - _WEBKIT_AUTO = 654; - _INTERNAL_QUIRK_INHERIT = 655; - INITIAL = 656; - FUCHSIA = 657; - MENULIST_BUTTON = 658; - BLANCHEDALMOND = 659; - CARET = 660; - START = 661; - _INTERNAL_MEDIA_CAST_OFF_BUTTON = 662; - ITALIC = 663; - IVORY = 664; - BUTTONTEXT = 665; - SEMI_CONDENSED = 666; - INLINE_GRID = 667; - _WEBKIT_ACTIVELINK = 668; - SERIF = 669; - FORESTGREEN = 670; - BENGALI = 671; - UPRIGHT = 672; - RESET = 673; - BEVEL = 674; - IDEOGRAPHIC = 675; - DARKEN = 676; - MEDIA_VOLUME_SLIDERTHUMB = 677; - DEFAULT = 678; - INSIDE = 679; - BELOW = 680; - HIGHLIGHT = 681; - EMBED = 682; - GROOVE = 683; - NESW_RESIZE = 684; - STACKED_FRACTIONS = 685; - UNSAFE = 686; - MAROON = 687; - KANNADA = 688; - SINGLE = 689; - AT = 690; - INK = 691; - ARABIC_INDIC = 692; - MEDIA_VOLUME_SLIDER = 693; - COLUMN_REVERSE = 694; - _WEBKIT_ZOOM_OUT = 695; - FILL = 696; - EVENODD = 697; - DOTTED = 698; - DIMGRAY = 699; - DASHED = 700; - SEAGREEN = 701; - TRAD_CHINESE_FORMAL = 702; - MEDIUMSLATEBLUE = 703; - PALETURQUOISE = 704; - INNER_SPIN_BUTTON = 705; - REPEAT = 706; - DARKORCHID = 707; - _WEBKIT_ISOLATE = 708; - SEARCHFIELD_CANCEL_BUTTON = 709; - ALL_SMALL_CAPS = 710; - A3 = 711; - A5 = 712; - A4 = 713; - OPEN_QUOTE = 714; - LIGHTGREEN = 715; - SLASHED_ZERO = 716; - COLOR_BURN = 717; - AUTO_FLOW = 718; - OVERLAY = 719; - VISUAL = 720; - SCALE_DOWN = 721; - OVERLINE = 722; - INSET = 723; - MEDIUMAQUAMARINE = 724; - SCROLL = 725; - LAYOUT = 726; - BREAK_SPACES = 727; - PAN_LEFT = 728; - PROXIMITY = 729; - INLINE_START = 730; - PAN_X = 731; - GRAB = 732; - GRABBING = 733; - INLINE_END = 734; - PAN_RIGHT = 735; - JUMP_END = 736; - MANIPULATION = 737; - PINCH_ZOOM = 738; - XXX_LARGE = 739; - PAN_DOWN = 740; - ANYWHERE = 741; - JUMP_NONE = 742; - DRAG = 743; - AVOID_PAGE = 744; - MANDATORY = 745; - PAINT = 746; - JUMP_BOTH = 747; - SIZE = 748; - STYLE = 749; - PAN_Y = 750; - RECTO = 751; - MARKERS = 752; - VERSO = 753; - PAGE = 754; - PAN_UP = 755; - AVOID_COLUMN = 756; - SMOOTH = 757; - JUMP_START = 758; - NO_DRAG = 759; - JIS_B5 = 760; - JIS_B4 = 761; - STANDARD = 762; - HIGH = 763; - SPELLING_ERROR = 764; - GRAMMAR_ERROR = 765; - INVALID_VALUE = 766; - }; - - optional ValueId value_id = 4; -} - -message Expr { - required Term term = 1; - repeated OperatorTerm operator_terms = 2; -} - -// Not in grammar. -message OperatorTerm { - required Operator _operator = 1; - required Term term = 2; -} - -message Term { - optional UnaryOperator unary_operator = 1; - oneof rhs { - // [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | - // TIME S* | FREQ S* | function ] - TermPart term_part = 2; - // | STRING - String string = 3; - } - // S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor - optional Ident ident = 4; - optional Uri uri = 5; - // TODO(metzman): Add UNICODERANGE token once (if) I implement it. - optional Hexcolor hexcolor = 6; -} - -// Not in grammar. -message TermPart { - // NUMBER - required Num number = 1; - // S* | PERCENTAGE - optional Num percentage = 2; // num "%" - // S* | LENGTH - optional Length length = 3; - optional Num ems = 4; // {num}em - optional Num exs = 5; // {num}ex - optional Angle angle = 6; - optional Time time = 7; - optional Freq freq = 8; - optional Function function = 9; -} - -message Function { - required FunctionToken function_token = 1; - required Expr expr = 2; -} - -message Hexcolor { - required HexcolorThree first_three = 1; - optional HexcolorThree last_three = 2; -} - -// Not in grammar. -message HexcolorThree { - // 0-9A-Za-z - required H ascii_value_1 = 1; - required H ascii_value_2 = 2; - required H ascii_value_3 = 3; -} - -message Input { - enum CSSParserMode { - kHTMLStandardMode = 0; - kHTMLQuirksMode = 1; - kSVGAttributeMode = 2; - kCSSViewportRuleMode = 3; - kCSSFontFaceRuleMode = 4; - kUASheetMode = 5; - } - enum SecureContextMode { - kInsecureContext = 0; - kSecureContext = 1; - } - required CSSParserMode css_parser_mode = 1; - required bool defer_property_parsing = 2; - required StyleSheet style_sheet = 3; - required bool is_live_profile = 4; - required SecureContextMode secure_context_mode = 5; -}
diff --git a/third_party/blink/renderer/core/css/parser/css_proto_converter.cc b/third_party/blink/renderer/core/css/parser/css_proto_converter.cc index 6c4ca462..556b3fb1 100644 --- a/third_party/blink/renderer/core/css/parser/css_proto_converter.cc +++ b/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
@@ -205,1340 +205,7 @@ "UTF-8", "UTF-16", "UTF-32", }; -const std::string Converter::kValueLookupTable[] = { - "", // This is just to fill the zeroth spot. It should not be used. - "all", - "dynamic", - "yellow", - "graytext", - "color-dodge", - "darkseagreen", - "disc", - "extra-condensed", - "hanging", - "step-middle", - "menulist", - "row", - "pre-wrap", - "inline-block", - "step-start", - "isolate-override", - "swap", - "rtl", - "crimson", - "tb", - "common-ligatures", - "-webkit-min-content", - "brown", - "khmer", - "infinite", - "table-header-group", - "before-edge", - "read-write", - "rl", - "wavy", - "proportional-width", - "no-drop", - "cyan", - "difference", - "exact", - "square-button", - "skyblue", - "-webkit-isolate-override", - "table-row-group", - "darkgray", - "button", - "ethiopic-halehame-am", - "large", - "lightpink", - "crosshair", - "teal", - "fill-box", - "small", - "media-sliderthumb", - "round", - "-internal-media-subtitles-icon", - "media-play-button", - "smaller", - "jis04", - "lr-tb", - "lightgoldenrodyellow", - "lavender", - "ultra-expanded", - "dimgrey", - "diagonal-fractions", - "blue", - "xor", - "sub", - "telugu", - "crispEdges", - "-webkit-mini-control", - "zoom-out", - "searchfield", - "cell", - "gujarati", - "above", - "no-punctuation", - "new", - "filled", - "use-script", - "condensed", - "loose", - "source-out", - "objects", - "slider-horizontal", - "row-resize", - "break-all", - "wait", - "media-exit-fullscreen-button", - "korean-hangul-formal", - "floralwhite", - "reset-size", - "zoom-in", - "-webkit-grabbing", - "larger", - "max-content", - "sRGB", - "literal-punctuation", - "windowframe", - "subpixel-antialiased", - "buttonhighlight", - "hue", - "pixelated", - "sticky", - "greenyellow", - "linearRGB", - "lightseagreen", - "logical", - "-webkit-right", - "sienna", - "flow-root", - "optimizeSpeed", - "korean-hanja-formal", - "nowrap", - "x-small", - "landscape", - "lime", - "x-large", - "ns-resize", - "appworkspace", - "peru", - "all-petite-caps", - "black", - "xx-small", - "all-scroll", - "darkslategray", - "flat", - "georgian", - "under", - "lemonchiffon", - "chocolate", - "pre-line", - "context-menu", - "darkgrey", - "view-box", - "olive", - "-webkit-plaintext", - "extra-expanded", - "antiquewhite", - "none", - "moccasin", - "local", - "stroke", - "darkslateblue", - "lightskyblue", - "content-box", - "thin", - "deeppink", - "spell-out", - "non-scaling-stroke", - "slider-vertical", - "-webkit-box", - "plum", - "-internal-media-overlay-cast-off-button", - "inactivecaptiontext", - "dodgerblue", - "threedshadow", - "petite-caps", - "paused", - "-webkit-link", - "message-box", - "-internal-center", - "triangle", - "magenta", - "tan", - "absolute", - "pink", - "hiragana-iroha", - "farthest-side", - "palevioletred", - "close-quote", - "threedlightshadow", - "caption", - "powderblue", - "table-column", - "source-atop", - "hiragana", - "upper-armenian", - "windowtext", - "full-width", - "progress-bar-value", - "midnightblue", - "inline-flex", - "economy", - "lao", - "clone", - "after", - "status-bar", - "lowercase", - "mixed", - "line-through", - "lightslategray", - "small-caption", - "infobackground", - "discard", - "captiontext", - "end", - "-internal-inactive-list-box-selection-text", - "capitalize", - "mediumseagreen", - "tomato", - "cadetblue", - "decimal-leading-zero", - "sans-serif", - "linen", - "green", - "inactiveborder", - "inline", - "fallback", - "peachpuff", - "-webkit-max-content", - "plus-lighter", - "checkbox", - "help", - "oblique", - "move", - "meter", - "ledger", - "slategrey", - "media-time-remaining-display", - "urdu", - "pointer", - "before", - "darkslategrey", - "-webkit-control", - "-webkit-inline-box", - "hard-light", - "miter", - "oriya", - "upper-latin", - "window", - "mediumblue", - "lr", - "orange", - "hidden", - "-internal-active-list-box-selection", - "bolder", - "-webkit-center", - "safe", - "highlighttext", - "accumulate", - "flex-end", - "transparent", - "-internal-media-remoting-cast-icon", - "goldenrod", - "historical-ligatures", - "darkviolet", - "always", - "decimal", - "block-axis", - "scrollbar", - "ew-resize", - "darkmagenta", - "not-allowed", - "ease-in", - "table-column-group", - "square", - "no-contextual", - "-webkit-fill-available", - "frames", - "persian", - "static", - "navy", - "visiblePainted", - "thick", - "simp-chinese-formal", - "ghostwhite", - "space", - "darkkhaki", - "keep-all", - "content", - "-internal-media-download-button", - "upper-roman", - "cornsilk", - "red", - "no-change", - "linear", - "-internal-media-control", - "sideways", - "contain", - "katakana-iroha", - "steelblue", - "double-circle", - "antialiased", - "aliceblue", - "lightslategrey", - "geometricPrecision", - "gainsboro", - "inline-table", - "ltr", - "backwards", - "s-resize", - "lightgrey", - "media-mute-button", - "listitem", - "mistyrose", - "darksalmon", - "sideways-right", - "jis83", - "mediumspringgreen", - "caps-lock-indicator", - "sliderthumb-horizontal", - "forwards", - "upper-alpha", - "blink", - "fantasy", - "simplified", - "orangered", - "navajowhite", - "open", - "horizontal", - "slategray", - "activecaption", - "korean-hanja-informal", - "strict", - "lightcyan", - "top", - "-webkit-pictograph", - "white", - "text-after-edge", - "lightgray", - "collapse", - "hover", - "-webkit-optimize-contrast", - "padding", - "butt", - "off", - "thai", - "copy", - "hotpink", - "double", - "lower-greek", - "grey", - "media-volume-slider-container", - "-webkit-inline-flex", - "space-evenly", - "activeborder", - "browser", - "pre", - "unicase", - "simp-chinese-informal", - "clip", - "closest-corner", - "plaintext", - "no-repeat", - "text-top", - "jis78", - "xx-large", - "rl-tb", - "table-row", - "medium", - "mongolian", - "katakana", - "element", - "border", - "rosybrown", - "progress-bar", - "whitesmoke", - "lightblue", - "-webkit-left", - "no-common-ligatures", - "listbox", - "isolate", - "snow", - "step-end", - "ethiopic-halehame-ti-er", - "ethiopic-halehame-ti-et", - "multiple", - "-internal-inactive-list-box-selection", - "normal", - "blueviolet", - "salmon", - "lower-alpha", - "oldlace", - "letter", - "border-box", - "alpha", - "tibetan", - "icon", - "flex-start", - "textarea", - "w-resize", - "clear", - "cover", - "farthest-corner", - "menulist-textfield", - "traditional", - "left", - "dot", - "luminance", - "gold", - "show", - "text", - "-webkit-match-parent", - "radio", - "cambodian", - "repeat-x", - "repeat-y", - "fine", - "textfield", - "from-image", - "lining-nums", - "menu", - "proportional-nums", - "source-over", - "ne-resize", - "papayawhip", - "source-in", - "se-resize", - "circle", - "destination-out", - "threedface", - "over", - "distribute", - "inactivecaption", - "lighten", - "-webkit-fit-content", - "lighter", - "contextual", - "gray", - "darkturquoise", - "e-resize", - "luminosity", - "list-item", - "limegreen", - "fixed", - "min-content", - "media-slider", - "visibleStroke", - "cubic-bezier", - "closest-side", - "relative", - "no-open-quote", - "thistle", - "violet", - "portrait", - "fullscreen", - "honeydew", - "on-demand", - "cornflowerblue", - "darkblue", - "outside", - "progress", - "mediumpurple", - "darkcyan", - "vertical", - "monospace", - "break-word", - "screen", - "rebeccapurple", - "darkred", - "vertical-lr", - "optimizeQuality", - "armenian", - "nwse-resize", - "text-before-edge", - "optional", - "exclusion", - "both", - "mediumturquoise", - "lower-roman", - "reverse", - "hangul-consonant", - "soft-light", - "aqua", - "button-bevel", - "gurmukhi", - "lightsteelblue", - "small-caps", - "n-resize", - "table-footer-group", - "destination-in", - "olivedrab", - "read-write-plaintext-only", - "padding-box", - "col-resize", - "-internal-media-track-selection-checkmark", - "lower-latin", - "-webkit-nowrap", - "table", - "buttonshadow", - "palegreen", - "jis90", - "fit-content", - "stretch", - "seashell", - "threedhighlight", - "visibleFill", - "space-around", - "coarse", - "aquamarine", - "digits", - "currentcolor", - "painted", - "tb-rl", - "buttonface", - "lawngreen", - "burlywood", - "-webkit-small-control", - "slateblue", - "mintcream", - "ruby", - "solid", - "ultra-condensed", - "expanded", - "saddlebrown", - "vertical-rl", - "sesame", - "-webkit-body", - "destination-atop", - "malayalam", - "wrap-reverse", - "balance", - "vertical-right", - "no-close-quote", - "flex", - "push-button", - "darkgoldenrod", - "saturation", - "middle", - "sandybrown", - "hebrew", - "menutext", - "inline-axis", - "baseline", - "-webkit-grab", - "darkorange", - "-webkit-flex", - "nw-resize", - "contents", - "auto", - "margin-box", - "document", - "palegoldenrod", - "ordinal", - "hand", - "running", - "cjk-earthly-branch", - "table-caption", - "media-toggle-closed-captions-button", - "after-edge", - "sliderthumb-vertical", - "center", - "lightyellow", - "lavenderblush", - "-internal-media-closed-captions-icon", - "inherit", - "media-controls-background", - "justify", - "optimizeLegibility", - "-webkit-baseline-middle", - "indigo", - "minimal-ui", - "firebrick", - "indianred", - "darkolivegreen", - "semi-expanded", - "underline", - "myanmar", - "space-between", - "ease", - "alternate", - "mediumorchid", - "silver", - "color", - "chartreuse", - "ease-in-out", - "springgreen", - "lightsalmon", - "turquoise", - "hide", - "horizontal-tb", - "vertical-text", - "alias", - "grid", - "no-discretionary-ligatures", - "background", - "devanagari", - "text-bottom", - "darkgreen", - "visible", - "tabular-nums", - "manual", - "zoom", - "cjk-heavenly-stem", - "steps", - "bounding-box", - "alphabetic", - "after-white-space", - "row-reverse", - "media-current-time-display", - "mathematical", - "ethiopic-halehame", - "right", - "uppercase", - "-webkit-xxx-large", - "b4", - "b5", - "yellowgreen", - "media-controls-fullscreen-background", - "lower-armenian", - "orchid", - "nonzero", - "slice", - "dense", - "inter-word", - "bottom", - "purple", - "avoid", - "separate", - "hangul", - "legal", - "alternate-reverse", - "preserve-3d", - "read-only", - "ellipsis", - "media-overlay-play-button", - "bisque", - "infotext", - "khaki", - "wheat", - "bold", - "no-historical-ligatures", - "bidi-override", - "deepskyblue", - "ease-out", - "cjk-ideographic", - "oldstyle-nums", - "media-enter-fullscreen-button", - "super", - "cursive", - "on", - "central", - "-internal-media-overflow-button", - "standalone", - "column", - "coral", - "destination-over", - "discretionary-ligatures", - "beige", - "table-cell", - "azure", - "trad-chinese-informal", - "titling-caps", - "-webkit-zoom-in", - "block", - "outset", - "mediumvioletred", - "royalblue", - "menulist-text", - "sw-resize", - "multiply", - "threeddarkshadow", - "wrap", - "lightcoral", - "ellipse", - "-internal-active-list-box-selection-text", - "ridge", - "-webkit-auto", - "-internal-quirk-inherit", - "initial", - "fuchsia", - "menulist-button", - "blanchedalmond", - "caret", - "start", - "-internal-media-cast-off-button", - "italic", - "ivory", - "buttontext", - "semi-condensed", - "inline-grid", - "-webkit-activelink", - "serif", - "forestgreen", - "bengali", - "upright", - "reset", - "bevel", - "ideographic", - "darken", - "media-volume-sliderthumb", - "default", - "inside", - "below", - "highlight", - "embed", - "groove", - "nesw-resize", - "stacked-fractions", - "unsafe", - "maroon", - "kannada", - "single", - "at", - "ink", - "arabic-indic", - "media-volume-slider", - "column-reverse", - "-webkit-zoom-out", - "fill", - "evenodd", - "dotted", - "dimgray", - "dashed", - "seagreen", - "trad-chinese-formal", - "mediumslateblue", - "paleturquoise", - "inner-spin-button", - "repeat", - "darkorchid", - "-webkit-isolate", - "searchfield-cancel-button", - "all-small-caps", - "a3", - "a5", - "a4", - "open-quote", - "lightgreen", - "slashed-zero", - "color-burn", - "auto-flow", - "overlay", - "visual", - "scale-down", - "overline", - "inset", - "mediumaquamarine", - "scroll", - "layout", - "break-spaces", - "pan-left", - "proximity", - "inline-start", - "pan-x", - "grab", - "grabbing", - "inline-end", - "pan-right", - "jump-end", - "manipulation", - "pinch-zoom", - "xxx-large", - "pan-down", - "anywhere", - "jump-none", - "drag", - "avoid-page", - "mandatory", - "paint", - "jump-both", - "size", - "style", - "pan-y", - "recto", - "markers", - "verso", - "page", - "pan-up", - "avoid-column", - "smooth", - "jump-start", - "no-drag", - "jis-b5", - "jis-b4", - "standard", - "high", - "spelling-error", - "grammar-error", - "INVALID_VALUE", -}; - -const std::string Converter::kPropertyLookupTable[] = { - "", // This is just to fill the zeroth spot. It should not be used. - "all", - "-webkit-animation-iteration-count", - "font-feature-settings", - "-webkit-text-emphasis-position", - "-webkit-text-emphasis-style", - "grid-template-rows", - "text-underline-position", - "-webkit-flex-grow", - "scroll-margin-right", - "-webkit-column-rule", - "-webkit-order", - "grid-row-gap", - "row-gap", - "backdrop-filter", - "font-variant-east-asian", - "buffered-rendering", - "-webkit-appearance", - "outline-width", - "alignment-baseline", - "-webkit-flex-flow", - "column-rule", - "grid-column-gap", - "-webkit-border-after", - "-webkit-column-break-inside", - "-webkit-shape-outside", - "-webkit-print-color-adjust", - "list-style-type", - "page-break-before", - "flood-color", - "text-anchor", - "-webkit-padding-start", - "-webkit-user-select", - "-webkit-column-rule-color", - "padding-left", - "-webkit-backface-visibility", - "-webkit-margin-before", - "break-inside", - "column-count", - "-webkit-logical-height", - "perspective", - "max-block-size", - "-webkit-animation-play-state", - "border-image-repeat", - "-internal-font-size-delta", - "scroll-padding-bottom", - "border-right-style", - "border-left-style", - "scroll-margin-block", - "flex-flow", - "outline-color", - "flex-grow", - "max-width", - "grid-column", - "image-orientation", - "animation-duration", - "-webkit-columns", - "-webkit-animation-delay", - "-epub-text-emphasis", - "flex-shrink", - "text-rendering", - "align-items", - "border-collapse", - "offset", - "text-combine-upright", - "-webkit-mask-position-x", - "-webkit-mask-position-y", - "outline-style", - "color-interpolation-filters", - "font-variant", - "-webkit-animation-fill-mode", - "border-right", - "visibility", - "transform-box", - "font-variant-caps", - "-epub-text-emphasis-color", - "-webkit-border-before-style", - "resize", - "-webkit-rtl-ordering", - "-webkit-box-ordinal-group", - "paint-order", - "stroke-linecap", - "animation-direction", - "-webkit-font-feature-settings", - "border-top-left-radius", - "-webkit-column-width", - "-webkit-box-align", - "-webkit-padding-after", - "column-width", - "list-style", - "-webkit-mask-repeat-y", - "stroke", - "text-decoration-line", - "-webkit-background-size", - "-webkit-mask-repeat-x", - "padding-bottom", - "font-style", - "-webkit-transition-delay", - "background-repeat", - "flex-basis", - "border-image-slice", - "-webkit-transform-origin", - "scroll-boundary-behavior-x", - "scroll-boundary-behavior-y", - "vector-effect", - "-webkit-animation-timing-function", - "-webkit-border-after-style", - "-webkit-perspective-origin-x", - "-webkit-perspective-origin-y", - "inline-size", - "outline", - "font-display", - "-webkit-border-before", - "border-image-source", - "transition-duration", - "scroll-padding-top", - "order", - "-webkit-box-orient", - "counter-reset", - "color-rendering", - "flex-direction", - "-webkit-text-stroke-width", - "font-variant-numeric", - "scroll-margin-block-end", - "min-height", - "scroll-padding-inline-start", - "-webkit-mask-box-image", - "left", - "-webkit-mask", - "-webkit-border-after-width", - "stroke-width", - "-webkit-box-decoration-break", - "-webkit-mask-position", - "background-origin", - "-webkit-border-start-color", - "font-stretch", - "-webkit-background-clip", - "scroll-margin-top", - "-webkit-border-horizontal-spacing", - "border-radius", - "flex", - "text-indent", - "hyphens", - "column-rule-width", - "-webkit-margin-after", - "-epub-caption-side", - "break-after", - "text-transform", - "touch-action", - "font-size", - "-webkit-animation-name", - "scroll-padding-inline", - "offset-path", - "scroll-margin", - "padding-top", - "scroll-snap-align", - "-webkit-text-combine", - "-webkit-flex-shrink", - "rx", - "ry", - "content", - "padding-right", - "-webkit-transform", - "marker-mid", - "-webkit-min-logical-width", - "clip-rule", - "font-family", - "scroll-snap-type", - "text-decoration-skip-ink", - "transition", - "filter", - "border-right-width", - "-webkit-flex-direction", - "-webkit-mask-composite", - "mix-blend-mode", - "color-interpolation", - "border-top-style", - "fill-opacity", - "marker-start", - "border-bottom-width", - "-webkit-text-emphasis", - "grid-area", - "size", - "background-clip", - "-webkit-text-fill-color", - "top", - "-webkit-box-reflect", - "border-width", - "offset-anchor", - "max-inline-size", - "-webkit-column-rule-style", - "-webkit-column-count", - "animation-play-state", - "padding", - "dominant-baseline", - "background-attachment", - "-webkit-box-sizing", - "-webkit-box-flex", - "text-orientation", - "background-position", - "-webkit-border-start-width", - "-epub-text-emphasis-style", - "isolation", - "-epub-text-orientation", - "-webkit-border-bottom-right-radius", - "r", - "border-left-width", - "grid-column-end", - "background-blend-mode", - "vertical-align", - "clip", - "grid-auto-rows", - "offset-rotate", - "margin-left", - "animation-name", - "text-decoration", - "border", - "-webkit-transition-timing-function", - "margin-bottom", - "unicode-range", - "animation", - "-webkit-shape-margin", - "font-weight", - "shape-margin", - "mask-type", - "scroll-padding", - "min-inline-size", - "object-position", - "page-break-after", - "-webkit-mask-clip", - "white-space", - "-webkit-border-after-color", - "-webkit-max-logical-width", - "-webkit-border-before-color", - "font-kerning", - "-epub-word-break", - "clear", - "animation-timing-function", - "-webkit-border-radius", - "scroll-padding-right", - "-webkit-text-decorations-in-effect", - "-webkit-animation-direction", - "justify-self", - "transition-timing-function", - "scroll-snap-stop", - "counter-increment", - "-webkit-transform-style", - "grid-auto-columns", - "-webkit-align-content", - "font", - "flex-wrap", - "grid-row-start", - "list-style-image", - "-webkit-tap-highlight-color", - "-webkit-text-emphasis-color", - "border-left", - "-webkit-border-end-color", - "columns", - "box-shadow", - "-webkit-flex-wrap", - "align-self", - "border-bottom", - "border-spacing", - "-webkit-column-span", - "grid-row-end", - "-webkit-border-end", - "perspective-origin", - "page-break-inside", - "orphans", - "-webkit-border-start-style", - "scroll-behavior", - "column-span", - "-webkit-hyphenate-character", - "column-fill", - "tab-size", - "contain", - "x", - "grid-row", - "border-bottom-right-radius", - "line-height", - "stroke-linejoin", - "text-align-last", - "offset-position", - "word-spacing", - "transform-style", - "-webkit-app-region", - "-webkit-border-end-style", - "-webkit-transform-origin-z", - "-webkit-transform-origin-x", - "-webkit-transform-origin-y", - "background-repeat-x", - "background-repeat-y", - "border-bottom-color", - "-webkit-ruby-position", - "-webkit-logical-width", - "text-justify", - "scroll-margin-inline-start", - "caption-side", - "mask-source-type", - "-webkit-mask-box-image-slice", - "-webkit-border-image", - "text-size-adjust", - "-webkit-text-security", - "-epub-writing-mode", - "grid-template", - "-webkit-mask-box-image-repeat", - "-webkit-mask-repeat", - "-webkit-justify-content", - "baseline-shift", - "border-image", - "text-decoration-color", - "color", - "shape-image-threshold", - "shape-rendering", - "cy", - "cx", - "-webkit-user-modify", - "offset-distance", - "-webkit-border-bottom-left-radius", - "speak", - "border-bottom-left-radius", - "-webkit-column-break-after", - "-webkit-font-smoothing", - "-webkit-max-logical-height", - "-webkit-line-break", - "fill-rule", - "-webkit-margin-start", - "min-width", - "-epub-text-combine", - "break-before", - "caret-color", - "empty-cells", - "direction", - "clip-path", - "justify-content", - "scroll-padding-block-end", - "z-index", - "background-position-y", - "text-decoration-style", - "grid-template-areas", - "-webkit-min-logical-height", - "font-size-adjust", - "scroll-padding-block", - "overflow-anchor", - "cursor", - "scroll-margin-block-start", - "-webkit-mask-box-image-source", - "margin", - "-webkit-animation", - "letter-spacing", - "orientation", - "will-change", - "-webkit-highlight", - "transform-origin", - "font-variant-ligatures", - "-webkit-animation-duration", - "-webkit-mask-origin", - "-webkit-clip-path", - "word-break", - "table-layout", - "text-overflow", - "-webkit-locale", - "-webkit-flex", - "grid-auto-flow", - "border-top-right-radius", - "border-image-outset", - "place-items", - "border-left-color", - "font-variation-settings", - "border-right-color", - "min-zoom", - "scroll-margin-inline", - "-webkit-border-before-width", - "backface-visibility", - "background-image", - "-webkit-transition-property", - "writing-mode", - "stroke-opacity", - "box-sizing", - "margin-top", - "column-rule-color", - "y", - "position", - "scroll-margin-bottom", - "list-style-position", - "-webkit-box-pack", - "scroll-padding-inline-end", - "quotes", - "border-top", - "scroll-padding-left", - "-webkit-transition", - "-webkit-column-break-before", - "lighting-color", - "background-size", - "-webkit-padding-before", - "-webkit-border-top-left-radius", - "flood-opacity", - "line-height-step", - "-webkit-mask-size", - "text-align", - "-webkit-filter", - "word-wrap", - "max-zoom", - "grid", - "background", - "height", - "grid-column-start", - "animation-fill-mode", - "rotate", - "marker-end", - "d", - "justify-items", - "zoom", - "scroll-padding-block-start", - "page", - "right", - "user-select", - "margin-right", - "marker", - "line-break", - "-webkit-margin-end", - "-webkit-transition-duration", - "-webkit-writing-mode", - "border-top-width", - "bottom", - "place-content", - "-webkit-shape-image-threshold", - "-webkit-user-drag", - "-webkit-border-vertical-spacing", - "-webkit-column-gap", - "-webkit-opacity", - "background-color", - "column-gap", - "shape-outside", - "-webkit-padding-end", - "-webkit-border-start", - "animation-delay", - "unicode-bidi", - "text-shadow", - "-webkit-box-direction", - "image-rendering", - "src", - "gap", - "grid-gap", - "pointer-events", - "border-image-width", - "min-block-size", - "transition-property", - "-webkit-mask-image", - "float", - "max-height", - "outline-offset", - "-webkit-box-shadow", - "overflow-wrap", - "block-size", - "transform", - "place-self", - "width", - "stroke-miterlimit", - "stop-opacity", - "border-top-color", - "translate", - "object-fit", - "-webkit-mask-box-image-width", - "-webkit-background-origin", - "-webkit-align-items", - "transition-delay", - "scroll-margin-left", - "border-style", - "animation-iteration-count", - "overflow", - "user-zoom", - "-webkit-border-top-right-radius", - "grid-template-columns", - "-webkit-align-self", - "-webkit-perspective-origin", - "column-rule-style", - "display", - "-webkit-column-rule-width", - "border-color", - "-webkit-flex-basis", - "stroke-dashoffset", - "-webkit-text-size-adjust", - "scroll-boundary-behavior", - "-webkit-text-stroke", - "widows", - "fill", - "overflow-y", - "overflow-x", - "opacity", - "-webkit-perspective", - "-webkit-text-stroke-color", - "scroll-margin-inline-end", - "scale", - "-webkit-text-orientation", - "-webkit-mask-box-image-outset", - "align-content", - "-webkit-border-end-width", - "border-bottom-style", - "mask", - "background-position-x", - "-epub-text-transform", - "stop-color", - "stroke-dasharray", - "-webkit-line-clamp", - "margin-block-start", - "margin-block-end", - "margin-inline-start", - "margin-inline-end", - "padding-block-start", - "padding-block-end", - "padding-inline-start", - "padding-inline-end", - "border-block-start-width", - "border-block-start-style", - "border-block-start-color", - "border-block-end-width", - "border-block-end-style", - "border-block-end-color", - "border-inline-start-width", - "border-inline-start-style", - "border-inline-start-color", - "border-inline-end-width", - "border-inline-end-style", - "border-inline-end-color", - "border-block-start", - "border-block-end", - "border-inline-start", - "border-inline-end", - "margin-block", - "margin-inline", - "padding-block", - "padding-inline", - "border-block-width", - "border-block-style", - "border-block-color", - "border-inline-width", - "border-inline-style", - "border-inline-color", - "border-block", - "border-inline", - "inset-block-start", - "inset-block-end", - "inset-block", - "inset-inline-start", - "inset-inline-end", - "inset-inline", - "inset", - "overflow-block", - "overflow-inline", - "forced-color-adjust", - "overscroll-behavior-inline", - "overscroll-behavior-block", - "overscroll-behavior-x", - "overscroll-behavior-y", - "animation-timeline", - "counter-set", - "border-start-start-radius", - "border-start-end-radius", - "border-end-start-radius", - "border-end-end-radius", - "INVALID_PROPERTY", -}; +#include "third_party/blink/renderer/core/css/parser/css_proto_converter_generated.h" Converter::Converter() = default;
diff --git a/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h b/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h index fd96aef..e1e519c 100644 --- a/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h +++ b/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_DEPTH_ORDERED_LAYOUT_OBJECT_LIST_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_DEPTH_ORDERED_LAYOUT_OBJECT_LIST_H_ +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -61,7 +62,7 @@ void Clear(); int size() const; - bool IsEmpty() const; + CORE_EXPORT bool IsEmpty() const; const HeapHashSet<Member<LayoutObject>>& Unordered() const; const HeapVector<LayoutObjectWithDepth>& Ordered();
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc index 7bb3909..718a1c6 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -416,7 +416,8 @@ // Even if we are a layout root, our baseline may have shifted. In this // (rare) case, mark our containing-block for layout. - if (is_layout_root && previous_result) { + // The baseline of SVG <text> doesn't affect other boxes. + if (is_layout_root && previous_result && !Base::IsNGSVGText()) { if (To<NGPhysicalBoxFragment>(previous_result->PhysicalFragment()) .Baseline() != physical_fragment.Baseline()) { if (auto* containing_block = Base::ContainingBlock()) {
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text_test.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text_test.cc index 6edbae8..e73977f 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text_test.cc +++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text_test.cc
@@ -3,12 +3,36 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h" +#include "third_party/blink/renderer/core/loader/empty_clients.h" namespace blink { +class LayoutCounts : public EmptyLocalFrameClient { + public: + uint32_t AllCallCount() const { return all_call_count_; } + + private: + void DidObserveLayoutNg(uint32_t all_block_count, + uint32_t ng_block_count, + uint32_t all_call_count, + uint32_t ng_call_count, + uint32_t flexbox_ng_block_count, + uint32_t grid_ng_block_count) override { + all_call_count_ += all_call_count; + } + + uint32_t all_call_count_ = 0; +}; + class LayoutNGSVGTextTest : public NGLayoutTest { public: - LayoutNGSVGTextTest() : svg_text_ng_(true) {} + LayoutNGSVGTextTest() + : NGLayoutTest(MakeGarbageCollected<LayoutCounts>()), + svg_text_ng_(true) {} + + uint32_t AllLayoutCallCount() const { + return static_cast<LayoutCounts*>(GetFrame().Client())->AllCallCount(); + } private: ScopedSVGTextNGForTest svg_text_ng_; @@ -72,4 +96,27 @@ EXPECT_FALSE(std::isinf(box.height())); } +// crbug.com/1285666 +TEST_F(LayoutNGSVGTextTest, SubtreeLayout) { + SetBodyInnerHTML(R"HTML( +<body> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 360"> +<text x="240" y="25" font-size="16" id="t">foo</text> +<text x="240" y="50" font-size="16" id="t2">bar</text> +</svg> +</body>)HTML"); + UpdateAllLifecyclePhasesForTest(); + LocalFrameView* frame_view = GetFrame().View(); + LayoutView& view = GetLayoutView(); + ASSERT_FALSE(view.NeedsLayout()); + + GetElementById("t")->setAttribute("transform", "scale(0.5)"); + EXPECT_TRUE(frame_view->IsSubtreeLayout()); + + uint32_t pre_layout_count = AllLayoutCallCount(); + UpdateAllLifecyclePhasesForTest(); + // Only the <text> and its parent <svg> should be laid out again. + EXPECT_EQ(2u, AllLayoutCallCount() - pre_layout_count); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc index 2a7251e..31bbaf2 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -51,17 +51,6 @@ INSTANTIATE_PAINT_TEST_SUITE_P(CompositingReasonFinderTest); -TEST_P(CompositingReasonFinderTest, CompositingReasonDependencies) { - EXPECT_FALSE(CompositingReason::kComboAllDirectNonStyleDeterminedReasons & - (~CompositingReason::kComboAllDirectReasons)); - EXPECT_REASONS( - CompositingReason::kComboAllDirectReasons, - CompositingReason::kComboAllDirectStyleDeterminedReasons | - CompositingReason::kComboAllDirectNonStyleDeterminedReasons); - EXPECT_FALSE(CompositingReason::kComboAllDirectNonStyleDeterminedReasons & - CompositingReason::kComboAllStyleDeterminedReasons); -} - TEST_P(CompositingReasonFinderTest, PromoteTrivial3D) { SetBodyInnerHTML(R"HTML( <div id='target'
diff --git a/third_party/blink/renderer/core/streams/promise_handler.h b/third_party/blink/renderer/core/streams/promise_handler.h index ce8d713..c6004ab 100644 --- a/third_party/blink/renderer/core/streams/promise_handler.h +++ b/third_party/blink/renderer/core/streams/promise_handler.h
@@ -39,7 +39,7 @@ // PromiseHandlers. It avoids having to call BindToV8Function() // explicitly. If |on_rejected| is null then behaves like single-argument // Then(). If |on_fulfilled| is null then it behaves like Catch(). -v8::Local<v8::Promise> StreamThenPromise( +CORE_EXPORT v8::Local<v8::Promise> StreamThenPromise( v8::Local<v8::Context>, v8::Local<v8::Promise>, NewScriptFunction* on_fulfilled,
diff --git a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc index fb0c8106..9caa50f 100644 --- a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc +++ b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc
@@ -928,35 +928,6 @@ return out; } -ScriptPromise NavigatorAuction::deprecatedURNToURL( - ScriptState* script_state, - const String& uuid_url_string, - ExceptionState& exception_state) { - if (!uuid_url_string.StartsWithIgnoringCase("urn:uuid:")) { - exception_state.ThrowTypeError( - String::Format("Passed URL must start with 'urn:uuid:'.")); - return ScriptPromise(); - } - - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - KURL uuid_url(uuid_url_string); - ad_auction_service_->DeprecatedGetURLFromURN( - std::move(uuid_url), - WTF::Bind(&NavigatorAuction::GetURLFromURNComplete, WrapPersistent(this), - WrapPersistent(resolver))); - return promise; -} - -ScriptPromise NavigatorAuction::deprecatedURNToURL( - ScriptState* script_state, - Navigator& navigator, - const String& uuid_url, - ExceptionState& exception_state) { - return From(ExecutionContext::From(script_state), navigator) - .deprecatedURNToURL(script_state, uuid_url, exception_state); -} - ScriptPromise NavigatorAuction::createAdRequest( ScriptState* script_state, const AdRequestConfig* config, @@ -1092,17 +1063,4 @@ } } -void NavigatorAuction::GetURLFromURNComplete( - ScriptPromiseResolver* resolver, - const absl::optional<KURL>& decoded_url) { - if (!resolver->GetExecutionContext() || - resolver->GetExecutionContext()->IsContextDestroyed()) - return; - if (decoded_url) { - resolver->Resolve(*decoded_url); - } else { - resolver->Resolve(v8::Null(resolver->GetScriptState()->GetIsolate())); - } -} - } // namespace blink
diff --git a/third_party/blink/renderer/modules/ad_auction/navigator_auction.h b/third_party/blink/renderer/modules/ad_auction/navigator_auction.h index 9872e46..097a9d9 100644 --- a/third_party/blink/renderer/modules/ad_auction/navigator_auction.h +++ b/third_party/blink/renderer/modules/ad_auction/navigator_auction.h
@@ -80,15 +80,6 @@ uint16_t num_ad_components, ExceptionState& exception_state); - ScriptPromise deprecatedURNToURL(ScriptState* script_state, - const String& uuid_url_string, - ExceptionState& exception_state); - - static ScriptPromise deprecatedURNToURL(ScriptState* script_state, - Navigator& navigator, - const String& uuid_url_string, - ExceptionState& exception_state); - ScriptPromise createAdRequest(ScriptState*, const AdRequestConfig*, ExceptionState&); @@ -120,9 +111,6 @@ const absl::optional<KURL>& creative_url); // Completion callback for Mojo call made by runAdAuction(). void AuctionComplete(ScriptPromiseResolver*, const absl::optional<KURL>&); - // Completion callback for Mojo call made by deprecatedURNToURL(). - void GetURLFromURNComplete(ScriptPromiseResolver*, - const absl::optional<KURL>&); HeapMojoRemote<mojom::blink::AdAuctionService> ad_auction_service_; };
diff --git a/third_party/blink/renderer/modules/ad_auction/navigator_auction.idl b/third_party/blink/renderer/modules/ad_auction/navigator_auction.idl index 0853b9f7..5e1749b5b 100644 --- a/third_party/blink/renderer/modules/ad_auction/navigator_auction.idl +++ b/third_party/blink/renderer/modules/ad_auction/navigator_auction.idl
@@ -29,9 +29,6 @@ [RuntimeEnabled=Fledge, CallWith=ScriptState, Measure, RaisesException] sequence<USVString> adAuctionComponents([Clamp] unsigned short numComponents); - [RuntimeEnable=AllowURLsinIframes, CallWith=ScriptState, Measure, RaisesException] - Promise<USVString> deprecatedURNToURL(USVString uuid_url); - [RuntimeEnabled=Parakeet, CallWith=ScriptState, Measure, RaisesException] Promise<Ads> createAdRequest(AdRequestConfig config);
diff --git a/third_party/blink/renderer/modules/nfc/ndef_reader.idl b/third_party/blink/renderer/modules/nfc/ndef_reader.idl index b7d7330c..4ca6843 100644 --- a/third_party/blink/renderer/modules/nfc/ndef_reader.idl +++ b/third_party/blink/renderer/modules/nfc/ndef_reader.idl
@@ -24,6 +24,6 @@ NDEFMessageSource message, optional NDEFWriteOptions options={}); - [CallWith=ScriptState, RaisesException, RuntimeEnabled=WebNFCMakeReadOnly] Promise<void> makeReadOnly( + [CallWith=ScriptState, RaisesException, MeasureAs=WebNfcNdefMakeReadOnly, RuntimeEnabled=WebNFCMakeReadOnly] Promise<void> makeReadOnly( optional NDEFMakeReadOnlyOptions options={}); };
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc index 268ec1c1..17c10797 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
@@ -110,13 +110,13 @@ } // static -media::StatusOr<AudioDecoderTraits::OutputType*> AudioDecoderTraits::MakeOutput( - scoped_refptr<MediaOutputType> output, - ExecutionContext* context) { +media::DecoderStatus::Or<AudioDecoderTraits::OutputType*> +AudioDecoderTraits::MakeOutput(scoped_refptr<MediaOutputType> output, + ExecutionContext* context) { if (!blink::audio_utilities::IsValidAudioBufferSampleRate( output->sample_rate())) { - return media::Status( - media::StatusCode::kInvalidArgument, + return media::DecoderStatus( + media::DecoderStatus::Codes::kInvalidArgument, String::Format("Invalid decoded audio output sample rate. Got %u, " "which is outside [%f, %f]", output->sample_rate(), @@ -127,12 +127,13 @@ if (static_cast<uint32_t>(output->channel_count()) > BaseAudioContext::MaxNumberOfChannels()) { - return media::Status(media::StatusCode::kInvalidArgument, - String::Format("Invalid decoded audio output channel " - "count. Got %u, which exceeds %u", - output->channel_count(), - BaseAudioContext::MaxNumberOfChannels()) - .Ascii()); + return media::DecoderStatus( + media::DecoderStatus::Codes::kInvalidArgument, + String::Format("Invalid decoded audio output channel " + "count. Got %u, which exceeds %u", + output->channel_count(), + BaseAudioContext::MaxNumberOfChannels()) + .Ascii()); } return MakeGarbageCollected<AudioDecoderTraits::OutputType>( @@ -243,11 +244,10 @@ *out_console_message); } -media::StatusOr<scoped_refptr<media::DecoderBuffer>> +media::DecoderStatus::Or<scoped_refptr<media::DecoderBuffer>> AudioDecoder::MakeDecoderBuffer(const InputType& chunk, bool verify_key_frame) { if (verify_key_frame && !chunk.buffer()->is_key_frame()) - return media::Status(media::StatusCode::kKeyFrameRequired); - + return media::DecoderStatus::Codes::kKeyFrameRequired; return chunk.buffer(); }
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.h b/third_party/blink/renderer/modules/webcodecs/audio_decoder.h index 074f48d..61b4cc8b 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.h +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.h
@@ -64,8 +64,9 @@ static void UpdateDecoderLog(const MediaDecoderType& decoder, const MediaConfigType& media_config, media::MediaLog* media_log); - static media::StatusOr<OutputType*> MakeOutput(scoped_refptr<MediaOutputType>, - ExecutionContext*); + static media::DecoderStatus::Or<OutputType*> MakeOutput( + scoped_refptr<MediaOutputType>, + ExecutionContext*); static const char* GetName(); }; @@ -94,9 +95,8 @@ CodecConfigEval MakeMediaConfig(const ConfigType& config, MediaConfigType* out_media_config, String* out_console_message) override; - media::StatusOr<scoped_refptr<media::DecoderBuffer>> MakeDecoderBuffer( - const InputType& chunk, - bool verify_key_frame) override; + media::DecoderStatus::Or<scoped_refptr<media::DecoderBuffer>> + MakeDecoderBuffer(const InputType& chunk, bool verify_key_frame) override; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.cc index 34d2a772..d47563a6 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.cc +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.cc
@@ -42,8 +42,8 @@ }; template <> -struct CrossThreadCopier<media::Status> - : public CrossThreadCopierPassThrough<media::Status> { +struct CrossThreadCopier<media::DecoderStatus> + : public CrossThreadCopierPassThrough<media::DecoderStatus> { STATIC_ONLY(CrossThreadCopier); }; @@ -64,10 +64,10 @@ class MediaAudioTaskWrapper { public: using CrossThreadOnceInitCB = - WTF::CrossThreadOnceFunction<void(media::Status status, + WTF::CrossThreadOnceFunction<void(media::DecoderStatus status, absl::optional<DecoderDetails>)>; using CrossThreadOnceDecodeCB = - WTF::CrossThreadOnceFunction<void(media::Status)>; + WTF::CrossThreadOnceFunction<void(media::DecoderStatus)>; using CrossThreadOnceResetCB = WTF::CrossThreadOnceClosure; MediaAudioTaskWrapper( @@ -134,7 +134,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!decoder_) { - OnDecodeDone(cb_id, media::DecodeStatus::DECODE_ERROR); + OnDecodeDone(cb_id, media::DecoderStatus::Codes::kNotInitialized); return; } @@ -195,13 +195,14 @@ decoder_ = std::move(decoder); - media::Status status(media::StatusCode::kDecoderUnsupportedConfig); - absl::optional<DecoderDetails> decoder_details; + media::DecoderStatus status = media::DecoderStatus::Codes::kOk; + absl::optional<DecoderDetails> decoder_details = absl::nullopt; if (decoder_) { - status = media::OkStatus(); decoder_details = DecoderDetails({decoder_->GetDecoderType(), decoder_->IsPlatformDecoder(), decoder_->NeedsBitstreamConversion()}); + } else { + status = media::DecoderStatus::Codes::kUnsupportedConfig; } // Fire |init_cb|. @@ -221,7 +222,7 @@ weak_client_, std::move(buffer))); } - void OnDecodeDone(int cb_id, media::Status status) { + void OnDecodeDone(int cb_id, media::DecoderStatus status) { DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); PostCrossThreadTask( @@ -326,7 +327,7 @@ return last_callback_id_; } -void AudioDecoderBroker::OnInitialize(media::Status status, +void AudioDecoderBroker::OnInitialize(media::DecoderStatus status, absl::optional<DecoderDetails> details) { DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -349,7 +350,7 @@ buffer, callback_id)); } -void AudioDecoderBroker::OnDecodeDone(int cb_id, media::Status status) { +void AudioDecoderBroker::OnDecodeDone(int cb_id, media::DecoderStatus status) { DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(pending_decode_cb_map_.Contains(cb_id));
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h index fcdc3e20..cf9b2b49 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h
@@ -15,7 +15,7 @@ #include "base/sequence_checker.h" #include "media/base/audio_buffer.h" #include "media/base/audio_decoder.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -45,10 +45,10 @@ bool needs_bitstream_conversion; }; - virtual void OnInitialize(media::Status status, + virtual void OnInitialize(media::DecoderStatus status, absl::optional<DecoderDetails> details) = 0; - virtual void OnDecodeDone(int cb_id, media::Status status) = 0; + virtual void OnDecodeDone(int cb_id, media::DecoderStatus status) = 0; virtual void OnDecodeOutput(scoped_refptr<media::AudioBuffer> buffer) = 0; @@ -96,9 +96,9 @@ int CreateCallbackId(); // MediaAudioTaskWrapper::CrossThreadAudioDecoderClient - void OnInitialize(media::Status status, + void OnInitialize(media::DecoderStatus status, absl::optional<DecoderDetails> details) override; - void OnDecodeDone(int cb_id, media::Status status) override; + void OnDecodeDone(int cb_id, media::DecoderStatus status) override; void OnDecodeOutput(scoped_refptr<media::AudioBuffer> buffer) override; void OnReset(int cb_id) override;
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker_test.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker_test.cc index 87101a3..dad591f 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker_test.cc
@@ -10,8 +10,8 @@ #include "build/build_config.h" #include "media/base/audio_codecs.h" #include "media/base/channel_layout.h" -#include "media/base/decode_status.h" #include "media/base/decoder_buffer.h" +#include "media/base/decoder_status.h" #include "media/base/media_util.h" #include "media/base/mock_filters.h" #include "media/base/sample_format.h" @@ -64,14 +64,14 @@ const OutputCB& output_cb, const media::WaitingCB& waiting_cb) override { output_cb_ = output_cb; - std::move(init_cb).Run(media::OkStatus()); + std::move(init_cb).Run(media::DecoderStatus::Codes::kOk); } void Decode(scoped_refptr<media::DecoderBuffer> buffer, DecodeCB done_cb) override { DCHECK(output_cb_); - std::move(done_cb).Run(media::DecodeStatus::OK); + std::move(done_cb).Run(media::DecoderStatus::Codes::kOk); if (!buffer->end_of_stream()) { output_cb_.Run(MakeAudioBuffer(kSampleFormat, kChannelLayout, kChannels, @@ -164,12 +164,13 @@ AudioDecoderBrokerTest() = default; ~AudioDecoderBrokerTest() override = default; - void OnInitWithClosure(base::RepeatingClosure done_cb, media::Status status) { + void OnInitWithClosure(base::RepeatingClosure done_cb, + media::DecoderStatus status) { OnInit(status); done_cb.Run(); } void OnDecodeDoneWithClosure(base::RepeatingClosure done_cb, - media::Status status) { + media::DecoderStatus status) { OnDecodeDone(std::move(status)); done_cb.Run(); } @@ -179,8 +180,8 @@ done_cb.Run(); } - MOCK_METHOD1(OnInit, void(media::Status status)); - MOCK_METHOD1(OnDecodeDone, void(media::Status)); + MOCK_METHOD1(OnInit, void(media::DecoderStatus status)); + MOCK_METHOD1(OnDecodeDone, void(media::DecoderStatus)); MOCK_METHOD0(OnResetDone, void()); void OnOutput(scoped_refptr<media::AudioBuffer> buffer) { @@ -206,7 +207,8 @@ void InitializeDecoder(media::AudioDecoderConfig config) { base::RunLoop run_loop; - EXPECT_CALL(*this, OnInit(media::SameStatusCode(media::OkStatus()))); + EXPECT_CALL(*this, OnInit(media::SameStatusCode(media::DecoderStatus( + media::DecoderStatus::Codes::kOk)))); decoder_broker_->Initialize( config, nullptr /* cdm_context */, WTF::Bind(&AudioDecoderBrokerTest::OnInitWithClosure, @@ -218,9 +220,9 @@ testing::Mock::VerifyAndClearExpectations(this); } - void DecodeBuffer( - scoped_refptr<media::DecoderBuffer> buffer, - media::StatusCode expected_status = media::StatusCode::kOk) { + void DecodeBuffer(scoped_refptr<media::DecoderBuffer> buffer, + media::DecoderStatus::Codes expected_status = + media::DecoderStatus::Codes::kOk) { base::RunLoop run_loop; EXPECT_CALL(*this, OnDecodeDone(HasStatusCode(expected_status))); decoder_broker_->Decode( @@ -263,9 +265,9 @@ // No call to Initialize. Other APIs should fail gracefully. DecodeBuffer(media::ReadTestDataFile("vorbis-packet-0"), - media::DecodeStatus::DECODE_ERROR); + media::DecoderStatus::Codes::kNotInitialized); DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer(), - media::DecodeStatus::DECODE_ERROR); + media::DecoderStatus::Codes::kNotInitialized); ASSERT_EQ(0U, output_buffers_.size()); ResetDecoder();
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc b/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc index ef65121..d1e96b6 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc
@@ -69,8 +69,8 @@ const media::WaitingCB&) { EXPECT_TRUE(config.Matches(expected_config)); std::move(init_cb).Run(capability == kSucceed - ? media::OkStatus() - : media::StatusCode::kCodeOnlyForTesting); + ? media::DecoderStatus::Codes::kOk + : media::DecoderStatus::Codes::kFailed); }); } }; @@ -108,8 +108,8 @@ const media::WaitingCB&) { EXPECT_TRUE(config.Matches(expected_config)); std::move(init_cb).Run(capability == kSucceed - ? media::OkStatus() - : media::StatusCode::kCodeOnlyForTesting); + ? media::DecoderStatus::Codes::kOk + : media::DecoderStatus::Codes::kFailed); }); } };
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc index 0e7c22d..bc5bc09 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc +++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
@@ -15,7 +15,7 @@ #include "base/time/time.h" #include "base/trace_event/common/trace_event_common.h" #include "base/trace_event/trace_event.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/media_buildflags.h" #include "media/video/gpu_video_accelerator_factories.h" #include "third_party/blink/public/platform/platform.h" @@ -83,7 +83,7 @@ main_thread_task_runner_ = context->GetTaskRunner(TaskType::kInternalMediaRealTime); - logger_ = std::make_unique<CodecLogger<media::Status>>( + logger_ = std::make_unique<CodecLogger<media::DecoderStatus>>( context, main_thread_task_runner_); logger_->log()->SetProperty<media::MediaLogProperty::kFrameUrl>( @@ -180,22 +180,20 @@ Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kDecode; request->reset_generation = reset_generation_; - auto status_or_buffer = - MakeDecoderBuffer(*chunk, /*verify_key_frame=*/require_key_frame_); + auto status_or_buffer = MakeDecoderBuffer(*chunk, require_key_frame_); if (status_or_buffer.has_value()) { request->decoder_buffer = std::move(status_or_buffer).value(); require_key_frame_ = false; } else { request->status = std::move(status_or_buffer).error(); - if (request->status.code() == media::StatusCode::kKeyFrameRequired) { + if (request->status == media::DecoderStatus::Codes::kKeyFrameRequired) { exception_state.ThrowDOMException( DOMExceptionCode::kDataError, "A key frame is required after configure() or flush()."); return; } } - MarkCodecActive(); requests_.push_back(request); @@ -340,9 +338,9 @@ decoder_ = Traits::CreateDecoder(*ExecutionContext::From(script_state_), gpu_factories_.value(), logger_->log()); if (!decoder_) { - Shutdown( - logger_->MakeException("Internal error: Could not create decoder.", - media::StatusCode::kDecoderCreationFailed)); + Shutdown(logger_->MakeException( + "Internal error: Could not create decoder.", + media::DecoderStatus::Codes::kFailedToCreateDecoder)); return; } @@ -375,9 +373,9 @@ DCHECK_GT(num_pending_decodes_, 0); if (!decoder_) { - Shutdown(logger_->MakeException( - "Decoding error: no decoder found.", - media::StatusCode::kDecoderInitializeNeverCompleted)); + Shutdown( + logger_->MakeException("Decoding error: no decoder found.", + media::DecoderStatus::Codes::kNotInitialized)); return false; } @@ -391,7 +389,7 @@ if (!request->decoder_buffer || request->decoder_buffer->data_size() == 0) { if (request->status.is_ok()) { Shutdown(logger_->MakeException("Null or empty decoder buffer.", - media::StatusCode::kDecoderFailedDecode)); + media::DecoderStatus::Codes::kFailed)); } else { Shutdown(logger_->MakeException("Decoder error.", request->status)); } @@ -565,7 +563,7 @@ } template <typename Traits> -void DecoderTemplate<Traits>::OnFlushDone(media::Status status) { +void DecoderTemplate<Traits>::OnFlushDone(media::DecoderStatus status) { DVLOG(3) << __func__; if (IsClosed()) return; @@ -608,7 +606,7 @@ } template <typename Traits> -void DecoderTemplate<Traits>::OnInitializeDone(media::Status status) { +void DecoderTemplate<Traits>::OnInitializeDone(media::DecoderStatus status) { DVLOG(3) << __func__; if (IsClosed()) return; @@ -622,7 +620,8 @@ std::string error_message; if (is_flush) { error_message = "Error during initialize after flush."; - } else if (status.code() == media::StatusCode::kDecoderUnsupportedConfig) { + } else if (status.code() == + media::DecoderStatus::Codes::kUnsupportedConfig) { error_message = "Unsupported configuration. Check isConfigSupported() prior to " "calling configure()."; @@ -654,7 +653,8 @@ } template <typename Traits> -void DecoderTemplate<Traits>::OnDecodeDone(uint32_t id, media::Status status) { +void DecoderTemplate<Traits>::OnDecodeDone(uint32_t id, + media::DecoderStatus status) { DVLOG(3) << __func__; if (IsClosed()) return; @@ -666,8 +666,9 @@ pending_decodes_.erase(it); } - if (!status.is_ok() && status.code() != media::StatusCode::kAborted) { - Shutdown(logger_->MakeException("Decoding error.", status)); + if (!status.is_ok() && + status.code() != media::DecoderStatus::Codes::kAborted) { + Shutdown(logger_->MakeException("Decoding error.", std::move(status))); return; }
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.h b/third_party/blink/renderer/modules/webcodecs/decoder_template.h index f7350558e..4c310db 100644 --- a/third_party/blink/renderer/modules/webcodecs/decoder_template.h +++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.h
@@ -8,9 +8,8 @@ #include <stdint.h> #include <memory> -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/media_log.h" -#include "media/base/status.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -108,7 +107,7 @@ // When |verify_key_frame| is true, clients are expected to verify and set the // DecoderBuffer::is_key_frame() value. I.e., they must process the encoded // data to ensure the value is actually what the chunk says it is. - virtual media::StatusOr<scoped_refptr<media::DecoderBuffer>> + virtual media::DecoderStatus::Or<scoped_refptr<media::DecoderBuffer>> MakeDecoderBuffer(const InputType& chunk, bool verify_key_frame) = 0; private: @@ -146,7 +145,7 @@ Member<ScriptPromiseResolver> resolver; // For reporting an error at the time when a request is processed. - media::Status status; + media::DecoderStatus status; // The value of |reset_generation_| at the time of this request. Used to // abort pending requests following a reset(). @@ -173,9 +172,9 @@ void Shutdown(DOMException* ex = nullptr); // Called by |decoder_|. - void OnInitializeDone(media::Status status); - void OnDecodeDone(uint32_t id, media::Status); - void OnFlushDone(media::Status); + void OnInitializeDone(media::DecoderStatus status); + void OnDecodeDone(uint32_t id, media::DecoderStatus); + void OnFlushDone(media::DecoderStatus); void OnResetDone(); void OnOutput(uint32_t reset_generation, scoped_refptr<MediaOutputType>); @@ -204,7 +203,7 @@ // Could be a configure, flush, or reset. Decodes go in |pending_decodes_|. Member<Request> pending_request_; - std::unique_ptr<CodecLogger<media::Status>> logger_; + std::unique_ptr<CodecLogger<media::DecoderStatus>> logger_; // Empty - GPU factories haven't been retrieved yet. // nullptr - We tried to get GPU factories, but acceleration is unavailable.
diff --git a/third_party/blink/renderer/modules/webcodecs/reclaimable_codec.cc b/third_party/blink/renderer/modules/webcodecs/reclaimable_codec.cc index a73e171c..cf73380 100644 --- a/third_party/blink/renderer/modules/webcodecs/reclaimable_codec.cc +++ b/third_party/blink/renderer/modules/webcodecs/reclaimable_codec.cc
@@ -8,7 +8,9 @@ #include "base/location.h" #include "base/time/default_tick_clock.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -31,7 +33,9 @@ if (base::FeatureList::IsEnabled(kOnlyReclaimBackgroundWebCodecs)) { // Do this last, it will immediately re-enter via OnLifecycleStateChanged(). observer_handle_ = context->GetScheduler()->AddLifecycleObserver( - FrameOrWorkerScheduler::ObserverType::kWorkerScheduler, this); + FrameOrWorkerScheduler::ObserverType::kWorkerScheduler, + WTF::BindRepeating(&ReclaimableCodec::OnLifecycleStateChanged, + WrapWeakPersistent(this))); } else { // Pretend we're always in the background to _always_ reclaim. is_backgrounded_ = true;
diff --git a/third_party/blink/renderer/modules/webcodecs/reclaimable_codec.h b/third_party/blink/renderer/modules/webcodecs/reclaimable_codec.h index 4057372..4ec8682 100644 --- a/third_party/blink/renderer/modules/webcodecs/reclaimable_codec.h +++ b/third_party/blink/renderer/modules/webcodecs/reclaimable_codec.h
@@ -25,9 +25,7 @@ extern const MODULES_EXPORT base::Feature kReclaimInactiveWebCodecs; extern const MODULES_EXPORT base::Feature kOnlyReclaimBackgroundWebCodecs; -class MODULES_EXPORT ReclaimableCodec - : public GarbageCollectedMixin, - public FrameOrWorkerScheduler::Observer { +class MODULES_EXPORT ReclaimableCodec : public GarbageCollectedMixin { public: explicit ReclaimableCodec(ExecutionContext*); @@ -56,7 +54,7 @@ // Notified when throttling state is changed. May be called consecutively // with the same value. - void OnLifecycleStateChanged(scheduler::SchedulingLifecycleState) override; + void OnLifecycleStateChanged(scheduler::SchedulingLifecycleState); protected: // Pushes back the time at which |this| can be reclaimed due to inactivity.
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc index 0540e604..85a6f5d 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
@@ -295,9 +295,9 @@ } // static -media::StatusOr<VideoDecoderTraits::OutputType*> VideoDecoderTraits::MakeOutput( - scoped_refptr<MediaOutputType> output, - ExecutionContext* context) { +media::DecoderStatus::Or<VideoDecoderTraits::OutputType*> +VideoDecoderTraits::MakeOutput(scoped_refptr<MediaOutputType> output, + ExecutionContext* context) { return MakeGarbageCollected<VideoDecoderTraits::OutputType>(std::move(output), context); } @@ -518,7 +518,7 @@ return result; } -media::StatusOr<scoped_refptr<media::DecoderBuffer>> +media::DecoderStatus::Or<scoped_refptr<media::DecoderBuffer>> VideoDecoder::MakeDecoderBuffer(const InputType& chunk, bool verify_key_frame) { scoped_refptr<media::DecoderBuffer> decoder_buffer = chunk.buffer(); #if BUILDFLAG(USE_PROPRIETARY_CODECS) @@ -530,16 +530,18 @@ uint32_t output_size = h264_converter_->CalculateNeededOutputBufferSize( src, static_cast<uint32_t>(src_size), h264_avcc_.get()); if (!output_size) { - return media::Status(media::StatusCode::kH264ParsingError, - "Unable to determine size of bitstream buffer."); + return media::DecoderStatus( + media::DecoderStatus::Codes::kMalformedBitstream, + "Unable to determine size of bitstream buffer."); } std::vector<uint8_t> buf(output_size); if (!h264_converter_->ConvertNalUnitStreamToByteStream( src, static_cast<uint32_t>(src_size), h264_avcc_.get(), buf.data(), &output_size)) { - return media::Status(media::StatusCode::kH264ParsingError, - "Unable to convert NALU to byte stream."); + return media::DecoderStatus( + media::DecoderStatus::Codes::kMalformedBitstream, + "Unable to convert NALU to byte stream."); } decoder_buffer = media::DecoderBuffer::CopyFrom(buf.data(), output_size); @@ -559,8 +561,11 @@ ParseH264KeyFrame(*decoder_buffer, &is_key_frame); } - if (!is_key_frame) - return media::Status(media::StatusCode::kKeyFrameRequired); + if (!is_key_frame) { + return media::DecoderStatus( + media::DecoderStatus::Codes::kKeyFrameRequired, + "A key frame is required after configure() or flush()."); + } } return decoder_buffer;
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.h b/third_party/blink/renderer/modules/webcodecs/video_decoder.h index e31bfa3..ad0e1ee 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_decoder.h +++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.h
@@ -74,8 +74,9 @@ static void UpdateDecoderLog(const MediaDecoderType& decoder, const MediaConfigType& media_config, media::MediaLog* media_log); - static media::StatusOr<OutputType*> MakeOutput(scoped_refptr<MediaOutputType>, - ExecutionContext*); + static media::DecoderStatus::Or<OutputType*> MakeOutput( + scoped_refptr<MediaOutputType>, + ExecutionContext*); static const char* GetName(); }; @@ -112,9 +113,8 @@ CodecConfigEval MakeMediaConfig(const ConfigType& config, MediaConfigType* out_media_config, String* out_console_message) override; - media::StatusOr<scoped_refptr<media::DecoderBuffer>> MakeDecoderBuffer( - const InputType& input, - bool verify_key_frame) override; + media::DecoderStatus::Or<scoped_refptr<media::DecoderBuffer>> + MakeDecoderBuffer(const InputType& input, bool verify_key_frame) override; static ScriptPromise IsAcceleratedConfigSupported(ScriptState* script_state, const VideoDecoderConfig*,
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc index 9a2251e7..78a13abd 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc
@@ -11,8 +11,8 @@ #include "base/memory/weak_ptr.h" #include "build/buildflag.h" #include "media/base/decoder_factory.h" +#include "media/base/decoder_status.h" #include "media/base/media_util.h" -#include "media/base/status_codes.h" #include "media/base/video_decoder_config.h" #include "media/mojo/buildflags.h" #include "media/mojo/clients/mojo_decoder_factory.h" @@ -46,8 +46,8 @@ }; template <> -struct CrossThreadCopier<media::Status> - : public CrossThreadCopierPassThrough<media::Status> { +struct CrossThreadCopier<media::DecoderStatus> + : public CrossThreadCopierPassThrough<media::DecoderStatus> { STATIC_ONLY(CrossThreadCopier); }; @@ -68,10 +68,10 @@ class MediaVideoTaskWrapper { public: using CrossThreadOnceInitCB = - WTF::CrossThreadOnceFunction<void(media::Status status, + WTF::CrossThreadOnceFunction<void(media::DecoderStatus status, absl::optional<DecoderDetails>)>; using CrossThreadOnceDecodeCB = - WTF::CrossThreadOnceFunction<void(const media::Status&)>; + WTF::CrossThreadOnceFunction<void(const media::DecoderStatus&)>; using CrossThreadOnceResetCB = WTF::CrossThreadOnceClosure; MediaVideoTaskWrapper( @@ -148,7 +148,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!decoder_) { - OnDecodeDone(cb_id, media::DecodeStatus::DECODE_ERROR); + OnDecodeDone(cb_id, media::DecoderStatus::Codes::kNotInitialized); return; } @@ -254,14 +254,16 @@ decoder_ = std::move(decoder); - media::Status status(media::StatusCode::kDecoderUnsupportedConfig); - absl::optional<DecoderDetails> decoder_details; + media::DecoderStatus status = media::DecoderStatus::Codes::kOk; + absl::optional<DecoderDetails> decoder_details = absl::nullopt; + if (decoder_) { - status = media::OkStatus(); decoder_details = DecoderDetails({decoder_->GetDecoderType(), decoder_->IsPlatformDecoder(), decoder_->NeedsBitstreamConversion(), decoder_->GetMaxDecodeRequests()}); + } else { + status = media::DecoderStatus::Codes::kUnsupportedConfig; } // Fire |init_cb|. @@ -282,7 +284,7 @@ decoder_->CanReadWithoutStalling())); } - void OnDecodeDone(int cb_id, media::Status status) { + void OnDecodeDone(int cb_id, media::DecoderStatus status) { DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -407,7 +409,7 @@ return last_callback_id_; } -void VideoDecoderBroker::OnInitialize(media::Status status, +void VideoDecoderBroker::OnInitialize(media::DecoderStatus status, absl::optional<DecoderDetails> details) { DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -431,7 +433,7 @@ buffer, callback_id)); } -void VideoDecoderBroker::OnDecodeDone(int cb_id, media::Status status) { +void VideoDecoderBroker::OnDecodeDone(int cb_id, media::DecoderStatus status) { DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(pending_decode_cb_map_.Contains(cb_id));
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h index f53f3f2..0bf5d5c 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h +++ b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h
@@ -13,7 +13,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/video_decoder.h" #include "media/base/video_frame.h" #include "media/video/gpu_video_accelerator_factories.h" @@ -51,10 +51,10 @@ int max_decode_requests; }; - virtual void OnInitialize(media::Status status, + virtual void OnInitialize(media::DecoderStatus status, absl::optional<DecoderDetails> details) = 0; - virtual void OnDecodeDone(int cb_id, media::Status status) = 0; + virtual void OnDecodeDone(int cb_id, media::DecoderStatus status) = 0; virtual void OnDecodeOutput(scoped_refptr<media::VideoFrame> frame, bool can_read_without_stalling) = 0; @@ -110,9 +110,9 @@ int CreateCallbackId(); // MediaVideoTaskWrapper::CrossThreadVideoDecoderClient - void OnInitialize(media::Status status, + void OnInitialize(media::DecoderStatus status, absl::optional<DecoderDetails> details) override; - void OnDecodeDone(int cb_id, media::Status status) override; + void OnDecodeDone(int cb_id, media::DecoderStatus status) override; void OnDecodeOutput(scoped_refptr<media::VideoFrame> frame, bool can_read_without_stalling) override; void OnReset(int cb_id) override;
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc index 8a94e1a..5639d55 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc
@@ -10,8 +10,8 @@ #include "base/threading/thread.h" #include "build/build_config.h" #include "gpu/command_buffer/common/mailbox_holder.h" -#include "media/base/decode_status.h" #include "media/base/decoder_buffer.h" +#include "media/base/decoder_status.h" #include "media/base/media_switches.h" #include "media/base/media_util.h" #include "media/base/test_data_util.h" @@ -192,12 +192,13 @@ base::RepeatingCallback<void(mojo::ScopedMessagePipeHandle)>()); } - void OnInitWithClosure(base::RepeatingClosure done_cb, media::Status status) { + void OnInitWithClosure(base::RepeatingClosure done_cb, + media::DecoderStatus status) { OnInit(status); done_cb.Run(); } void OnDecodeDoneWithClosure(base::RepeatingClosure done_cb, - media::Status status) { + media::DecoderStatus status) { OnDecodeDone(std::move(status)); done_cb.Run(); } @@ -207,8 +208,8 @@ done_cb.Run(); } - MOCK_METHOD1(OnInit, void(media::Status status)); - MOCK_METHOD1(OnDecodeDone, void(media::Status)); + MOCK_METHOD1(OnInit, void(media::DecoderStatus status)); + MOCK_METHOD1(OnDecodeDone, void(media::DecoderStatus)); MOCK_METHOD0(OnResetDone, void()); void OnOutput(scoped_refptr<media::VideoFrame> frame) { @@ -260,10 +261,12 @@ bool expect_success = true) { base::RunLoop run_loop; if (expect_success) { - EXPECT_CALL(*this, OnInit(media::SameStatusCode(media::OkStatus()))); + EXPECT_CALL(*this, OnInit(media::SameStatusCode(media::DecoderStatus( + media::DecoderStatus::Codes::kOk)))); } else { - EXPECT_CALL(*this, OnInit(media::SameStatusCode(media::Status( - media::StatusCode::kDecoderUnsupportedConfig)))); + EXPECT_CALL(*this, + OnInit(media::SameStatusCode(media::DecoderStatus( + media::DecoderStatus::Codes::kUnsupportedConfig)))); } decoder_broker_->Initialize( config, false /*low_delay*/, nullptr /* cdm_context */, @@ -276,9 +279,9 @@ testing::Mock::VerifyAndClearExpectations(this); } - void DecodeBuffer( - scoped_refptr<media::DecoderBuffer> buffer, - media::StatusCode expected_status = media::StatusCode::kOk) { + void DecodeBuffer(scoped_refptr<media::DecoderBuffer> buffer, + media::DecoderStatus::Codes expected_status = + media::DecoderStatus::Codes::kOk) { base::RunLoop run_loop; EXPECT_CALL(*this, OnDecodeDone(HasStatusCode(expected_status))); decoder_broker_->Decode( @@ -334,9 +337,9 @@ // No call to Initialize. Other APIs should fail gracefully. DecodeBuffer(media::ReadTestDataFile("vp8-I-frame-320x120"), - media::DecodeStatus::DECODE_ERROR); + media::DecoderStatus::Codes::kNotInitialized); DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer(), - media::DecodeStatus::DECODE_ERROR); + media::DecoderStatus::Codes::kNotInitialized); ASSERT_EQ(0U, output_frames_.size()); ResetDecoder();
diff --git a/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc b/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc index d872f70..3f6416c 100644 --- a/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc +++ b/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc
@@ -15,7 +15,9 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_transport_error.h" +#include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/streams/promise_handler.h" #include "third_party/blink/renderer/core/streams/underlying_sink_base.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream_default_controller.h" @@ -32,6 +34,26 @@ namespace blink { +namespace { + +class SendStreamAbortAlgorithm final : public AbortSignal::Algorithm { + public: + explicit SendStreamAbortAlgorithm(OutgoingStream* stream) : stream_(stream) {} + ~SendStreamAbortAlgorithm() override = default; + + void Run() override { stream_->AbortAlgorithm(stream_); } + + void Trace(Visitor* visitor) const override { + visitor->Trace(stream_); + Algorithm::Trace(visitor); + } + + private: + Member<OutgoingStream> stream_; +}; + +} // namespace + class OutgoingStream::UnderlyingSink final : public UnderlyingSinkBase { public: explicit UnderlyingSink(OutgoingStream* outgoing_stream) @@ -73,6 +95,8 @@ outgoing_stream_->close_promise_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + outgoing_stream_->pending_operation_ = + outgoing_stream_->close_promise_resolver_; // In some cases (when the stream is aborted by a network error for // example), there may not be a call to OnOutgoingStreamClose. In that case @@ -173,12 +197,74 @@ stream->InitWithCountQueueingStrategy( script_state_, MakeGarbageCollected<UnderlyingSink>(this), 1, /*optimizer=*/nullptr, exception_state); + + controller_->signal()->AddAlgorithm( + MakeGarbageCollected<SendStreamAbortAlgorithm>(this)); +} + +void OutgoingStream::AbortAlgorithm(OutgoingStream* stream) { + // Step 6 of https://w3c.github.io/webtransport/#sendstream-create + // 1. If stream's [[PendingOperation]] is null, then abort these steps. + if (!stream->pending_operation_) { + return; + } + + // 2. Let reason be stream’s [[controller]]'s [[signal]]'s abort reason. + ScriptValue reason = stream->controller_->signal()->reason(script_state_); + + // 3. Let abortPromise be the result of aborting stream with reason. + // ASSERT_NO_EXCEPTION is used as OutgoingStream::UnderlyingSink::abort() + // does not throw an exception, and hence a proper ExceptionState does not + // have to be passed since it is not used. + auto* underlying_sink = MakeGarbageCollected<UnderlyingSink>(stream); + ScriptPromise abort_promise = + underlying_sink->abort(script_state_, reason, ASSERT_NO_EXCEPTION); + + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state_); + class ResolveFunction final : public PromiseHandler { + // 4. Upon fulfillment of abortPromise, + public: + explicit ResolveFunction(ScriptValue reason, + ScriptPromiseResolver* resolver) + : reason_(reason), resolver_(resolver) {} + + void CallWithLocal(ScriptState*, v8::Local<v8::Value>) override { + // reject promise with reason. + resolver_->Reject(reason_); + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(reason_); + visitor->Trace(resolver_); + PromiseHandler::Trace(visitor); + } + + private: + ScriptValue reason_; + Member<ScriptPromiseResolver> resolver_; + }; + + StreamThenPromise(script_state_->GetContext(), abort_promise.V8Promise(), + MakeGarbageCollected<NewScriptFunction>( + script_state_, MakeGarbageCollected<ResolveFunction>( + reason, resolver))); + + // 5. Let pendingOperation be stream’s [[PendingOperation]]. + ScriptPromiseResolver* pending_operation = stream->pending_operation_; + + // 6. Set stream’s [[PendingOperation]] to null. + stream->pending_operation_ = nullptr; + + // 7. Resolve pendingOperation with promise. + pending_operation->Resolve(resolver->Promise()); } void OutgoingStream::OnOutgoingStreamClosed() { DVLOG(1) << "OutgoingStream::OnOutgoingStreamClosed() this=" << this; DCHECK(close_promise_resolver_); + pending_operation_ = nullptr; close_promise_resolver_->Resolve(); close_promise_resolver_ = nullptr; } @@ -202,6 +288,7 @@ visitor->Trace(controller_); visitor->Trace(write_promise_resolver_); visitor->Trace(close_promise_resolver_); + visitor->Trace(pending_operation_); } void OutgoingStream::OnHandleReady(MojoResult result, @@ -292,6 +379,7 @@ write_watcher_.ArmOrNotify(); write_promise_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + pending_operation_ = write_promise_resolver_; return write_promise_resolver_->Promise(); } @@ -311,6 +399,7 @@ cached_data_.reset(); offset_ = 0; + pending_operation_ = nullptr; write_promise_resolver_->Resolve(); write_promise_resolver_ = nullptr; return;
diff --git a/third_party/blink/renderer/modules/webtransport/outgoing_stream.h b/third_party/blink/renderer/modules/webtransport/outgoing_stream.h index 593432a..9fb27b6 100644 --- a/third_party/blink/renderer/modules/webtransport/outgoing_stream.h +++ b/third_party/blink/renderer/modules/webtransport/outgoing_stream.h
@@ -65,6 +65,8 @@ void InitWithExistingWritableStream(WritableStream*, ExceptionState&); + void AbortAlgorithm(OutgoingStream*); + // Implementation of OutgoingStream IDL, used by client classes to implement // it. https://wicg.github.io/web-transport/#outgoing-stream WritableStream* Writable() const { @@ -187,6 +189,8 @@ // non-null. Member<ScriptPromiseResolver> close_promise_resolver_; + Member<ScriptPromiseResolver> pending_operation_; + State state_ = State::kOpen; };
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc index af1e87d..6c902ea 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -1341,7 +1341,7 @@ auto scroll_a = CreateScroll(ScrollPaintPropertyNode::Root(), ScrollState1(), kNotScrollingOnMain, scroll_element_id_a); auto scroll_translation_a = CreateScrollTranslation( - t0(), 11, 13, *scroll_a, CompositingReason::kLayerForScrollingContents); + t0(), 11, 13, *scroll_a, CompositingReason::kOverflowScrolling); CompositorElementId scroll_element_id_b = ScrollElementId(3); auto scroll_b = @@ -1948,7 +1948,7 @@ TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleMask) { auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -1982,12 +1982,13 @@ TEST_P(PaintArtifactCompositorTest, CompositedMaskOneChild) { auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); masking_state.blend_mode = SkBlendMode::kDstIn; - masking_state.direct_compositing_reasons = CompositingReason::kLayerForMask; + masking_state.direct_compositing_reasons = + CompositingReason::kMaskWithCompositedDescendants; auto masking = EffectPaintPropertyNode::Create(*masked, std::move(masking_state)); @@ -2015,7 +2016,7 @@ TEST_P(PaintArtifactCompositorTest, CompositedMaskTwoChildren) { auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -2024,7 +2025,7 @@ EffectPaintPropertyNode::Create(*masked, std::move(masking_state)); auto child_of_masked = CreateOpacityEffect( - *masking, 1.0, CompositingReason::kIsolateCompositedDescendants); + *masking, 1.0, CompositingReason::kOpacityWithCompositedDescendants); TestPaintArtifact artifact; artifact.Chunk(t0(), c0(), *masked) @@ -2052,7 +2053,7 @@ TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleExoticBlendMode) { auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -2079,7 +2080,7 @@ TEST_P(PaintArtifactCompositorTest, ForcedCompositedExoticBlendMode) { auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); EffectPaintPropertyNode::State masking_state; masking_state.local_transform_space = &t0(); masking_state.output_clip = &c0(); @@ -2112,7 +2113,7 @@ TEST_P(PaintArtifactCompositorTest, CompositedExoticBlendModeOnTwoOpacityAnimationLayers) { auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); auto masked_child1 = CreateOpacityEffect( *masked, 1.0, CompositingReason::kActiveOpacityAnimation); auto masked_child2 = CreateOpacityEffect( @@ -2150,7 +2151,7 @@ TEST_P(PaintArtifactCompositorTest, CompositedExoticBlendModeOnTwo3DTransformLayers) { auto masked = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); auto transform1 = CreateTransform(t0(), TransformationMatrix(), gfx::Point3F(), CompositingReason::k3DTransform); @@ -2189,7 +2190,7 @@ TEST_P(PaintArtifactCompositorTest, DecompositeExoticBlendModeWithoutBackdrop) { auto parent_effect = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); EffectPaintPropertyNode::State blend_state1; blend_state1.local_transform_space = &t0(); blend_state1.blend_mode = SkBlendMode::kScreen; @@ -2220,7 +2221,7 @@ TEST_P(PaintArtifactCompositorTest, DecompositeExoticBlendModeWithNonDrawingLayer) { auto parent_effect = CreateOpacityEffect( - e0(), 1.0, CompositingReason::kIsolateCompositedDescendants); + e0(), 1.0, CompositingReason::kOpacityWithCompositedDescendants); EffectPaintPropertyNode::State blend_state1; blend_state1.local_transform_space = &t0(); blend_state1.blend_mode = SkBlendMode::kScreen;
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc index 31781d6f..09d093b 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -27,7 +27,6 @@ "promoted to a layer based on a performance heuristic."}, {CompositingReason::kPlugin, "plugin", "Is an accelerated plugin"}, {CompositingReason::kIFrame, "iFrame", "Is an accelerated iFrame"}, - {CompositingReason::kSVGRoot, "SVGRoot", "Is an accelerated SVG root"}, {CompositingReason::kBackfaceVisibilityHidden, "backfaceVisibilityHidden", "Has backface-visibility: hidden"}, {CompositingReason::kActiveTransformAnimation, "activeTransformAnimation", @@ -39,17 +38,11 @@ {CompositingReason::kActiveBackdropFilterAnimation, "activeBackdropFilterAnimation", "Has an active accelerated backdrop filter animation or transition"}, - {CompositingReason::kXrOverlay, "xrOverlay", - "Is DOM overlay for WebXR immersive-ar mode"}, {CompositingReason::kFixedPosition, "fixedPosition", "Is fixed position"}, {CompositingReason::kStickyPosition, "stickyPosition", "Is sticky position"}, {CompositingReason::kOverflowScrolling, "overflowScrolling", "Is a scrollable overflow element"}, - {CompositingReason::kOutOfFlowClipping, "outOfFlowClipping", - "Has clipping ancestor"}, - {CompositingReason::kVideoOverlay, "videoOverlay", - "Is overlay controls for video"}, {CompositingReason::kWillChangeTransform, "willChangeTransform", "Has a will-change: transform compositing hint"}, {CompositingReason::kWillChangeOpacity, "willChangeOpacity", @@ -66,12 +59,8 @@ "Is a mask for backdrop filter"}, {CompositingReason::kRootScroller, "rootScroller", "Is the document.rootScroller"}, - {CompositingReason::kAssumedOverlap, "assumedOverlap", - "Might overlap other composited content"}, {CompositingReason::kOverlap, "overlap", "Overlaps other composited content"}, - {CompositingReason::kNegativeZIndexChildren, "negativeZIndexChildren", - "Parent with composited negative z-index content"}, {CompositingReason::kOpacityWithCompositedDescendants, "opacityWithCompositedDescendants", "Has opacity that needs to be applied by compositor because of composited " @@ -80,10 +69,6 @@ "maskWithCompositedDescendants", "Has a mask that needs to be known by compositor because of composited " "descendants"}, - {CompositingReason::kReflectionWithCompositedDescendants, - "reflectionWithCompositedDescendants", - "Has a reflection that needs to be known by compositor because of " - "composited descendants"}, {CompositingReason::kFilterWithCompositedDescendants, "filterWithCompositedDescendants", "Has a filter effect that needs to be known by compositor because of " @@ -100,31 +85,12 @@ "preserve3DWith3DDescendants", "Has a preserves-3d property that needs to be known by compositor because " "of 3d descendants"}, - {CompositingReason::kIsolateCompositedDescendants, - "isolateCompositedDescendants", - "Should isolate descendants to apply a blend effect"}, - {CompositingReason::kFullscreenVideoWithCompositedDescendants, - "fullscreenVideoWithCompositedDescendants", - "Is a fullscreen video element with composited descendants"}, {CompositingReason::kRoot, "root", "Is the root layer"}, {CompositingReason::kLayerForHorizontalScrollbar, "layerForHorizontalScrollbar", "Secondary layer, the horizontal scrollbar layer"}, {CompositingReason::kLayerForVerticalScrollbar, "layerForVerticalScrollbar", "Secondary layer, the vertical scrollbar layer"}, - {CompositingReason::kLayerForScrollCorner, "layerForScrollCorner", - "Secondary layer, the scroll corner layer"}, - {CompositingReason::kLayerForScrollingContents, "layerForScrollingContents", - "Secondary layer, to house contents that can be scrolled"}, - {CompositingReason::kLayerForSquashingContents, "layerForSquashingContents", - "Secondary layer, home for a group of squashable content"}, - {CompositingReason::kLayerForForeground, "layerForForeground", - "Secondary layer, to contain any normal flow and positive z-index " - "contents on top of a negative z-index layer"}, - {CompositingReason::kLayerForMask, "layerForMask", - "Secondary layer, to contain the mask contents"}, - {CompositingReason::kLayerForDecoration, "layerForDecoration", - "Layer painted on top of other layers as decoration"}, {CompositingReason::kLayerForOther, "layerForOther", "Layer for link highlight, frame overlay, etc."}, {CompositingReason::kBackfaceInvisibility3DAncestor,
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/third_party/blink/renderer/platform/graphics/compositing_reasons.h index 4cfec46..a14e3fde 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.h +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -24,8 +24,6 @@ V(Plugin) \ V(IFrame) \ V(DocumentTransitionContentElement) \ - /* This is used for pre-CompositAfterPaint + CompositeSVG only. */ \ - V(SVGRoot) \ V(BackfaceVisibilityHidden) \ V(ActiveTransformAnimation) \ V(ActiveOpacityAnimation) \ @@ -35,8 +33,6 @@ V(FixedPosition) \ V(StickyPosition) \ V(OverflowScrolling) \ - V(OutOfFlowClipping) \ - V(VideoOverlay) \ V(WillChangeTransform) \ V(WillChangeOpacity) \ V(WillChangeFilter) \ @@ -54,44 +50,30 @@ V(BackdropFilter) \ V(BackdropFilterMask) \ V(RootScroller) \ - V(XrOverlay) \ V(Viewport) \ \ - /* Overlap reasons that require knowing what's behind you in paint-order \ - before knowing the answer. */ \ - V(AssumedOverlap) \ + /* This is based on overlapping relationship among pending layers, \ + determined after paint. See PaintArtifactCompositor. */ \ V(Overlap) \ - V(NegativeZIndexChildren) \ \ /* Subtree reasons that require knowing what the status of your subtree is \ before knowing the answer. */ \ V(OpacityWithCompositedDescendants) \ V(MaskWithCompositedDescendants) \ - V(ReflectionWithCompositedDescendants) \ V(FilterWithCompositedDescendants) \ V(BlendingWithCompositedDescendants) \ V(PerspectiveWith3DDescendants) \ V(Preserve3DWith3DDescendants) \ - V(IsolateCompositedDescendants) \ - V(FullscreenVideoWithCompositedDescendants) \ \ /* The root layer is a special case. It may be forced to be a layer, but it \ also needs to be a layer if anything else in the subtree is composited. */ \ V(Root) \ \ - /* CompositedLayerMapping internal hierarchy reasons. Some of them are also \ - used in CompositeAfterPaint. */ \ V(LayerForHorizontalScrollbar) \ V(LayerForVerticalScrollbar) \ - V(LayerForScrollCorner) \ - V(LayerForScrollingContents) \ - V(LayerForSquashingContents) \ - V(LayerForForeground) \ - V(LayerForMask) \ - /* Composited layer painted on top of all other layers as decoration. */ \ - V(LayerForDecoration) \ /* Link highlight, frame overlay, etc. */ \ V(LayerForOther) \ + \ /* DocumentTransition shared element. \ See third_party/blink/renderer/core/document_transition/README.md. */ \ V(DocumentTransitionSharedElement) @@ -129,47 +111,11 @@ kComboActiveAnimation = kActiveTransformAnimation | kActiveOpacityAnimation | kActiveFilterAnimation | kActiveBackdropFilterAnimation, - - kComboAllDirectStyleDeterminedReasons = - k3DTransform | kTrivial3DTransform | kBackfaceVisibilityHidden | - kComboActiveAnimation | kWillChangeTransform | kWillChangeOpacity | - kWillChangeFilter | kWillChangeOther | kBackdropFilter | - kWillChangeBackdropFilter, - kComboScrollDependentPosition = kFixedPosition | kStickyPosition, - - kComboAllDirectNonStyleDeterminedReasons = - kVideo | kCanvas | kPlugin | kIFrame | kSVGRoot | kOutOfFlowClipping | - kVideoOverlay | kXrOverlay | kRoot | kRootScroller | - kComboScrollDependentPosition | kAffectedByOuterViewportBoundsDelta | - kBackfaceInvisibility3DAncestor | kTransform3DSceneLeaf | - kDocumentTransitionSharedElement | kDocumentTransitionContentElement, - - kComboAllDirectReasons = kComboAllDirectStyleDeterminedReasons | - kComboAllDirectNonStyleDeterminedReasons, - - kComboAllCompositedScrollingDeterminedReasons = - kComboScrollDependentPosition | kAffectedByOuterViewportBoundsDelta | - kOverflowScrolling, - - kComboCompositedDescendants = - kIsolateCompositedDescendants | kOpacityWithCompositedDescendants | - kMaskWithCompositedDescendants | kFilterWithCompositedDescendants | - kBlendingWithCompositedDescendants | - kReflectionWithCompositedDescendants, - - kCombo3DDescendants = - kPreserve3DWith3DDescendants | kPerspectiveWith3DDescendants, - - kComboAllStyleDeterminedReasons = kComboAllDirectStyleDeterminedReasons | - kComboCompositedDescendants | - kCombo3DDescendants, - kPreventingSubpixelAccumulationReasons = kWillChangeTransform, - kDirectReasonsForPaintOffsetTranslationProperty = kComboScrollDependentPosition | kAffectedByOuterViewportBoundsDelta | - kVideo | kCanvas | kPlugin | kIFrame | kSVGRoot, + kVideo | kCanvas | kPlugin | kIFrame, kDirectReasonsForTransformProperty = k3DTransform | kTrivial3DTransform | kWillChangeTransform | kWillChangeOther | kPerspectiveWith3DDescendants |
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc index 1261130..ea79b44 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
@@ -16,6 +16,7 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/loader/fetch/console_logger.h" #include "third_party/blink/renderer/platform/loader/fetch/loading_behavior_observer.h" @@ -23,6 +24,7 @@ #include "third_party/blink/renderer/platform/network/network_state_notifier.h" #include "third_party/blink/renderer/platform/scheduler/public/aggregated_metric_reporter.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_status.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -104,7 +106,9 @@ kTightLimitForRendererSideResourceScheduler); scheduler_observer_handle_ = frame_or_worker_scheduler->AddLifecycleObserver( - FrameScheduler::ObserverType::kLoader, this); + FrameScheduler::ObserverType::kLoader, + WTF::BindRepeating(&ResourceLoadScheduler::OnLifecycleStateChanged, + WrapWeakPersistent(this))); } ResourceLoadScheduler::~ResourceLoadScheduler() = default;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h index a68a78e..84b56d6 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
@@ -91,8 +91,7 @@ // and the milestones being experimented with are first paint and first // contentful paint so far. class PLATFORM_EXPORT ResourceLoadScheduler final - : public GarbageCollected<ResourceLoadScheduler>, - public FrameOrWorkerScheduler::Observer { + : public GarbageCollected<ResourceLoadScheduler> { public: // An option to use in calling Request(). If kCanNotBeStoppedOrThrottled is // specified, the request should be granted and Run() should be called @@ -180,7 +179,7 @@ LoadingBehaviorObserver* loading_behavior_observer); ResourceLoadScheduler(const ResourceLoadScheduler&) = delete; ResourceLoadScheduler& operator=(const ResourceLoadScheduler&) = delete; - ~ResourceLoadScheduler() override; + ~ResourceLoadScheduler(); void Trace(Visitor*) const; @@ -225,8 +224,8 @@ } void SetOutstandingLimitForTesting(size_t tight_limit, size_t normal_limit); - // FrameOrWorkerScheduler::Observer overrides: - void OnLifecycleStateChanged(scheduler::SchedulingLifecycleState) override; + // FrameOrWorkerScheduler lifecycle observer callback. + void OnLifecycleStateChanged(scheduler::SchedulingLifecycleState); // The caller is the owner of the |clock|. The |clock| must outlive the // ResourceLoadScheduler.
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc index 6a9f0c6..0bc3ee2 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
@@ -478,7 +478,7 @@ // static void RTCVideoDecoderAdapter::OnInitializeDone(base::OnceCallback<void(bool)> cb, - media::Status status) { + media::DecoderStatus status) { std::move(cb).Run(status.is_ok()); } @@ -512,13 +512,15 @@ } } -void RTCVideoDecoderAdapter::OnDecodeDone(media::Status status) { - DVLOG(3) << __func__ << "(" << status.code() << ")"; +void RTCVideoDecoderAdapter::OnDecodeDone(media::DecoderStatus status) { + DVLOG(3) << __func__ << "(" << status.group() << ":" + << static_cast<int>(status.code()) << ")"; DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_); outstanding_decode_requests_--; - if (!status.is_ok() && status.code() != media::StatusCode::kAborted) { + if (!status.is_ok() && + status.code() != media::DecoderStatus::Codes::kAborted) { DVLOG(2) << "Entering permanent error state"; base::UmaHistogramSparse("Media.RTCVideoDecoderError", static_cast<int>(status.code())); @@ -635,7 +637,7 @@ media::DecoderBuffer::CreateEOSBuffer(), WTF::Bind( [](FlushDoneCB flush_success, FlushDoneCB flush_fail, - media::Status status) { + media::DecoderStatus status) { if (status.is_ok()) std::move(flush_success).Run(); else
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h index 9d1c68a..1a4a561 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h
@@ -14,7 +14,7 @@ #include "base/sequence_checker.h" #include "base/synchronization/lock.h" #include "build/build_config.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/status.h" #include "media/base/supported_video_decoder_config.h" #include "media/base/video_codecs.h" @@ -123,9 +123,9 @@ void InitializeOnMediaThread(const media::VideoDecoderConfig& config, InitCB init_cb); static void OnInitializeDone(base::OnceCallback<void(bool)> cb, - media::Status status); + media::DecoderStatus status); void DecodeOnMediaThread(); - void OnDecodeDone(media::Status status); + void OnDecodeDone(media::DecoderStatus status); void OnOutput(scoped_refptr<media::VideoFrame> frame); bool ShouldReinitializeForSettingHDRColorSpace(
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc index 4567a4e..667a7aa 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
@@ -20,7 +20,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "gpu/command_buffer/common/mailbox.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/media_switches.h" #include "media/base/media_util.h" #include "media/base/video_decoder.h" @@ -183,12 +183,11 @@ bool CreateAndInitialize(bool init_cb_result = true) { EXPECT_CALL(*video_decoder_, Initialize_(_, _, _, _, _, _)) - .WillOnce(DoAll( - SaveArg<0>(&vda_config_), SaveArg<4>(&output_cb_), - base::test::RunOnceCallback<3>( - init_cb_result - ? media::OkStatus() - : media::Status(media::StatusCode::kCodeOnlyForTesting)))); + .WillOnce( + DoAll(SaveArg<0>(&vda_config_), SaveArg<4>(&output_cb_), + base::test::RunOnceCallback<3>( + init_cb_result ? media::DecoderStatus::Codes::kOk + : media::DecoderStatus::Codes::kFailed))); rtc_video_decoder_adapter_ = RTCVideoDecoderAdapter::Create(&gpu_factories_, sdp_format_); return !!rtc_video_decoder_adapter_; @@ -314,7 +313,8 @@ ASSERT_TRUE(BasicSetup()); EXPECT_CALL(*video_decoder_, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); ASSERT_EQ(Decode(0), WEBRTC_VIDEO_CODEC_OK); @@ -328,7 +328,7 @@ EXPECT_CALL(*video_decoder_, Decode_(_, _)) .WillOnce( - base::test::RunOnceCallback<1>(media::DecodeStatus::DECODE_ERROR)); + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kFailed)); ASSERT_EQ(Decode(0), WEBRTC_VIDEO_CODEC_OK); media_thread_.FlushForTesting(); @@ -383,13 +383,15 @@ // Decode() is expected to be called for EOS flush as well. EXPECT_CALL(*video_decoder_, Decode_(_, _)) .Times(3) - .WillRepeatedly(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillRepeatedly( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); EXPECT_CALL(decoded_cb_, Run(_)).Times(2); // First Decode() should cause a reinitialize as new color space is given. EXPECT_CALL(*video_decoder_, Initialize_(_, _, _, _, _, _)) - .WillOnce(DoAll(SaveArg<0>(&vda_config_), - base::test::RunOnceCallback<3>(media::OkStatus()))); + .WillOnce(DoAll( + SaveArg<0>(&vda_config_), + base::test::RunOnceCallback<3>(media::DecoderStatus::Codes::kOk))); webrtc::EncodedImage first_input_image = GetEncodedImageWithColorSpace(0); ASSERT_EQ(rtc_video_decoder_adapter_->Decode(first_input_image, false, 0), WEBRTC_VIDEO_CODEC_OK); @@ -417,12 +419,13 @@ // Decode() is expected to be called for EOS flush as well. EXPECT_CALL(*video_decoder_, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); // Set Initialize() to fail. EXPECT_CALL(*video_decoder_, Initialize_(_, _, _, _, _, _)) - .WillOnce(base::test::RunOnceCallback<3>( - media::Status(media::StatusCode::kCodeOnlyForTesting))); + .WillOnce( + base::test::RunOnceCallback<3>(media::DecoderStatus::Codes::kFailed)); ASSERT_EQ(rtc_video_decoder_adapter_->Decode(input_image, false, 0), WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE); } @@ -438,7 +441,8 @@ // Decode() is expected to be called for EOS flush, set to fail. EXPECT_CALL(*video_decoder_, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::ABORTED)); + .WillOnce(base::test::RunOnceCallback<1>( + media::DecoderStatus::Codes::kAborted)); ASSERT_EQ(rtc_video_decoder_adapter_->Decode(input_image, false, 0), WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE); } @@ -454,7 +458,8 @@ // The first decode should increment the count. EXPECT_CALL(*video_decoder_, Decode_) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); EXPECT_EQ(Decode(0), WEBRTC_VIDEO_CODEC_OK); EXPECT_EQ(RTCVideoDecoderAdapter::GetCurrentDecoderCountForTesting(), 1); @@ -525,7 +530,8 @@ // The first decode should increment the count and succeed. EXPECT_CALL(*video_decoder_, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); EXPECT_EQ(Decode(0), WEBRTC_VIDEO_CODEC_OK); EXPECT_EQ(RTCVideoDecoderAdapter::GetCurrentDecoderCountForTesting(), RTCVideoDecoderAdapter::kMaxDecoderInstances + 1); @@ -541,7 +547,8 @@ SetSpatialIndex(2); video_decoder_->SetDecoderType(media::VideoDecoderType::kD3D11); EXPECT_CALL(*video_decoder_, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); ASSERT_EQ(Decode(0), WEBRTC_VIDEO_CODEC_OK);
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc index c50a5f3..88335c6 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.cc
@@ -825,9 +825,9 @@ pending_read_ = false; switch (result.code()) { - case media::StatusCode::kOk: + case media::DecoderStatus::Codes::kOk: break; - case media::StatusCode::kAborted: + case media::DecoderStatus::Codes::kAborted: // We're doing a Reset(), so just ignore it and keep going. return; default:
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.h b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.h index 068735b..50200bf 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.h +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter.h
@@ -14,7 +14,7 @@ #include "base/metrics/single_sample_metrics.h" #include "base/sequence_checker.h" #include "base/synchronization/lock.h" -#include "media/base/decode_status.h" +#include "media/base/decoder_status.h" #include "media/base/media_switches.h" #include "media/base/overlay_info.h" #include "media/base/status.h"
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc index a815b27..f12a73e 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc
@@ -21,8 +21,8 @@ #include "base/time/time.h" #include "build/build_config.h" #include "gpu/command_buffer/common/mailbox.h" -#include "media/base/decode_status.h" #include "media/base/decoder_factory.h" +#include "media/base/decoder_status.h" #include "media/base/media_util.h" #include "media/base/video_decoder.h" #include "media/base/video_decoder_config.h" @@ -253,12 +253,11 @@ void SetUpMockDecoder(MockVideoDecoder* decoder, bool init_cb_result) { EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _, _)) - .WillOnce(DoAll( - SaveArg<0>(&vda_config_), SaveArg<4>(&output_cb_), - base::test::RunOnceCallback<3>( - init_cb_result - ? media::OkStatus() - : media::Status(media::StatusCode::kCodeOnlyForTesting)))); + .WillOnce( + DoAll(SaveArg<0>(&vda_config_), SaveArg<4>(&output_cb_), + base::test::RunOnceCallback<3>( + init_cb_result ? media::DecoderStatus::Codes::kOk + : media::DecoderStatus::Codes::kFailed))); } // Set up our decoder factory to provide a decoder that will succeed or fail @@ -452,7 +451,8 @@ auto* decoder = decoder_factory_->decoder(); EXPECT_TRUE(BasicSetup()); EXPECT_CALL(*decoder, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); EXPECT_EQ(Decode(0), WEBRTC_VIDEO_CODEC_OK); task_environment_.RunUntilIdle(); EXPECT_CALL(decoded_cb_, Run(_)); @@ -469,7 +469,8 @@ // All Decodes succeed immediately. The backup will come from the fact that // we won't run the media thread while sending decode requests in. EXPECT_CALL(*decoder, Decode_(_, _)) - .WillRepeatedly(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillRepeatedly( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); // At some point, `adapter_` should trigger a reset. EXPECT_CALL(*decoder, Reset_(_)).WillOnce(base::test::RunOnceCallback<0>()); @@ -516,7 +517,8 @@ // All Decodes succeed immediately. The backup will come from the fact that // we won't run the media thread while sending decode requests in. EXPECT_CALL(*decoder, Decode_(_, _)) - .WillRepeatedly(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillRepeatedly( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); // At some point, `adapter_` should trigger a reset, before it falls back. It // should not do so more than once, since we won't complete the reset. EXPECT_CALL(*decoder, Reset_(_)).WillOnce(base::test::RunOnceCallback<0>()); @@ -553,7 +555,8 @@ auto* decoder = decoder_factory_->decoder(); EXPECT_TRUE(BasicSetup()); EXPECT_CALL(*decoder, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); EXPECT_EQ(Decode(0), WEBRTC_VIDEO_CODEC_OK); task_environment_.RunUntilIdle(); // Should not be called. @@ -602,7 +605,8 @@ task_environment_.RunUntilIdle(); EXPECT_CALL(*correct_decoder, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); Decode(0); task_environment_.RunUntilIdle(); } @@ -615,7 +619,8 @@ decoder->SetDecoderType(media::VideoDecoderType::kD3D11); EXPECT_TRUE(BasicSetup()); EXPECT_CALL(*decoder, Decode_(_, _)) - .WillOnce(base::test::RunOnceCallback<1>(media::DecodeStatus::OK)); + .WillOnce( + base::test::RunOnceCallback<1>(media::DecoderStatus::Codes::kOk)); EXPECT_EQ(Decode(0, false), WEBRTC_VIDEO_CODEC_OK); task_environment_.RunUntilIdle(); EXPECT_CALL(decoded_cb_, Run(_));
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 8801e295..afa60b3a 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -539,7 +539,7 @@ { // https://github.com/DevSDK/calc-infinity-and-NaN/blob/master/explainer.md name: "CSSCalcInfinityAndNaN", - status: "test", + status: "stable", }, { // https://drafts.csswg.org/css-cascade-5/#layering
diff --git a/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc index 66031c6..707f4dc6 100644 --- a/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc
@@ -4,16 +4,20 @@ #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" +#include <memory> +#include <utility> + +#include "base/callback.h" + namespace blink { FrameOrWorkerScheduler::LifecycleObserverHandle::LifecycleObserverHandle( - FrameOrWorkerScheduler* scheduler, - Observer* observer) - : scheduler_(scheduler->GetWeakPtr()), observer_(observer) {} + FrameOrWorkerScheduler* scheduler) + : scheduler_(scheduler->GetWeakPtr()) {} FrameOrWorkerScheduler::LifecycleObserverHandle::~LifecycleObserverHandle() { if (scheduler_) - scheduler_->RemoveLifecycleObserver(observer_); + scheduler_->RemoveLifecycleObserver(this); } FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle:: @@ -65,25 +69,28 @@ } std::unique_ptr<FrameOrWorkerScheduler::LifecycleObserverHandle> -FrameOrWorkerScheduler::AddLifecycleObserver(ObserverType type, - Observer* observer) { - DCHECK(observer); - observer->OnLifecycleStateChanged(CalculateLifecycleState(type)); - lifecycle_observers_.Set(observer, type); - return std::make_unique<LifecycleObserverHandle>(this, observer); +FrameOrWorkerScheduler::AddLifecycleObserver( + ObserverType type, + OnLifecycleStateChangedCallback callback) { + callback.Run(CalculateLifecycleState(type)); + auto handle = std::make_unique<LifecycleObserverHandle>(this); + lifecycle_observers_.Set( + handle.get(), std::make_unique<ObserverState>(type, std::move(callback))); + return handle; } -void FrameOrWorkerScheduler::RemoveLifecycleObserver(Observer* observer) { - DCHECK(observer); - const auto found = lifecycle_observers_.find(observer); +void FrameOrWorkerScheduler::RemoveLifecycleObserver( + LifecycleObserverHandle* handle) { + DCHECK(handle); + const auto found = lifecycle_observers_.find(handle); DCHECK(lifecycle_observers_.end() != found); lifecycle_observers_.erase(found); } void FrameOrWorkerScheduler::NotifyLifecycleObservers() { for (const auto& observer : lifecycle_observers_) { - observer.key->OnLifecycleStateChanged( - CalculateLifecycleState(observer.value)); + observer.value->GetCallback().Run( + CalculateLifecycleState(observer.value->GetObserverType())); } } @@ -91,4 +98,11 @@ return weak_factory_.GetWeakPtr(); } +FrameOrWorkerScheduler::ObserverState::ObserverState( + FrameOrWorkerScheduler::ObserverType observer_type, + FrameOrWorkerScheduler::OnLifecycleStateChangedCallback callback) + : observer_type_(observer_type), callback_(callback) {} + +FrameOrWorkerScheduler::ObserverState::~ObserverState() = default; + } // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index 6505478..03a2b40 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -550,7 +550,7 @@ namespace { -class MockLifecycleObserver final : public FrameScheduler::Observer { +class MockLifecycleObserver { public: MockLifecycleObserver() : not_throttled_count_(0u), @@ -570,7 +570,7 @@ EXPECT_EQ(stopped_count_expectation, stopped_count_) << from.ToString(); } - void OnLifecycleStateChanged(SchedulingLifecycleState state) override { + void OnLifecycleStateChanged(SchedulingLifecycleState state) { switch (state) { case SchedulingLifecycleState::kNotThrottled: not_throttled_count_++; @@ -588,6 +588,11 @@ } } + FrameOrWorkerScheduler::OnLifecycleStateChangedCallback GetCallback() { + return base::BindRepeating(&MockLifecycleObserver::OnLifecycleStateChanged, + base::Unretained(this)); + } + private: size_t not_throttled_count_; size_t hidden_count_; @@ -1102,7 +1107,7 @@ EXPECT_EQ(2, counter); } -// Tests if throttling observer interfaces work. +// Tests if throttling observer callbacks work. TEST_F(FrameSchedulerImplTest, LifecycleObserver) { std::unique_ptr<MockLifecycleObserver> observer = std::make_unique<MockLifecycleObserver>(); @@ -1116,7 +1121,7 @@ throttled_count, stopped_count); auto observer_handle = frame_scheduler_->AddLifecycleObserver( - FrameScheduler::ObserverType::kLoader, observer.get()); + FrameScheduler::ObserverType::kLoader, observer->GetCallback()); // Initial state should be synchronously notified here. // We assume kNotThrottled is notified as an initial state, but it could @@ -1215,10 +1220,11 @@ // Adding the observers should recieve a non-throttled response auto loader_observer_handle = frame_scheduler_->AddLifecycleObserver( - FrameScheduler::ObserverType::kLoader, loader_observer.get()); + FrameScheduler::ObserverType::kLoader, loader_observer->GetCallback()); auto worker_observer_handle = frame_scheduler_->AddLifecycleObserver( - FrameScheduler::ObserverType::kWorkerScheduler, worker_observer.get()); + FrameScheduler::ObserverType::kWorkerScheduler, + worker_observer->GetCallback()); loader_observer->CheckObserverState( FROM_HERE, ++loader_not_throttled_count, loader_hidden_count, @@ -1245,7 +1251,7 @@ auto loader_observer_added_after_stopped_handle = frame_scheduler_->AddLifecycleObserver( FrameScheduler::ObserverType::kLoader, - loader_observer_added_after_stopped.get()); + loader_observer_added_after_stopped->GetCallback()); // This observer should see stopped when added. loader_observer_added_after_stopped->CheckObserverState(FROM_HERE, 0, 0, 0, 1u);
diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h index c04c69c..8232974e 100644 --- a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_ +#include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/types/strong_alias.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -26,30 +27,21 @@ // Observer type that regulates conditions to invoke callbacks. enum class ObserverType { kLoader, kWorkerScheduler }; - // Observer interface to receive scheduling policy change events. - class Observer { - public: - virtual ~Observer() = default; - - // Notified when throttling state is changed. May be called consecutively - // with the same value. - virtual void OnLifecycleStateChanged( - scheduler::SchedulingLifecycleState) = 0; - }; + // Callback type for receiving scheduling policy change events. + using OnLifecycleStateChangedCallback = + base::RepeatingCallback<void(scheduler::SchedulingLifecycleState)>; class PLATFORM_EXPORT LifecycleObserverHandle { USING_FAST_MALLOC(LifecycleObserverHandle); public: - LifecycleObserverHandle(FrameOrWorkerScheduler* scheduler, - Observer* observer); + explicit LifecycleObserverHandle(FrameOrWorkerScheduler* scheduler); LifecycleObserverHandle(const LifecycleObserverHandle&) = delete; LifecycleObserverHandle& operator=(const LifecycleObserverHandle&) = delete; ~LifecycleObserverHandle(); private: base::WeakPtr<FrameOrWorkerScheduler> scheduler_; - Observer* observer_; }; // RAII handle which should be kept alive as long as the feature is active @@ -120,14 +112,21 @@ void RegisterStickyFeature(SchedulingPolicy::Feature feature, SchedulingPolicy policy); - // Adds an Observer instance to be notified on scheduling policy changed. - // When an Observer is added, the initial state will be notified synchronously - // through the Observer interface. - // A RAII handle is returned and observer is unregistered when the handle is - // destroyed. - std::unique_ptr<LifecycleObserverHandle> AddLifecycleObserver(ObserverType, - Observer*) - WARN_UNUSED_RESULT; + // Adds an observer callback to be notified on scheduling policy changed. + // When a callback is added, the initial state will be notified synchronously + // through the callback. The callback may be invoked consecutively with the + // same value. Returns a RAII handle that unregisters the callback when the + // handle is destroyed. + // + // New usage outside of platform/ should be rare. Prefer using + // ExecutionContextLifecycleStateObserver to observe paused and frozenness + // changes and PageVisibilityObserver to observe visibility changes. One + // exception is that this observer enables observing visibility changes of the + // associated page in workers, whereas PageVisibilityObserver does not + // (crbug.com/1286570). + std::unique_ptr<LifecycleObserverHandle> AddLifecycleObserver( + ObserverType, + OnLifecycleStateChangedCallback) WARN_UNUSED_RESULT; virtual std::unique_ptr<WebSchedulingTaskQueue> CreateWebSchedulingTaskQueue( WebSchedulingPriority) = 0; @@ -157,10 +156,25 @@ GetSchedulingAffectingFeatureWeakPtr() = 0; private: - void RemoveLifecycleObserver(Observer* observer); + class ObserverState { + public: + ObserverState(ObserverType, OnLifecycleStateChangedCallback); + ObserverState(const ObserverState&) = delete; + ObserverState& operator=(const ObserverState&) = delete; + ~ObserverState(); - // Observers are not owned by the scheduler. - HashMap<Observer*, ObserverType> lifecycle_observers_; + ObserverType GetObserverType() const { return observer_type_; } + OnLifecycleStateChangedCallback& GetCallback() { return callback_; } + + private: + ObserverType observer_type_; + OnLifecycleStateChangedCallback callback_; + }; + + void RemoveLifecycleObserver(LifecycleObserverHandle* handle); + + HashMap<LifecycleObserverHandle*, std::unique_ptr<ObserverState>> + lifecycle_observers_; base::WeakPtrFactory<FrameOrWorkerScheduler> weak_factory_{this}; };
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc index 3ff3afd..9d73ff8 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc
@@ -16,7 +16,9 @@ WorkerSchedulerProxy::WorkerSchedulerProxy(FrameOrWorkerScheduler* scheduler) { DCHECK(scheduler); throttling_observer_handle_ = scheduler->AddLifecycleObserver( - FrameOrWorkerScheduler::ObserverType::kWorkerScheduler, this); + FrameOrWorkerScheduler::ObserverType::kWorkerScheduler, + base::BindRepeating(&WorkerSchedulerProxy::OnLifecycleStateChanged, + base::Unretained(this))); if (FrameScheduler* frame_scheduler = scheduler->ToFrameScheduler()) { parent_frame_type_ = GetFrameOriginType(frame_scheduler); initial_frame_status_ = GetFrameStatus(frame_scheduler);
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h index fcd56d50..747af85 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h
@@ -29,19 +29,17 @@ // on the parent thread. It's passed to WorkerScheduler during its // construction. Given that DedicatedWorkerThread object outlives worker thread, // this class outlives worker thread too. -class PLATFORM_EXPORT WorkerSchedulerProxy - : public FrameOrWorkerScheduler::Observer { +class PLATFORM_EXPORT WorkerSchedulerProxy { public: explicit WorkerSchedulerProxy(FrameOrWorkerScheduler* scheduler); WorkerSchedulerProxy(const WorkerSchedulerProxy&) = delete; WorkerSchedulerProxy& operator=(const WorkerSchedulerProxy&) = delete; - ~WorkerSchedulerProxy() override; + ~WorkerSchedulerProxy(); void OnWorkerSchedulerCreated( base::WeakPtr<WorkerScheduler> worker_scheduler); - void OnLifecycleStateChanged( - SchedulingLifecycleState lifecycle_state) override; + void OnLifecycleStateChanged(SchedulingLifecycleState lifecycle_state); // Accessed only during init. SchedulingLifecycleState lifecycle_state() const {
diff --git a/third_party/blink/renderer/platform/wtf/OWNERS b/third_party/blink/renderer/platform/wtf/OWNERS index 9707fda..306cb4e7 100644 --- a/third_party/blink/renderer/platform/wtf/OWNERS +++ b/third_party/blink/renderer/platform/wtf/OWNERS
@@ -1,4 +1,3 @@ haraken@chromium.org thakis@chromium.org tkent@chromium.org -yutak@chromium.org
diff --git a/third_party/blink/web_tests/FlagExpectations/highdpi b/third_party/blink/web_tests/FlagExpectations/highdpi index f96ef02..e84955b 100644 --- a/third_party/blink/web_tests/FlagExpectations/highdpi +++ b/third_party/blink/web_tests/FlagExpectations/highdpi
@@ -1,57 +1,335 @@ # results: [ Timeout Crash Pass Failure Slow Skip ] -# Skip the following tests for high DPI test suite. -crypto/* [ Skip ] -css3/selectors3/* [ Skip ] -custom-elements/* [ Skip ] -custom-properties/* [ Skip ] -external/wpt/* [ Skip ] -gamepad/* [ Skip ] -harness-tests/* [ Skip ] -js/* [ Skip ] -media/* [ Skip ] -mhtml/* [ Skip ] -netinfo/* [ Skip ] -payments/* [ Skip ] -plugins/* [ Skip ] -scrollingcoordinator/* [ Skip ] -storage/* [ Skip ] -touchadjustment/* [ Skip ] -transitions/* [ Skip ] -traversal/* [ Skip ] -virtual/controls-refresh-hc/* [ Skip ] -virtual/dark-color-scheme/* [ Skip ] -virtual/exotic-color-space/* [ Skip ] -virtual/gpu/* [ Skip ] -virtual/gpu-rasterization/* [ Skip ] -virtual/prefer_compositing_to_lcd_text/* [ Skip ] -virtual/system-color-compute/* [ Skip ] -virtual/threaded/* [ Skip ] -virtual/threaded-prefer-compositing/* [ Skip ] -webaudio/* [ Skip ] -webexposed/* [ Skip ] -wpt_internal/* [ Skip ] +# Skip all tests for high DPI test suite unless specified below. +* [ Skip ] -# TODO(crbug.com/1168836):Enable the following for highdpi. -dark-mode/* [ Skip ] -dom/* [ Skip ] -fast/canvas/* [ Skip ] -fast/clip/* [ Skip ] -fast/css3-text/* [ Skip ] -fast/dom/* [ Skip ] -fast/dynamic/* [ Skip ] -fast/frames/* [ Skip ] -fast/invalid/* [ Skip ] -fast/multicol/* [ Skip ] -fast/scrolling/* [ Skip ] -fast/spatial-navigation/* [ Skip ] -fast/tokenizer/* [ Skip ] -fast/webgl/* [ Skip ] -fast/xsl/* [ Skip ] -scrollbars/* [ Skip ] -# TODO(crbug.com/1178099): Adding to skip list temporarily -# to get around the size of results file due to large number of failures. -tables/* [ Skip ] +# Tests to be run on Highdpi. Trying to restrict this list to ~3000. +# Only small number of tests are picked to run on HighDPI not to burden +# the CQ/CI resources. +animations/skew-notsequential-compositor.html [ Pass ] +animations/state-at-end-event.html [ Pass ] +animations/3d/matrix-transform-type-animation.html [ Pass ] +animations/composition/background-position-composition.html [ Pass ] +animations/composition/clip-composition.html [ Pass ] +animations/composition/font-size-composition.html [ Pass ] +animations/custom-properties/angle-type-interpolation.html [ Pass ] +animations/custom-properties/animate-high-priority.html [ Pass ] +animations/custom-properties/color-type-interpolation.html [ Pass ] +animations/direction-and-fill/animation-direction-normal.html [ Pass ] +animations/direction-and-fill/animation-direction-reverse-fill-mode.html [ Pass ] +animations/interpolation/border-interpolation.html [ Pass ] +animations/interpolation/clip-path-interpolation.html [ Pass ] +animations/interpolation/color-interpolation.html [ Pass ] +animations/responsive/responsive-neutral-keyframes.html [ Pass ] +animations/responsive/stacked-visibility-animations-responsive.html [ Pass ] +animations/responsive/zoom-responsive-transform-animation-001.html [ Pass ] +animations/responsive/interpolation/fill-responsive.html [ Pass ] +animations/responsive/interpolation/transform-responsive.html [ Pass ] +animations/stability/font-builder-crash.html [ Pass ] +animations/svg/animated-filter-svg-element.html [ Pass ] +animations/svg-attribute-composition/svg-amplitude-composition.html [ Pass ] +animations/svg-attribute-composition/svg-azimuth-composition.html [ Pass ] +animations/svg-attribute-composition/svg-baseFrequency-composition.html [ Pass ] +animations/svg-attribute-composition/svg-bias-composition.html [ Pass ] +animations/svg-attribute-interpolation/svg-edgeMode-interpolation.html [ Pass ] +animations/svg-attribute-interpolation/svg-elevation-interpolation.html [ Pass ] +animations/svg-attribute-interpolation/svg-exponent-interpolation.html [ Pass ] +animations/svg-attribute-interpolation/svg-viewBox-interpolation.html [ Pass ] +animations/web-animations/KeyframeEffect-animation.html [ Pass ] +compositing/3d-cube.html [ Pass ] +compositing/checkerboard.html [ Pass ] +compositing/absolute-inside-out-of-view-fixed.html [ Pass ] +compositing/backface-visibility-transformed.html [ Pass ] +compositing/compositing-visible-descendant.html [ Pass ] +compositing/fixed-background-composited-html.html [ Pass ] +compositing/perspective-origin-with-scrollbars.html [ Pass ] +compositing/preserve-3d-toggle.html [ Pass ] +compositing/render-surface-alpha-blending.html [ Pass ] +compositing/scroll-with-ancestor-clip.html [ Pass ] +compositing/scroll-with-inner-clip.html [ Pass ] +compositing/scrollbar-painting.html [ Pass ] +compositing/self-painting-layers.html [ Pass ] +compositing/text-on-scaled-layer.html [ Pass ] +compositing/text-on-scaled-surface.html [ Pass ] +compositing/tiled-layers-hidpi.html [ Pass ] +compositing/toggle-compositing.html [ Pass ] +compositing/transform-complex-page.html [ Pass ] +compositing/animation/animation-compositing.html [ Pass ] +compositing/animation/animations-establish-stacking-context.html [ Pass ] +compositing/backface-visibility/backface-visibility-3d.html [ Pass ] +compositing/backface-visibility/backface-visibility-image.html [ Pass ] +compositing/background-color/background-color-alpha.html [ Pass ] +compositing/background-color/background-color-change-to-text.html [ Pass ] +compositing/background-color/background-color-change-to-transparent.html [ Pass ] +compositing/background-color/background-color-container.html [ Pass ] +compositing/background-color/background-color-content-clip.html [ Pass ] +compositing/background-color/background-color-text-change.html [ Pass ] +compositing/background-color/background-color-text-clip.html [ Pass ] +compositing/background-color/view-blending-base-background.html [ Pass ] +compositing/backgrounds/fixed-backgrounds.html [ Pass ] +compositing/backgrounds/local-background.html [ Pass ] +compositing/contents-opaque/background-clip.html [ Pass ] +compositing/contents-opaque/background-color.html [ Pass ] +compositing/culling/filter-occlusion-alpha-large.html [ Pass ] +compositing/culling/filter-occlusion-alpha.html [ Pass ] +compositing/culling/filter-occlusion-blur-large.html [ Pass ] +compositing/filters/sw-layer-overlaps-hw-shadow.html [ Pass ] +compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow.html [ Pass ] +compositing/force-compositing-mode/no-overflow-iframe-layer.html [ Pass ] +compositing/force-compositing-mode/overflow-hidden-iframe-layer.html [ Pass ] +compositing/force-compositing-mode/overflow-iframe-layer.html [ Pass ] +compositing/geometry/clip-inside.html [ Pass ] +compositing/geometry/clip-with-shadow.html [ Pass ] +compositing/geometry/clip.html [ Pass ] +compositing/geometry/clipped-video-controller.html [ Pass ] +compositing/geometry/fixed-position.html [ Pass ] +compositing/geometry/flipped-blocks-inline-mapping.html [ Pass ] +compositing/geometry/flipped-writing-mode.html [ Pass ] +compositing/geometry/foreground-layer.html [ Pass ] +compositing/geometry/horizontal-scroll-composited.html [ Pass ] +compositing/geometry/vertical-scroll-composited.html [ Pass ] +compositing/geometry/video-fixed-scrolling.html [ Pass ] +compositing/geometry/video-opacity-overlay.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-clipped.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-late-composite.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-late-noncomposite.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-iframe-composited.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-iframe-scrolled.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-iframe.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-overflow-div-composited-scroll-clip.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-overflow-div-layout-change-2.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-overflow-div-layout-change.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled-late-composite.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled.html [ Pass ] +compositing/gestures/gesture-tapHighlight-1-overflow-div.html [ Pass ] +compositing/gestures/gesture-tapHighlight-adjustment-clipping.html [ Pass ] +compositing/gestures/gesture-tapHighlight-block-in-multicol.html [ Pass ] +compositing/gestures/gesture-tapHighlight-composited-img.html [ Pass ] +compositing/gestures/gesture-tapHighlight-display-contents.html [ Pass ] +compositing/gestures/gesture-tapHighlight-form-input-text.html [ Pass ] +compositing/gestures/gesture-tapHighlight-imagemap.html [ Pass ] +compositing/gestures/gesture-tapHighlight-nested-cursor.html [ Pass ] +compositing/gestures/gesture-tapHighlight-simple-div-boxshadow-fixed.html [ Pass ] +compositing/gestures/gesture-tapHighlight-simple-div-boxshadow-static.html [ Pass ] +compositing/gestures/gesture-tapHighlight-simple-div-boxshadow.html [ Pass ] +compositing/gestures/gesture-tapHighlight-simple-navigate.html [ Pass ] +compositing/gestures/gesture-tapHighlight-simple-scaled-document.html [ Pass ] +compositing/gestures/gesture-tapHighlight-simple-scaledX.html [ Pass ] +compositing/gestures/gesture-tapHighlight-skew-matrix.html [ Pass ] +css1/box_properties/border.html [ Pass ] +css1/box_properties/border_color_inline.html [ Pass ] +css1/box_properties/border_style_inline.html [ Pass ] +css1/box_properties/clear.html [ Pass ] +css1/box_properties/float.html [ Pass ] +css1/box_properties/float_on_text_elements.html [ Pass ] +css1/box_properties/margin.html [ Pass ] +css1/box_properties/padding_inline.html [ Pass ] +css1/cascade/cascade_order.html [ Pass ] +css1/classification/display.html [ Pass ] +css1/classification/list_style_image.html [ Pass ] +css1/color_and_background/background.html [ Pass ] +css1/color_and_background/color.html [ Pass ] +css1/font_properties/font.html [ Pass ] +css1/formatting_model/horizontal_formatting.html [ Pass ] +css1/formatting_model/vertical_formatting.html [ Pass ] +css1/pseudo/multiple_pseudo_elements.html [ Pass ] +css1/text_properties/text_align.html [ Pass ] +css1/units/color_units.html [ Pass ] +css2.1/t010403-shand-border-00-c.html [ Pass ] +css2.1/t010403-shand-font-00-b.html [ Pass ] +css2.1/t040103-escapes-00-b.html [ Pass ] +css2.1/t040103-ident-00-c.html [ Pass ] +css2.1/t0803-c5501-imrgn-t-00-b-ag.html [ Pass ] +css2.1/t0803-c5501-mrgn-t-00-b-a.html [ Pass ] +css2.1/t0804-c5506-padn-t-00-b-a.html [ Pass ] +css2.1/t0804-c5507-ipadn-r-00-b-ag.html [ Pass ] +css2.1/t0805-c5517-brdr-s-00-c.html [ Pass ] +css2.1/t0805-c5517-ibrdr-s-00-a.html [ Pass ] +css2.1/t0905-c5525-flthw-00-c-g.html [ Pass ] +css2.1/t0905-c5525-fltinln-00-c-ag.html [ Pass ] +css2.1/t1202-counters-00-b.html [ Pass ] +css2.1/t140201-c533-bgimage-00-a.html [ Pass ] +css2.1/t1504-c523-font-style-00-b.html [ Pass ] +css2.1/t170602-bdr-conflct-w-00-d.html [ Pass ] +css2.1/20110323/background-intrinsic-001.htm [ Pass ] +css2.1/20110323/border-conflict-style-079.htm [ Pass ] +css2.1/20110323/inline-table-001.htm [ Pass ] +css2.1/20110323/margin-applies-to-001.htm [ Pass ] +css2.1/20110323/outline-color-applies-to-014.htm [ Pass ] +css2.1/20110323/table-caption-001.htm [ Pass ] +css3/font-feature-settings-rendering.html [ Pass ] +css3/background/background-color-gradient-alignment.html [ Pass ] +css3/blending/background-blend-mode-crossfade-image-gradient.html [ Pass ] +css3/blending/mix-blend-mode-composited-layers.html [ Pass ] +css3/blending/svg-blend-color.html [ Pass ] +css3/filters/add-filter-rendering.html [ Pass ] +css3/filters/backdrop-filter-basic-blur.html [ Pass ] +css3/filters/effect-blur.html [ Pass ] +css3/filters/effect-combined.html [ Pass ] +css3/masking/clip-path-circle.html [ Pass ] +css3/masking/mask-repeat-round-border.html [ Pass ] +editing/composition-underline-color.html [ Pass ] +editing/caret/caret-color.html [ Pass ] +editing/input/caret-at-the-edge-of-input.html [ Pass ] +editing/inserting/insert-space-in-empty-doc.html [ Pass ] +editing/pasteboard/drag-image-to-contenteditable-in-iframe.html [ Pass ] +editing/selection/selection-background.html [ Pass ] +fast/backgrounds/background-origin-root-element.html [ Pass ] +fast/block/basic/001.html [ Pass ] +fast/block/float/float-in-float-painting.html [ Pass ] +fast/block/margin-collapse/001.html [ Pass ] +fast/block/positioning/001.html [ Pass ] +fast/body-propagation/background-color/001.html [ Pass ] +fast/body-propagation/background-image/009.html [ Pass ] +fast/body-propagation/overflow/001.html [ Pass ] +fast/borders/bidi-002.html [ Pass ] +fast/borders/border-image-outset.html [ Pass ] +fast/box-shadow/box-shadow.html [ Pass ] +fast/box-sizing/box-sizing.html [ Pass ] +fast/css/001.html [ Pass ] +fast/css/color-correction.html [ Pass ] +fast/css-generated-content/001.html [ Pass ] +fast/events/pointer-events-2.html [ Pass ] +fast/forms/001.html [ Pass ] +fast/forms/form-element-geometry.html [ Pass ] +fast/forms/accent-color/accent-color-contrast-dark.html [ Pass ] +fast/forms/button/button-align.html [ Pass ] +fast/forms/calendar-picker/calendar-picker-appearance.html [ Pass ] +fast/forms/checkbox/checkbox-appearance-basic.html [ Pass ] +fast/forms/color/input-appearance-color.html [ Pass ] +fast/forms/color-scheme/button/button-appearance-basic.html [ Pass ] +fast/forms/datalist/input-appearance-range-with-datalist.html [ Pass ] +fast/forms/datetimelocal/datetimelocal-appearance-basic.html [ Pass ] +fast/forms/fieldset/fieldset-align.html [ Pass ] +fast/forms/file/file-appearance-basic.html [ Pass ] +fast/forms/focus-rect/textarea-with-scrollbar.html [ Pass ] +fast/forms/image/input-align-image.html [ Pass ] +fast/forms/month/month-picker-appearance-step.html [ Pass ] +fast/forms/number/number-appearance-rtl.html [ Pass ] +fast/forms/password/password-alt-f8.html [ Pass ] +fast/forms/radio/radio-appearance-basic.html [ Pass ] +fast/forms/range/input-appearance-range.html [ Pass ] +fast/forms/search/search-rtl.html [ Pass ] +fast/forms/select/basic-selects.html [ Pass ] +fast/forms/select-popup/popup-menu-appearance-coarse.html [ Pass ] +fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl.html [ Pass ] +fast/forms/text/input-baseline.html [ Pass ] +fast/forms/textarea/textarea-align.html [ Pass ] +fonts/default.html [ Pass ] +fragmentation/outline-crossing-columns.html [ Pass ] +html/details_summary/details-add-summary.html [ Pass ] +html/document_metadata/head-has-text-1.html [ Pass ] +html/grouping_content/listing.html [ Pass ] +html/tabular_data/table_createcaption.html [ Pass ] +html/text_level_semantics/font-weight-bold-for-b-and-strong.html [ Pass ] +http/tests/csspaint/border-color.html [ Pass ] +http/tests/images/jpeg-partial-load.html [ Pass ] +http/tests/images/png-animated-partial-load.html [ Pass ] +http/tests/images/png-partial-load-as-document.html [ Pass ] +http/tests/inspector-protocol/page/page-captureScreenshot-clip.js [ Pass ] +http/tests/media/video-buffered-range-contains-currentTime.html [ Pass ] +http/tests/webfont/popup-menu-load-webfont-after-open.html [ Pass ] +ietestcenter/css3/bordersbackgrounds/background-color-border-box.htm [ Pass ] +ietestcenter/css3/text/textshadow-001.htm [ Pass ] +images/color-profile-animate.html [ Pass ] +images/cross-fade-blending.html [ Pass ] +images/drag-image.html [ Pass ] +images/jpeg-with-color-profile.html [ Pass ] +images/png-with-color-profile.html [ Pass ] +images/jxl/jxl-images.html [ Pass ] +images/png-suite/test.html [ Pass ] +images/yuv-decode-eligible/color-profile-border-radius.html [ Pass ] +inspector-protocol/dom/dom-scrollIntoViewIfNeeded.js [ Pass ] +inspector-protocol/dom-snapshot/dom-snapshot-captureSnapshot-details.js [ Pass ] +inspector-protocol/emulation/device-emulation-desktop.js [ Pass ] +inspector-protocol/input/dispatchMouseEvent.js [ Pass ] +inspector-protocol/layers/paint-profiler.js [ Pass ] +inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.js [ Pass ] +inspector-protocol/page/get-layout-metrics.js [ Pass ] +paint/background/fieldset-legend-background-shadow-border-radius.html [ Pass ] +paint/clipath/clip-path-with-background-and-box-behind.html [ Pass ] +paint/filters/clip-under-filter.html [ Pass ] +paint/float/float-under-inline-self-painting-change.html [ Pass ] +paint/frames/frameset-with-stacking-contexts.html [ Pass ] +paint/inline/outline-offset.html [ Pass ] +paint/invalidation/canvas-resize.html [ Pass ] +paint/invalidation/background/viewport-gradient-background-html-resize-overflow.html [ Pass ] +paint/invalidation/box/border-radius-repaint-2.html [ Pass ] +paint/invalidation/clip/background-clip-text.html [ Pass ] +paint/invalidation/compositing/layer-repaint.html [ Pass ] +paint/invalidation/css-grid-layout/grid-element-change-columns-repaint.html [ Pass ] +paint/invalidation/filters/effect-reference-repaint-composite-1.html [ Pass ] +paint/invalidation/flexbox/repaint-during-resize-no-flex.html [ Pass ] +paint/invalidation/forms/textarea-caret.html [ Pass ] +paint/invalidation/image/image-resize.html [ Pass ] +paint/invalidation/multicol/column-rules-fixed-height.html [ Pass ] +paint/invalidation/outline/focus-layers.html [ Pass ] +paint/invalidation/overflow/composited-overflow-with-borderbox-background.html [ Pass ] +paint/invalidation/position/absolute-position-changed.html [ Pass ] +paint/invalidation/reflection/reflection-with-rotation.html [ Pass ] +paint/invalidation/scroll/destroy-composited-scrollbar.html [ Pass ] +paint/invalidation/selection/selection-within-composited-scroller.html [ Pass ] +paint/invalidation/svg/animate-path-morphing.svg [ Pass ] +paint/invalidation/table/composited-table-background.html [ Pass ] +paint/invalidation/transform/caret-with-transformation.html [ Pass ] +paint/markers/composition-marker-basic.html [ Pass ] +paint/masks/fieldset-mask.html [ Pass ] +paint/overflow/composited-rounded-clip-floating-element.html [ Pass ] +paint/printing/print-text-shadow.html [ Pass ] +paint/roundedrects/input-with-rounded-rect-and-shadow.html [ Pass ] +paint/selection/text-selection-drag-in-frame-scrolled.html [ Pass ] +paint/subpixel/transform-inside-clip.html [ Pass ] +paint/tables/composited-collapsed-table-borders.html [ Pass ] +paint/text/selection-no-clip-text.html [ Pass ] +paint/theme/adjust-progress-bar-size.html [ Pass ] +paint/transforms/percentage-transform-fractional-box-size.html [ Pass ] +printing/fixed-positioned-headers-and-footers.html [ Pass ] +printing/width-overflow.html [ Pass ] +printing/css2.1/page-break-inside-000.html [ Pass ] +svg/W3C-I18N/text-anchor-dirLTR-anchorMiddle.svg [ Pass ] +svg/W3C-I18N/text-anchor-dirRTL-anchorMiddle.svg [ Pass ] +svg/W3C-SVG-1.1/animate-elem-03-t.svg [ Pass ] +svg/W3C-SVG-1.1-SE/filters-image-03-f.svg [ Pass ] +svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t.svg [ Pass ] +svg/animations/animateMotion-accumulate-1a.svg [ Pass ] +svg/as-background-image/animated-svg-as-background.html [ Pass ] +svg/as-border-image/svg-as-border-image.html [ Pass ] +svg/as-image/svg-as-relative-image.html [ Pass ] +svg/as-object/svg-embedded-in-html-in-iframe.html [ Pass ] +svg/batik/paints/patternRegions.svg [ Pass ] +svg/batik/text/textEffect.svg [ Pass ] +svg/canvas/canvas-pattern-svg.html [ Pass ] +svg/carto.net/selectionlist.svg [ Pass ] +svg/clip-path/clip-path-on-svg.svg [ Pass ] +svg/css/background-image-svg.html [ Pass ] +svg/custom/SVGRect-interface.svg [ Pass ] +svg/dom/css-transforms.xhtml [ Pass ] +svg/dynamic-updates/SVGFilterElement-dom-filterUnits-attr.html [ Pass ] +svg/filters/feGaussianBlur.svg [ Pass ] +svg/foreignObject/filter.html [ Pass ] +svg/hittest/text-small-font-size-and-viewbox.html [ Pass ] +svg/hixie/dynamic/002.xml [ Pass ] +svg/hixie/error/001.xml [ Pass ] +svg/hixie/links/001.xml [ Pass ] +svg/hixie/mixed/003.xml [ Pass ] +svg/hixie/rendering-model/001.xml [ Pass ] +svg/hixie/viewbox/001.xml [ Pass ] +svg/in-html/circle.html [ Pass ] +svg/overflow/overflow-on-foreignObject.svg [ Pass ] +svg/stroke/zero-length-arc-linecaps-rendering.svg [ Pass ] +svg/text/bbox-with-glyph-overflow.html [ Pass ] +svg/text/text-decorations-in-scaled-pattern.svg [ Pass ] +svg/transforms/text-with-pattern-inside-transformed-html.xhtml [ Pass ] +svg/wicd/test-scalable-background-image1.xhtml [ Pass ] +svg/zoom/page/zoom-background-images.html [ Pass ] +svg/zoom/text/zoom-svg-float-border-padding.xml [ Pass ] +tables/layering/paint-test-layering-1.html [ Pass ] +transforms/svg-vs-css.xhtml [ Pass ] +transforms/transform-on-inline.html [ Pass ] +transforms/2d/transform-borderbox.html [ Pass ] +transforms/3d/general/perspective-units.html [ Pass ] +transforms/3d/hit-testing/backface-hit-test.html [ Pass ] # Layout tests significatly differ from non scale baseline crbug.com/1105168 fast/sub-pixel/sub-pixel-accumulates-to-layers.html [ Failure ] @@ -359,8 +637,8 @@ crbug.com/1179570 virtual/layout_ng_printing/printing/block-width-relayout-shrink.html [ Failure ] crbug.com/1179570 virtual/layout_ng_printing/printing/multicol-2-pages.html [ Failure ] crbug.com/1179570 virtual/layout_ng_printing/printing/thead-repeats-with-translucent-text-and-borders.html [ Failure ] -crbug.com/1179570 virtual/layout_ng_printing/printing/vertical-lr.html [ Failure ] -crbug.com/1179570 virtual/layout_ng_printing/printing/vertical-rl.html [ Failure ] +crbug.com/1286601 virtual/layout_ng_printing/printing/vertical-lr.html [ Failure Crash ] +crbug.com/1286601 virtual/layout_ng_printing/printing/vertical-rl.html [ Failure Crash ] crbug.com/1179570 virtual/off-main-thread-css-paint/http/tests/csspaint/entire-canvas-visible-zoom.html [ Failure ] crbug.com/1179570 virtual/off-main-thread-css-paint/http/tests/csspaint/geometry-background-image-zoom.html [ Failure ] crbug.com/1179570 virtual/off-main-thread-css-paint/http/tests/csspaint/geometry-border-image-zoom.html [ Failure ] @@ -382,6 +660,7 @@ crbug.com/1179554 http/tests/images/document-policy-oversized-images-styles.php [ Failure ] # These appear to be flaky +crbug.com/1191215 inspector-protocol/overlay/overlay-viewport.js [ Failure Pass ] crbug.com/1191215 fast/backgrounds/root-background-fixed-attachment-positioning.html [ Failure Pass ] crbug.com/1191215 fast/forms/date/date-appearance-basic.html [ Failure Pass ] crbug.com/1191215 fast/forms/number/number-appearance-datalist.html [ Failure Pass ] @@ -443,7 +722,6 @@ # Off by one errors cause by SwiftShader update crbug.com/1266821 compositing/3d-corners.html [ Failure ] -crbug.com/1266821 compositing/3d-cube.html [ Failure ] crbug.com/1266821 compositing/composited-scaled-child-with-border-radius-parent-clip.html [ Failure ] crbug.com/1266821 compositing/direct-image-compositing.html [ Failure ] crbug.com/1266821 compositing/geometry/layer-due-to-layer-children-deep.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 6934b100..e0343a0c 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -7656,3 +7656,6 @@ # Sheriff 2022-01-11 crbug.com/1286437 [ Mac ] media/picture-in-picture/v2/request-picture-in-picture-twice.html [ Failure Pass ] crbug.com/1286448 [ Mac ] virtual/without-coep-for-shared-worker/external/wpt/html/cross-origin-embedder-policy/anonymous-iframe/cache-storage.tentative.https.window.html [ Crash Pass ] + +# Sheriff 2022-01-12 +crbug.com/1286619 [ Mac ] external/wpt/storage-access-api/storageAccess.testdriver.sub.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/cors/access-control-expose-headers-parsing.window-expected.txt b/third_party/blink/web_tests/external/wpt/cors/access-control-expose-headers-parsing.window-expected.txt index 0fe27f2f..3000d57 100644 --- a/third_party/blink/web_tests/external/wpt/cors/access-control-expose-headers-parsing.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/cors/access-control-expose-headers-parsing.window-expected.txt
@@ -8,7 +8,7 @@ PASS Parsing: Access-Control-Expose-Headers%3A%20bb-8%0D%0AAccess-Control-Expose-Headers%3A%20no%20no PASS Parsing: Access-Control-Expose-Headers%3A%20no%0D%0AAccess-Control-Expose-Headers%3A%20bb-8 FAIL Parsing: Access-Control-Expose-Headers%3A%0D%0AAccess-Control-Expose-Headers%3A%20bb-8 assert_equals: expected (string) "hey" but got (object) null -FAIL Parsing: Access-Control-Expose-Headers%3A%20%2Cbb-8 assert_equals: expected (string) "hey" but got (object) null +PASS Parsing: Access-Control-Expose-Headers%3A%20%2Cbb-8 PASS Parsing: Access-Control-Expose-Headers%3A%20bb-8%0C PASS Parsing: Access-Control-Expose-Headers%3A%20bb-8%0B PASS Parsing: Access-Control-Expose-Headers%3A%20bb-8%0B%2Cbb-8
diff --git a/third_party/blink/web_tests/external/wpt/cors/resources/access-control-expose-headers.json b/third_party/blink/web_tests/external/wpt/cors/resources/access-control-expose-headers.json index e8915f7..4ab38fb 100644 --- a/third_party/blink/web_tests/external/wpt/cors/resources/access-control-expose-headers.json +++ b/third_party/blink/web_tests/external/wpt/cors/resources/access-control-expose-headers.json
@@ -33,7 +33,7 @@ }, { "input": "Access-Control-Expose-Headers: ,bb-8", - "exposed": true + "exposed": false }, { "input": "Access-Control-Expose-Headers: bb-8\u000C",
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-in-worker.https-expected.txt b/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-in-worker.https-expected.txt new file mode 100644 index 0000000..11ecc943 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-in-worker.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL A worker is able to initialize a MediaStreamTrackGenerator without crashing promise_test: Unhandled rejection with value: "Failed with error ReferenceError: MediaStreamTrackGenerator is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-in-worker.https.html b/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-in-worker.https.html new file mode 100644 index 0000000..ff3b945 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mediacapture-insertable-streams/MediaStreamTrackGenerator-in-worker.https.html
@@ -0,0 +1,36 @@ +<!doctype html> +<title>Test creation of MediaStreamTrackGenerator in a worker</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script id="workerCode" type="javascript/worker"> +self.onmessage = (e) => { + try { + const mstg = new MediaStreamTrackGenerator({kind: 'video'}); + self.postMessage({result: 'Success'}); + } catch (e) { + self.postMessage({result: 'Failure', error: e}); + } +} +</script> +<script> +'use strict'; + +promise_test(async t => { + const workerBlob = new Blob([document.querySelector('#workerCode').textContent], + {type: "text/javascript"}); + const workerUrl = window.URL.createObjectURL(workerBlob); + const worker = new Worker(workerUrl); + window.URL.revokeObjectURL(workerUrl); + const result = new Promise((resolve, reject) => { + worker.onmessage = (e) => { + if (e.data.result === 'Failure') { + reject('Failed with error ' + e.data.error); + } else { + resolve(); + } + }; + }); + worker.postMessage('Hello there'); + return result; +}, 'A worker is able to initialize a MediaStreamTrackGenerator without crashing'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/streams-close.https.any.js b/third_party/blink/web_tests/external/wpt/webtransport/streams-close.https.any.js index be9a732..4871ee8 100644 --- a/third_party/blink/web_tests/external/wpt/webtransport/streams-close.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webtransport/streams-close.https.any.js
@@ -161,12 +161,15 @@ const e = new WebTransportError({streamErrorCode: WT_CODE}); // Write a chunk, close the stream, and then abort the stream immediately to // abort the closing operation. + // TODO: Check that the abort promise is correctly rejected/resolved based on + // the spec discussion at https://github.com/whatwg/streams/issues/1203. await writer.write(chunk); const close_promise = writer.close(); - await writer.abort(e); + const abort_promise = writer.abort(e); await promise_rejects_exactly(t, e, close_promise, 'close_promise'); await promise_rejects_exactly(t, e, writer.closed, '.closed'); + await promise_rejects_exactly(t, e, abort_promise, 'abort_promise'); writer.releaseLock(); await wait(10);
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/editing/input/caret-at-the-edge-of-input-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/editing/input/caret-at-the-edge-of-input-expected.png index 0c2cd15d..930d1fc0 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/editing/input/caret-at-the-edge-of-input-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/editing/input/caret-at-the-edge-of-input-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.png index 89c7c9f..17be6af 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/number/number-appearance-rtl-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/number/number-appearance-rtl-expected.png index 38b84aed..b9cc23e 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/number/number-appearance-rtl-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/number/number-appearance-rtl-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/password/password-alt-f8-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/password/password-alt-f8-expected.png index b471bf4..9cce879 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/password/password-alt-f8-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/password/password-alt-f8-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/search/search-rtl-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/search/search-rtl-expected.png index d43ab380..7d03541 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/search/search-rtl-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/fast/forms/search/search-rtl-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/forms/textarea-caret-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/forms/textarea-caret-expected.png index 8bf5af6..d45c97a 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/forms/textarea-caret-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/forms/textarea-caret-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/forms/textarea-caret-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/forms/textarea-caret-expected.txt index 70f899c..55ec39d 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/forms/textarea-caret-expected.txt +++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/forms/textarea-caret-expected.txt
@@ -45,6 +45,26 @@ }, { "name": "Scroll corner of LayoutNGTextControlMultiLine TEXTAREA id='editor'", + "position": [247, 29], + "bounds": [22, 22], + "contentsOpaque": true, + "invalidations": [ + [0, 0, 22, 22] + ], + "transform": 1 + }, + { + "name": "Caret", + "position": [723, 5], + "bounds": [1, 22], + "contentsOpaque": true, + "invalidations": [ + [0, 0, 1, 22] + ], + "transform": 2 + }, + { + "name": "LayoutNGTextControlMultiLine TEXTAREA id='editor'", "position": [-3, -3], "bounds": [277, 59], "contentsOpaqueForText": true,
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/transform/caret-with-transformation-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/transform/caret-with-transformation-expected.png index a742bce..4d5d363 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/transform/caret-with-transformation-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/transform/caret-with-transformation-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/transform/caret-with-transformation-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/transform/caret-with-transformation-expected.txt index b4f4d52..3f4affc 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/transform/caret-with-transformation-expected.txt +++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/transform/caret-with-transformation-expected.txt
@@ -4,11 +4,46 @@ "name": "Scrolling background of LayoutView #document", "bounds": [1200, 900], "contentsOpaque": true, - "backgroundColor": "#FFFFFF", + "backgroundColor": "#FFFFFF" + }, + { + "name": "Caret", + "position": [533, 0], + "bounds": [2, 26], + "contentsOpaque": true, "invalidations": [ - [64, 54, 16, 25], - [526, 321, 15, 24] + [0, 0, 2, 26] + ], + "transform": 2 + }, + { + "name": "LayoutNGBlockFlow DIV", + "position": [-4, -4], + "bounds": [1184, 35], + "contentsOpaqueForText": true, + "transform": 2 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [12, 12, 0, 1] ] + }, + { + "id": 2, + "parent": 1, + "transform": [ + [0.866025403784439, 0.5, 0, 0], + [-0.5, 0.866025403784439, 0, 0], + [0, 0, 1, 0], + [-20.0961894323342, 334.807621135332, 0, 1] + ], + "origin": [588, 13.5] } ] }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/tables/layering/paint-test-layering-1-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/tables/layering/paint-test-layering-1-expected.png index c1f407f..ca35f9f 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/tables/layering/paint-test-layering-1-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/tables/layering/paint-test-layering-1-expected.png Binary files differ
diff --git a/third_party/grpc/BUILD.gn b/third_party/grpc/BUILD.gn index 764f96889..6947383 100644 --- a/third_party/grpc/BUILD.gn +++ b/third_party/grpc/BUILD.gn
@@ -1161,7 +1161,7 @@ "src/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c", "src/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c", "src/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c", - "src/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c", + "src/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.c", "src/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c", "src/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c", "src/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c", @@ -1185,7 +1185,9 @@ "src/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c", "src/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c", "src/src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.c", + "src/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c", "src/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c", + "src/src/core/ext/upb-generated/envoy/type/v3/http.upb.c", "src/src/core/ext/upb-generated/envoy/type/v3/percent.upb.c", "src/src/core/ext/upb-generated/envoy/type/v3/range.upb.c", "src/src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c", @@ -1194,13 +1196,12 @@ "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/eval.upb.c", "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/explain.upb.c", "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c", - "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/value.upb.c", - "src/src/core/ext/upb-generated/google/api/http.upb.c", "src/src/core/ext/upb-generated/google/protobuf/any.upb.c", "src/src/core/ext/upb-generated/google/protobuf/duration.upb.c", "src/src/core/ext/upb-generated/google/protobuf/empty.upb.c", "src/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", "src/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", + "src/src/core/ext/upb-generated/google/rpc/status.upb.c", "src/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c", "src/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c", "src/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c", @@ -1210,7 +1211,6 @@ "src/src/core/ext/upb-generated/udpa/annotations/migrate.upb.c", "src/src/core/ext/upb-generated/udpa/annotations/security.upb.c", "src/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c", - "src/src/core/ext/upb-generated/udpa/annotations/status.upb.c", "src/src/core/ext/upb-generated/udpa/annotations/versioning.upb.c", "src/src/core/ext/upb-generated/validate/validate.upb.c", "src/src/core/ext/upb-generated/xds/core/v3/authority.upb.c", @@ -1222,6 +1222,7 @@ "src/src/core/ext/upb-generated/xds/type/v3/typed_struct.upb.c", "src/src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.c", @@ -1281,6 +1282,8 @@ "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.c", + "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.c", @@ -1291,11 +1294,9 @@ "src/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/eval.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/explain.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/syntax.upbdefs.c", - "src/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/value.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c", - "src/src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c", @@ -1307,7 +1308,6 @@ "src/src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c", "src/src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c", "src/src/core/ext/upbdefs-generated/xds/core/v3/context_params.upbdefs.c", - "src/src/core/ext/upbdefs-generated/xds/core/v3/resource.upbdefs.c", "src/src/core/ext/upbdefs-generated/xds/core/v3/resource_locator.upbdefs.c", "src/src/core/ext/upbdefs-generated/xds/core/v3/resource_name.upbdefs.c", "src/src/core/ext/upbdefs-generated/xds/type/v3/typed_struct.upbdefs.c", @@ -1409,6 +1409,7 @@ "src/src/core/lib/iomgr/event_engine/iomgr.cc", "src/src/core/lib/iomgr/event_engine/pollset.cc", "src/src/core/lib/iomgr/event_engine/resolved_address_internal.cc", + "src/src/core/lib/iomgr/event_engine/resolver.cc", "src/src/core/lib/iomgr/event_engine/tcp.cc", "src/src/core/lib/iomgr/event_engine/timer.cc", "src/src/core/lib/iomgr/exec_ctx.cc", @@ -1477,11 +1478,13 @@ "src/src/core/lib/iomgr/wakeup_fd_posix.cc", "src/src/core/lib/iomgr/work_serializer.cc", "src/src/core/lib/json/json_reader.cc", + "src/src/core/lib/json/json_util.cc", "src/src/core/lib/json/json_writer.cc", + + # "src/src/core/lib/matchers/matchers.cc", "src/src/core/lib/profiling/basic_timers.cc", "src/src/core/lib/profiling/stap_timers.cc", "src/src/core/lib/promise/activity.cc", - "src/src/core/lib/resolver/resolver.cc", "src/src/core/lib/resolver/resolver_registry.cc", "src/src/core/lib/resolver/server_address.cc", "src/src/core/lib/resource_quota/api.cc", @@ -1493,7 +1496,6 @@ "src/src/core/lib/security/authorization/evaluate_args.cc", # "src/src/core/lib/security/authorization/grpc_authorization_engine.cc", - # "src/src/core/lib/security/authorization/matchers.cc", # "src/src/core/lib/security/authorization/rbac_policy.cc", "src/src/core/lib/security/authorization/sdk_server_authz_filter.cc", "src/src/core/lib/security/context/security_context.cc", @@ -1530,6 +1532,8 @@ "src/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", "src/src/core/lib/security/credentials/tls/tls_credentials.cc", "src/src/core/lib/security/credentials/tls/tls_utils.cc", + + # "src/src/core/lib/security/credentials/xds/xds_credentials.cc", "src/src/core/lib/security/security_connector/alts/alts_security_connector.cc", "src/src/core/lib/security/security_connector/fake/fake_security_connector.cc", "src/src/core/lib/security/security_connector/insecure/insecure_security_connector.cc", @@ -1546,7 +1550,6 @@ "src/src/core/lib/security/transport/security_handshaker.cc", "src/src/core/lib/security/transport/server_auth_filter.cc", "src/src/core/lib/security/transport/tsi_error.cc", - "src/src/core/lib/security/util/json_util.cc", "src/src/core/lib/service_config/service_config.cc", "src/src/core/lib/slice/b64.cc", "src/src/core/lib/slice/percent_encoding.cc", @@ -1625,8 +1628,6 @@ "src/src/cpp/client/create_channel_posix.cc", "src/src/cpp/client/credentials_cc.cc", "src/src/cpp/client/secure_credentials.cc", - - # "src/src/cpp/client/xds_credentials.cc", "src/src/cpp/codegen/codegen_init.cc", "src/src/cpp/common/alarm.cc", "src/src/cpp/common/auth_property_iterator.cc", @@ -1696,36 +1697,36 @@ sources = [ "src/src/core/ext/transport/chttp2/client/insecure/channel_create.cc", "src/src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c", - "src/src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.c", + "src/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c", "src/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c", - "src/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c", "src/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c", - "src/src/core/ext/upb-generated/envoy/type/v3/http.upb.c", + "src/src/core/ext/upb-generated/google/api/expr/v1alpha1/value.upb.c", + "src/src/core/ext/upb-generated/google/api/http.upb.c", "src/src/core/ext/upb-generated/google/protobuf/struct.upb.c", - "src/src/core/ext/upb-generated/google/rpc/status.upb.c", + "src/src/core/ext/upb-generated/udpa/annotations/status.upb.c", "src/src/core/ext/upb-generated/xds/core/v3/resource.upb.c", - "src/src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c", - "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.c", - "src/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c", "src/src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/value.upbdefs.c", "src/src/core/ext/upbdefs-generated/google/api/http.upbdefs.c", + "src/src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c", "src/src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c", + "src/src/core/ext/upbdefs-generated/xds/core/v3/resource.upbdefs.c", "src/src/core/lib/iomgr/event_engine/endpoint.cc", - "src/src/core/lib/iomgr/event_engine/resolver.cc", "src/src/core/lib/iomgr/iomgr.cc", "src/src/core/lib/iomgr/pollset.cc", "src/src/core/lib/iomgr/timer.cc", - "src/src/core/lib/json/json_util.cc", - - # "src/src/core/lib/matchers/matchers.cc", + "src/src/core/lib/resolver/resolver.cc", "src/src/core/lib/resource_quota/trace.cc", - # "src/src/core/lib/security/credentials/xds/xds_credentials.cc", + # "src/src/core/lib/security/authorization/matchers.cc", + "src/src/core/lib/security/util/json_util.cc", "src/src/core/lib/service_config/service_config_parser.cc", "src/src/cpp/client/insecure_credentials.cc", + + # "src/src/cpp/client/xds_credentials.cc", ] deps = [
diff --git a/third_party/grpc/template/BUILD.chromium.gn.template b/third_party/grpc/template/BUILD.chromium.gn.template index 29d6b7e4..924bd88 100644 --- a/third_party/grpc/template/BUILD.chromium.gn.template +++ b/third_party/grpc/template/BUILD.chromium.gn.template
@@ -140,6 +140,8 @@ # Deduplicate the sources files in the input so the same source file # don't appear in multiple sets sources = set(sources) + # Convert sources to sorted list so the sources are split into 3 targets deterministically + sources = sorted(sources) out_sources = [] repeated1 = [] repeated2 = []
diff --git a/tools/binary_size/README.md b/tools/binary_size/README.md index 2fadc7f..9cf1d16 100644 --- a/tools/binary_size/README.md +++ b/tools/binary_size/README.md
@@ -46,258 +46,8 @@ ## SuperSize -Collects, archives, and analyzes Chrome's binary size. -Supports Android and Linux (although Linux -[has issues](https://bugs.chromium.org/p/chromium/issues/detail?id=717550)). - -### Technical Details - -#### What's in a .size File? - -`.size` files are gzipped plain text files that contain: - -1. A list of section sizes, including: - * .so sections as reported by `readelf -S` - * .pak and .dex sections for apk files -1. Metadata (apk size, GN args, filenames, timestamps, git revision, build id), -1. A list of symbols, including name, address, size, - padding (caused by alignment), and associated source/object files. - -#### How are Symbols Collected? - -##### Native Symbols (.text, .rodata, .data, .data.rel.ro, .bss) - -1. Symbol list is extracted from linker `.map` file. - * Map files contain some unique pieces of information compared to `nm` - output, such as `** merge strings` entries, and some unnamed symbols - (which although unnamed, contain the `.o` path). - * Generated in `is_official_build=true` builds if `generate_linker_map` is - true. In official builds on Android generate_linker_map is true by default. -1. `.o` files are mapped to `.cc` files by parsing `.ninja` files. - * This means that `.h` files are never listed as sources. No information - about inlined symbols is gathered. -1. `** merge strings` symbols are further broken down into individual string - literal symbols. This is done by reading string literals from `.o` files, and - then searching for them within the `** merge strings` sections. - * For LLD with [ThinLTO](https://clang.llvm.org/docs/ThinLTO.html), - `llvm-bcanalyzer` is used to extract string literals. -1. Symbol aliases: - * Aliases have the same address and size, but report their `.pss` as - `.size / .num_aliases`. - * Type 1: Different names. Caused by identical code folding. - * These are collected from debug information via `nm elf-file`. - * Type 2: Same names, different paths. Caused by inline functions defined in - `.h` files. - * These are collected by running `nm` on each `.o` file. - * For LLD with ThinLTO, `llvm-bcanalyzer` is used to process `.o` files, - which are actually LLVM Bitcode files. - * Normally represented using one alias per path, but are sometimes - collapsed into a single symbol with a path of `{shared}/$SYMBOL_COUNT`. - This collapsing is done only for symbols owned by a large number of - paths. - * Type 3: String literals that are de-duped at link-time. - * These are found as part of the string literal extraction process. - -##### Pak Symbols (.pak.nontranslated and .pak.translations) - -1. Grit creates a mapping between numeric id and textual id for grd files. - * A side effect of pak allowlist generation is a mapping of `.cc` to numeric - id. - * A complete per-apk mapping of numeric id to textual id is stored in the - `output_dir/size-info` dir. -1. `supersize` uses these two mappings to find associated source files for the - pak entries found in all of the apk's `.pak` files. - * Pak entries with the same name are merged into a single symbol. - * This is the case of pak files for translations. - * The original grd file paths are stored in the full name of each symbol. - -##### Dex Symbols (.dex and .dex.method) - -1. Java compile targets create a mapping between java fully qualified names - (FQN) and source files. - * For `.java` files the FQN of the public class is mapped to the file. - * For `.srcjar` files the FQN of the public class is mapped to the `.srcjar` - file path. - * A complete per-apk class FQN to source mapping is stored in the - `output_dir/size-info` dir. -1. The `apkanalyzer` sdk tool is used to find the size and FQN of entries in - the dex file. - * If a proguard `.mapping` file is available, that is used to get back the - original FQN. -1. The output from `apkanalyzer` is used by `supersize` along with the mapping - file to find associated source files for the dex entries found in all of the - apk's `.dex` files. - -##### Other Symbols (.other) - -All files in an apk that are not broken down into sub-entries are tracked by a -symbol within the `.other` section. - -##### Overhead and Star Symbols - -Overhead symbols track bytes that are generally unactionable. They are recorded -as `size=0, padding=$size` (padding-only symbols) to de-emphasize them in diffs. - -Star symbols are those that track sections of the binary that are not padding, -but which the tool is not able to break down further -(e.g. "\*\* Merge Globals") - -* **\*\* symbol gap**: A gap between symbols that is larger than what could be - due to alignment. -* **Overhead: ELF file**: `elf_file_size - sum(elf_sections)`. - * Captures bytes taken up by ELF headers and section alignment. -* **Overhead: APK file**: `apk_file_size - sum(compressed_file_sizes)` - * Captures bytes taken up by `.zip` metadata and zipalign padding. -* **Overhead: ${NAME}.pak**: `pak_file_size - sum(pak_entries)` -* **Overhead: Pak compression artifacts**: - `compressed_size_of_paks - sum(pak_entries)` - * It would be possible to correctly attribute compressed size to pak symbols, - but doing so makes diffs very noisy (any change in compression ratio causes - every symbol to change by a small amount). Instead, SuperSize uses a - hard-coded compression ratio for compressed .pak symbols, and captures any - remainder in this overhead symbol. - * TODO([crbug/894320](https://crbug.com/894320)): Improve how compression is - tracked. - -#### What Other Processing Happens? - -1. Path normalization: - * Prefixes are removed: `out/Release/`, `gen/`, `obj/` - * Archive names made more pathy: `foo/bar.a(baz.o)` -> `foo/bar.a/baz.o` - * Shared symbols do not store the complete source paths. Instead, the - common ancestor is computed and stored as the path. - * Example: `base/{shared}/3` (the "3" means three different files contain - the symbol) - -1. Name normalization: - * `(anonymous::)` is removed from names (and stored as a symbol flag). - * `[clone]` suffix removed (and stored as a symbol flag). - * `vtable for FOO` -> `Foo [vtable]` - * Mangling done by linkers is undone (e.g. prefixing with "unlikely.") - * Names are processed into: - * `name`: Name without template and argument parameters - * `template_name`: Name without argument parameters. - * `full_name`: Name with all parameters. - -1. Special cases: - * LLVM function outlining creates many OUTLINED_FUNCTION_* symbols. These - renamed to '** outlined functions' or '** outlined functions * (count)', - and are deduped so an address can have at most one such symbol. - -1. Clustering: - * Compiler & linker optimizations can cause symbols to be broken into - multiple parts to become candidates for inlining ("partial inlining"). - * These symbols are sometimes suffixed with "`[clone]`" (removed by - normalization). - * Clustering creates groups containing all pieces of a symbol (in the case - where multiple pieces remain after inlining). - * Clustering is done by default on `SizeInfo.symbols`. To view unclustered - symbols, use `SizeInfo.raw_symbols`. - -1. Diffing: - * Some heuristics for matching up before/after symbols. - -1. Simulated compression: - * Only some `.pak` files are compressed and others are kept uncompressed. - * To get a reasonable idea of actual impact to final apk size, we use a - constant compression factor for all the compressed `.pak` files. - * This prevents swings in compressed sizes for all symbols when new - entries are added or old entries are removed. - * The constant is chosen so that it minimizes overall discrepancy with - actual total compressed sizes. - -#### Is SuperSize a Generic Tool? - -No. Some examples of why it's Chrome-specific: - - * Assumes `.ninja` build rules are available. - * Heuristic for locating `.so` given `.apk`. - * Requires `size-info` dir in output directory to analyze `.pak` and `.dex` - files. - -### Usage: archive - -Collect size information and dump it into a `.size` file. - -*** note -**Note:** Refer to -[diagnose_bloat.py](https://cs.chromium.org/search/?q=file:diagnose_bloat.py+gn_args) -for list of GN args to build a Release binary (or just use the tool with --single). -*** - -Example Usage: - -``` bash -# Android: -ninja -C out/Release -j 1000 apks/ChromePublic.apk -tools/binary_size/supersize archive chrome.size --apk-file out/Release/apks/ChromePublic.apk -v - -# Linux: -ninja -C out/Release -j 1000 chrome -tools/binary_size/supersize archive chrome.size --elf-file out/Release/chrome -v -``` - -### Usage: start_server - -Locally view a `.size` file, by starting a web server that links to the file. - -Example Usage: - -``` bash -# Starts a local server to view the data in ./report.size -tools/binary_size/supersize start_server report.size - -# Set a custom address and port. -tools/binary_size/supersize start_server report.size -a localhost -p 8080 -``` - -### Usage: diff - -A convenience command equivalent to: -`console before.size after.size --query='Print(Diff(size_info1, size_info2))'` - -Example Usage: - -``` bash -tools/binary_size/supersize diff before.size after.size --all -``` - -### Usage: console - -Starts a Python interpreter where you can run custom queries, or run pre-made -queries from `canned_queries.py`. - -Example Usage: - -```bash -# Prints size infomation and exits (does not enter interactive mode). -tools/binary_size/supersize console chrome.size --query='Print(size_info)' - -# Enters a Python REPL (it will print more guidance). -tools/binary_size/supersize console chrome.size -``` - -Example session: - -``` python ->>> ShowExamples() # Get some inspiration. -... ->>> sorted = size_info.symbols.WhereInSection('t').Sorted() ->>> Print(sorted) # Have a look at the largest symbols. -... ->>> sym = sorted.WhereNameMatches('TrellisQuantizeBlock')[0] ->>> Disassemble(sym) # Time to learn assembly. -... ->>> help(canned_queries) -... ->>> Print(canned_queries.TemplatesByName(depth=-1)) -... ->>> syms = size_info.symbols.WherePathMatches(r'skia').Sorted() ->>> Print(syms, verbose=True) # Show full symbol names with parameter types. -... ->>> # Dump all string literals from skia files to "strings.txt". ->>> Print((t[1] for t in ReadStringLiterals(syms)), to_file='strings.txt') -``` +Collects, archives, and analyzes Chrome's binary size on Android. +See [//tools/binary_size/libsupersize/README.md](/tools/binary_size/libsupersize/README.md). ## diagnose_bloat.py
diff --git a/tools/binary_size/libsupersize/README.md b/tools/binary_size/libsupersize/README.md new file mode 100644 index 0000000..87c05b4 --- /dev/null +++ b/tools/binary_size/libsupersize/README.md
@@ -0,0 +1,106 @@ +# SuperSize + +SuperSize is comprised of two parts: + +1. A command-line tool for creating and inspecting `.size` files, +2. A web app for visualizing `.size` files. + +For more details, see [//tools/binary_size/libsupersize/docs]. + +[//tools/binary_size/libsupersize/docs]: /tools/binary_size/libsupersize/docs + +[TOC] + +## Why SuperSize? + +Chrome on Android needs to be as lean as possible. Having a tool that can show +why binary grows & shrinks helps keep it lean. + +The [android-binary-size trybot] uses SuperSize to show an APK Breakdown on +every Chromium code review. + +SuperSize is also used when creating [milestone size reports] (Googlers only). + +[android-binary-size trybot]: /docs/speed/binary_size/android_binary_size_trybot.md +[milestone size reports]: https://goto.google.com/chromemilestonesizes + +## Is SuperSize a Generic Tool? + +No. It works only for binaries built using Chrome's custom build system. E.g.: + + * It assumes `.ninja` build rules are available. + * It uses heuristic for locating `.so` given `.apk`. + * It requires the `size-info` build directory to analyze `.pak` and `.dex` + files. + +## SuperSize Usage + +### supersize archive + +Collect size information into a `.size` file. + +*** note +**Note:** Refer to +[diagnose_bloat.py](https://cs.chromium.org/search/?q=file:diagnose_bloat.py+gn_args) +for list of GN args to build a release binary (or just use the tool with --single). +*** + +Example Usage: + +``` bash +# Android: +autoninja -C out/Release apks/ChromePublic.apk +tools/binary_size/supersize archive chrome.size -f out/Release/apks/ChromePublic.apk -v + +# Linux: +autoninja -C out/Release chrome +tools/binary_size/supersize archive chrome.size -f out/Release/chrome -v +``` + +### supersize console + +Starts a Python interpreter where you can run custom queries, or run pre-made +queries from `canned_queries.py`. + +Example Usage: + +```bash +# Prints size information and exits (does not enter interactive mode). +tools/binary_size/supersize console chrome.size --query='Print(size_info)' + +# Enters a Python REPL (it will print more guidance). +tools/binary_size/supersize console chrome.size +``` + +Example Session: + +``` python +>>> ShowExamples() # Get some inspiration. +... +>>> sorted = size_info.symbols.WhereInSection('t').Sorted() +>>> Print(sorted) # Have a look at the largest symbols. +... +>>> sym = sorted.WhereNameMatches('TrellisQuantizeBlock')[0] +>>> Disassemble(sym) # Time to learn assembly. +... +>>> help(canned_queries) +... +>>> Print(canned_queries.TemplatesByName(depth=-1)) +... +>>> syms = size_info.symbols.WherePathMatches(r'skia').Sorted() +>>> Print(syms, verbose=True) # Show full symbol names with parameter types. +... +>>> # Dump all string literals from skia files to "strings.txt". +>>> Print((t[1] for t in ReadStringLiterals(syms)), to_file='strings.txt') +``` + +### supersize diff + +A convenience command equivalent to: +`console before.size after.size --query='Print(Diff(size_info1, size_info2))'` + +Example Usage: + +``` bash +tools/binary_size/supersize diff before.size after.size --all +```
diff --git a/tools/binary_size/libsupersize/docs/apk_symbols.md b/tools/binary_size/libsupersize/docs/apk_symbols.md new file mode 100644 index 0000000..03ea7cd --- /dev/null +++ b/tools/binary_size/libsupersize/docs/apk_symbols.md
@@ -0,0 +1,41 @@ +# APK Symbols + +All files in an APK that are not broken down into sub-entries are tracked by a +symbol within the `.other` section. This includes: + + * `resources.arsc` + * `assets/*` + * `res/*` + +## Algorithm + +**During builds:** + +* An `$output_dir/size-info/Foo.res.info` file is created that records the + originating path for each android resource file. + +**During `supersize archive`:** + +For each zip entry: + + * One symbol is created using the compressed size of the entry. + * Files within `res/` are given a source path using the mapping from + `$output_dir/Foo.apk.res.info` + * Other entries are given a source path of `$APK/$zip_path`. + +Each zip entry incurs additional size overhead from: + + * Zip file local header, + * Size dependent on filename length and zipalign overhead. + * Zip file central directory entry, + * An entry within V1 signature files (`META-INF/` files). + * Applicable only for older `minSdkVersion` apks, and for system image apks. + * `res/` files have an associated entry within `resources.arsc`. + +Rather than include this overhead in each symbol, they are put altogether into a +single `Overhead: APK file` symbol. Because: + +1. The symbol size is more understandable if it matches the `unzip -lv` output. +2. It prevents zipalign overhead from causing many small size changes in diffs. +3. When looking at size optimizations, it makes more sense to look at the total + overhead rather than the per-symbol overhead.
diff --git a/tools/binary_size/libsupersize/docs/dex_symbols.md b/tools/binary_size/libsupersize/docs/dex_symbols.md new file mode 100644 index 0000000..1b8c78e --- /dev/null +++ b/tools/binary_size/libsupersize/docs/dex_symbols.md
@@ -0,0 +1,25 @@ +# Dex Symbols + +Dex symbols are those with a `section` of: + * `.dex.method` (Java methods) + * `.dex` (All other forms of dex size. E.g. Class descriptors) + +## Algorithm + +**During builds:** + + * Java compile targets create a mapping between Java fully qualified names + (FQN) and source files. + * For `.java` files the FQN of the public class is mapped to the file. + * For `.srcjar` files the FQN of the public class is mapped to the `.srcjar` + file path. + * A complete per-apk class FQN to source mapping is stored in the + `$output_dir/size-info` dir. + +**During `supersize archive`:** + +1. `$ANDROID_SDK/cmdline-tools/apkanalyzer dex packages` is used to find the + size and FQN of entries in across all dex files. + * One symbol is created for each method and class entry in the output. +2. Source paths are added to symbols using the mapping from + `$output_dir/Foo.apk.jar.info`
diff --git a/tools/binary_size/libsupersize/docs/file_format.md b/tools/binary_size/libsupersize/docs/file_format.md new file mode 100644 index 0000000..ffbd2b3 --- /dev/null +++ b/tools/binary_size/libsupersize/docs/file_format.md
@@ -0,0 +1,143 @@ +# File Format + +[TOC] + +## Overview + +There are three formats that SuperSize uses: + +1. Full `.size` files: + * Contains size information from running `supersize archive`. + * The fields `padding`, `short_name`, and `template_name` are omitted and + re-derived when loading. +2. Sparse `.size` files: + * Can be created only via `supersize console`. + * Contains a subset of symbols from a full `.size` file. + * Encodes padding information for each symbol. +3. `.sizediff` files: + * Created via `supersize console` or `supersize save_diff`. + * Contains two nested sparse `.size` files, where unchanged symbols are + removed from each. + +## Format Details: .size + +The file format is a `gzipped` encoding of symbols, where some symbol fields are +delta-encoded to improve compressibility. Text was chosen over binary because it +is easier to work with in Python and is easier than binary to debug. An effort +was made to make the text highly compressible in order to keep the file sizes as +small as possible. + +Each `.size` file contains: + +1. A list of section sizes. +2. Metadata (GN args, git revision, timestamp, etc), +3. A list of symbols. + +The following specifies the `.size` file format. + +### Header + +* Line 0: Vanity line - says what tool created the file. Ignored when loading. +* Line 1: format version string. The current version is "Size File Format v1.1". +* Line 2: number of bytes for the header fields. +* Line 3+: the header fields, a stringified JSON object. + +The JSON for the header fields looks like: + +```json +{ + "build_config": { + "git_revision": "f49193cacf8ed34160a04ada4acf2ad6a1a030c8", + "gn_args": [ ... ], + "linker_name": "lld_v1", + "tool_prefix": "third_party/llvm-build/Release+Asserts/bin/llvm-" + }, + "containers": [ + { + "name": "TrichromeLibrary.apk", + "metadata": { + ... (see models.py METADATA_ for list of keys) + }, + "section_sizes": { + ".rodata": 8344540, + ".shstrtab": 287, + ".text": 52389250 + ... + } + }, ... + ], + "has_components": true, + "has_padding": false +} +``` + +### Path List + +* Line 0: number of entries in the list. +* Lines 1..N: tuple of (`object_path`, `source_path`) where the two parts + are tab-separated. + +### Component List + +* This section is only present if `has_components` is True in header fields. +* Line 0: number of entries in the list. +* Lines 1..N: Component names. + +### Symbol Counts + +* Line 0: Tab-separated list of `"<Container Name>section_names"`. +* Line 1: Tab-separated list of symbol counts, in the same order as the previous + line. + +### Numeric Values + +In each section, the number of rows is the same as the number of items per line +in Symbol Counts. The values on a row are space separated, in the order of the +symbols in each group. + +The numeric values are: +* Symbol addresses, delta-encoded +* Symbol sizes (in bytes) +* Symbol paddings (in bytes) + * This section is only present if `has_padding` is True in header fields. +* Path indices, delta-encoded + * Indices reference paths from the Path List. +* Component indices, delta-encoded + * Indices reference components in the Component List. + * This section is only present if `has_components` is True in header fields. + +### Symbols + +* Each line represents a single symbol. +* Values are tab-separated. +* Values include: + * `full_name`, + * `num_aliases` (omitted when identical to previous line), + * `flags` (omitted when 0). + +## Format Details .sizediff + +The `.sizediff` file stores two sparse `.size` files. + +### Header + +* Line 0: Vanity line - says what tool created the file. Ignored when loading. +* Line 1: number of bytes for the header fields. +* Line 2+: the header fields, a stringified JSON object. + +The JSON for the header fields looks like: + +```json +{ + "before_length": 1234, + "version": 1 +} +``` + +### Before + +A sparse `.size` file (gzipped). + +### After + +A sparse `.size` file (gzipped).
diff --git a/tools/binary_size/libsupersize/docs/native_symbols.md b/tools/binary_size/libsupersize/docs/native_symbols.md new file mode 100644 index 0000000..1d16cbec --- /dev/null +++ b/tools/binary_size/libsupersize/docs/native_symbols.md
@@ -0,0 +1,122 @@ +# Native Symbols + +This doc describes how SuperSize breaks down native binaries into symbols. + +[TOC] + +## Overview + +Native symbols are those with a `section` of: + + * `.text` (executable code) + * `.rodata` (read-only data) + * `.data` (writable data) + * `.data.rel.ro` (data that is read-only after ELF relocations are applied) + * `.bss` (symbols that are zero-initialized. These consume no space in the + binary, and so are generally ignored despite still being collected. + +Symbol aliases: + * Aliases have the same address and size, but report their `.pss` as + `.size / .num_aliases`. + * Type 1: Different names. Caused by identical code folding. + * Type 2: Same names, different paths. Caused by inline functions defined in + `.h` files. + * Represented as one alias per path, but are collapsed into a single symbol + with a path of `{common_prefix}/$SYMBOL_COUNT` when the number of aliases + is large. + * Type 3: String literals that are de-duped at link-time. + * These are found as part of the string literal extraction process. + +There are 3 modes that SuperSize can use to break an ELF down into symbols: + + * `linker_map` - Uses linker map + build directory to create symbols. + * `dwarf` - Uses debug information to create symbols. + * `sections` - Creates one symbol for each ELF section. + +## Mode: linker_map + +This is the mode that produces the largest number of symbols, and thus is the +preferred mode. Information provided only by this mode: + + * Path information for symbols outside of .text + * DWARF information is complete for .text symbols (maybe because stack + symbolization is a primary use-case?), but incomplete or missing for symbols + in other sections. + * String literals (.rodata symbols that look like `"some string dat..."`). + * Linker map files contain `** merge strings` entries, which tell us where + to string tables exist within `.rodata`. + * `object_path`, which is useful for attributing STL usages to individual + source files. + * Path aliases - when an inline symbol is used by multiple source files, we + attribute the symbol's cost equally among the files. + * Linker-generated symbols. E.g. Switch tables. + +### Data Sources + + * `build.ninja` is parsed to get: + * List of `.o` and `.a` files that were inputs to the linker. + * Mapping of `.cc` -> `.o` files. + * All `.o` (and `.a`) files are parsed: + * with `nm` to get symbol list. + * Non-ThinLTO: with `nm` to get list of string literals + * ThinLTO: with `llvm-bcanalyzer` to get list of string literals + * ELF file is parse with `nm` to get list of symbol names that were + identical-code-folded to the same address. + * Linker map (created via `-Wl,-Map=output.map`) parsed to get: + * Full list of symbols that comprise the binary, + * Location of string tables (`** merge strings` entries). + * Non-ThinLTO: `object_path` (`.o` file) associated with each symbol + * Note: + * With ThinLTO, `object_path` points to a hashed filename within the thinlto + cache (not useful). + * When multiple symbols are folded together due to Identical Code Folding, + the linker map file lists only one of them. + * ELF file string tables are parsed by looking for `\0` bytes and creating + string literal symbols for each string therein. + +### Algorithm + +1. Create initial symbol list from linker map. +2. Assign object paths by seeing which `.o` files define each symbol (match up + the names). + * When multiple files define the same symbol, create symbol aliases. +3. Create string literal symbols from string tables, and assign them paths based + on which `.o` files define the same string literal. +4. Assign `source_path` using the `.o` -> `.cc` mapping from `build.ninja`. + * This means that `.h` files are never listed as sources. No information + about inlined symbols is gathered (by design). +5. Create symbol aliases when `nm` reports multiple symbols mapping to the same + address. +6. Normalize `source_path` by removing generated path prefix (and adding + `FLAG_GENERATED`) when applicable. +7. Normalize symbol names. + +## Mode: dwarf + +Creates symbols using only an ELF with debug information enabled. Requires +compiler flag `-gmlt` to enable full source paths (rather than just basename). + +### Algorithm + +1. Create initial symbol list with `nm --print-size`. +2. Add name aliases using output from `nm` (this could have been done at the + same time as the previous step, but is done as a separate step in order to + share logic with `linker_map` mode. +3. Uses `dwarfdump` to find all `DW_AT_compile_unit` and `DW_AT_ranges` entries + and create a map of address range -> source path. +4. Assign source paths based to .text symbols based on symbol address. + +### Why not use Bloaty? + +[Bloaty](https://github.com/google/bloaty) is an excellent tool, and produces +size information with similar fidelity to "dwarf" mode, as it uses the same +data source. We did not use bloaty since "dwarfdump" was already readily +available and gave similar results. It would be nice to also have a "bloaty" +mode so that we could more direclty compare outputs. + +## Mode: sections + +This mode uses `readelf -s` to create one symbol for each ELF section. It is +used for native files where no debug information or linker map file is +available, and for native files whose ABI do not match the `--abi-filter`. +
diff --git a/tools/binary_size/libsupersize/docs/pak_symbols.md b/tools/binary_size/libsupersize/docs/pak_symbols.md new file mode 100644 index 0000000..6b7b976 --- /dev/null +++ b/tools/binary_size/libsupersize/docs/pak_symbols.md
@@ -0,0 +1,33 @@ +## Pak Symbols + +Pak symbols are those with a `section` of: + + * `.pak.nontranslated` (entries in `resources.pak`, `chrome_100_percent.pak`) + * `.pak.translations` (entries in `en_US.pak`, `fr.pak`, etc) + * There is one symbols for each GRIT ID. The size of the symbol is the sum of + the size of all pak entries with that ID across all `.pak` files. + +## Algorithm + +**During builds:** + + * [Grit] records the originating `.grd` file, textual ID, and numeric ID for + each entry that it processes during a `grit()` step into a `.pak.info` file. + * These `.pak.info` files are merged during `repack` and APK / App Bundle steps + into a single `$output_dir/size-info/Foo.apk.pak.info`. + +[Grit]: /tools/grit/README.md + +**During `supersize archive`:** + +1. When native symbols are created using `linker_map` mode, a map of `pak_id` -> + `source_path` is created by looking for symbols named + `ui::AllowlistedResource<$PAK_ID>()`. +2. Pak files are extracted and turned into dicts using grit. +3. The size of each pak entry is summed with other entries of the same ID. +4. Symbol aliases are created for pak entries with different IDs, but that + refer to the same data (the `.pak` file format supports this). +5. Entry names ("textual IDs"), and the original `.grd` file paths are stored in + the `full_name` of each symbol by using the information in the + `$outdir/size-info/Foo.pak.info` file. +6. Path information is added to the symbols using the map from Step 1.
diff --git a/tools/binary_size/libsupersize/file_format.py b/tools/binary_size/libsupersize/file_format.py index 5da6fca..4e2184be 100644 --- a/tools/binary_size/libsupersize/file_format.py +++ b/tools/binary_size/libsupersize/file_format.py
@@ -4,101 +4,7 @@ """Deals with loading & saving .size and .sizediff files. -The .size file is written in the following format. There are no section -delimiters, instead the end of a section is usually determined by a row count on -the first line of a section, followed by that number of rows. In other cases, -the sections have a known size. - -Header ------- -4 lines long. -Line 0 of the file is a header comment. -Line 1 is the serialization version of the file. -Line 2 is the number of characters in the header fields string. -Line 3 is the header fields string, a stringified JSON object. - -Path list ---------- -A list of paths. The first line is the size of the list, -and the next N lines that follow are items in the list. Each item is a tuple -of (object_path, source_path) where the two parts are tab separated. - -Component list --------------- -A list of components. The first line is the size of the list, -and the next N lines that follow are items in the list. Each item is a unique -COMPONENT which is referenced later. -This section is only present if 'has_components' is True in header fields. - -Symbol counts -------------- -2 lines long. -The first line is a tab separated list of section names. -The second line is a tab separated list of symbol group lengths, in the same -order as the previous line. - -Numeric values --------------- -In each section, the number of rows is the same as the number of section names -in Symbol counts. The values on a row are space separated, in the order of the -symbols in each group. - -Addresses -~~~~~~~~~~ -Symbol start addresses which are delta-encoded. - -Sizes -~~~~~ -The number of bytes this symbol takes up. - -Padding -~~~~~~~ -The number of padding bytes this symbol has. -This section is only present if 'has_padding' is True in header fields. - -Path indices -~~~~~~~~~~~~~ -Indices that reference paths in the prior Path list section. Delta-encoded. - -Component indices -~~~~~~~~~~~~~~~~~~ -Indices that reference components in the prior Component list section. -Delta-encoded. -This section is only present if 'has_components' is True in header fields. - -Symbols -------- -The final section contains details info on each symbol. Each line represents -a single symbol. Values are tab separated and follow this format: -symbol.full_name, symbol.num_aliases, symbol.flags -|num_aliases| will be omitted if the aliases of the symbol are the same as the -previous line. |flags| will be omitted if there are no flags. - - - -The .sizediff file stores a sparse representation of a difference between .size -files. Each .sizediff file stores two sparse .size files, before and after, -containing only symbols that differed between "before" and "after". They can -be rendered via the Tiger viewer. .sizediff files use the following format: - -Header ------- -3 lines long. -Line 0 of the file is a header comment. -Line 1 is the number of characters in the header fields string. -Line 2 is the header fields string, a stringified JSON object. This currently -contains two fields, 'before_length' (the length in bytes of the 'before' -section) and 'version', which is always 1. - -Before ------- -The next |header.before_length| bytes are a valid gzipped sparse .size file -containing the "before" snapshot. - -After ------ -All remaining bytes are a valid gzipped sparse .size file containing the -"after" snapshot. +See docs/file_format.md for a specification of the file formats. """ import contextlib
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index bbf57b4e..6538692 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3113,6 +3113,7 @@ <int value="23" label="LAUNCH_SOURCE_INTENT_URL"/> <int value="24" label="LAUNCH_SOURCE_RUN_ON_OS_LOGIN"/> <int value="25" label="LAUNCH_SOURCE_PROTOCOL_HANDLER"/> + <int value="26" label="LAUNCH_SOURCE_REPARENTING"/> </enum> <enum name="AppleScriptCommandEvents"> @@ -36697,7 +36698,7 @@ <int value="4104" label="V8UDPSocket_Close_Method"/> <int value="4105" label="HTMLInputElementSimulatedClick"/> <int value="4106" label="RTCLocalSdpModificationIceUfragPwd"/> - <int value="4107" label="V8Navigator_DeprecatedURNToURL_Method"/> + <int value="4107" label="WebNfcNdefMakeReadOnly"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -50847,6 +50848,7 @@ <int value="-1951046208" label="SidePanelPrototype:disabled"/> <int value="-1950469963" label="SeparatePointingStickSettings:enabled"/> <int value="-1948540128" label="disable-webrtc-hw-encoding (deprecated)"/> + <int value="-1948261745" label="EnforceAshExtensionKeeplist:disabled"/> <int value="-1948236151" label="DrawPredictedInkPoint:disabled"/> <int value="-1946595906" label="enable-push-api-background-mode"/> <int value="-1946522787" label="VrCustomTabBrowsing:disabled"/> @@ -54864,6 +54866,7 @@ <int value="988981463" label="ImageCaptureAPI:enabled"/> <int value="989062160" label="ModuleScriptsImportMetaUrl:enabled"/> <int value="993486662" label="BorealisForceBetaClient:enabled"/> + <int value="993539774" label="EnforceAshExtensionKeeplist:enabled"/> <int value="994317727" label="AutofillSaveCreditCardUsesStrikeSystem:disabled"/> <int value="995112715" label="AutoDisableAccessibility:disabled"/>
diff --git a/tools/metrics/histograms/metadata/crostini/histograms.xml b/tools/metrics/histograms/metadata/crostini/histograms.xml index 7cfdc8d64..6e19286 100644 --- a/tools/metrics/histograms/metadata/crostini/histograms.xml +++ b/tools/metrics/histograms/metadata/crostini/histograms.xml
@@ -464,7 +464,7 @@ </histogram> <histogram name="Crostini.Sshfs.Mount.Result.{Visibility}" - enum="CrostiniSshfsResult" expires_after="2022-02-14"> + enum="CrostiniSshfsResult" expires_after="2022-08-14"> <owner>davidmunro@google.com</owner> <owner>clumptini@google.com</owner> <summary> @@ -483,7 +483,7 @@ </histogram> <histogram name="Crostini.Sshfs.Mount.TimeTaken" units="ms" - expires_after="2022-02-14"> + expires_after="2022-08-14"> <owner>davidmunro@google.com</owner> <owner>clumptini@google.com</owner> <summary> @@ -493,7 +493,7 @@ </histogram> <histogram name="Crostini.Sshfs.Unmount.Result" enum="BooleanSuccess" - expires_after="2022-02-14"> + expires_after="2022-08-14"> <owner>davidmunro@google.com</owner> <owner>clumptini@google.com</owner> <summary> @@ -503,7 +503,7 @@ </histogram> <histogram name="Crostini.Sshfs.Unmount.TimeTaken" units="ms" - expires_after="2022-02-14"> + expires_after="2022-08-14"> <owner>davidmunro@google.com</owner> <owner>clumptini@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index 65ce1df..0e290e112 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -92,6 +92,18 @@ </summary> </histogram> +<histogram name="Media.Android.BecomingNoisy" enum="Boolean" + expires_after="2022-07-01"> + <owner>liberato@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Android-specific metric. Occasionally, we cannot start a foreground service + when headphones are unplugged. This tracks how often that occurs, which is + one recorded boolean per "user unplugs headphones while media is + playing". See https://crbug.com/1245017 for more details. + </summary> +</histogram> + <histogram name="Media.Android.GetColorSpaceError" enum="BooleanError" expires_after="2022-06-12"> <owner>vasilyt@chromium.org</owner>
diff --git a/tools/traffic_annotation/scripts/annotation_tokenizer.py b/tools/traffic_annotation/scripts/annotation_tokenizer.py index 06a5d1ae..c5b70ba 100644 --- a/tools/traffic_annotation/scripts/annotation_tokenizer.py +++ b/tools/traffic_annotation/scripts/annotation_tokenizer.py
@@ -22,7 +22,7 @@ # String literal. "string" or R"(string)". In Java, this will incorrectly # accept R-strings, which aren't part of the language's syntax. But since # that wouldn't compile anyways, we can just ignore this issue. - ('string_literal', re.compile(r'"((?:[^"]|\\.)*?)"|R"\((.*?)\)"', + ('string_literal', re.compile(r'"((?:\\.|[^"])*?)"|R"\((.*?)\)"', re.DOTALL)), # The '+' operator, for string concatenation. Java doesn't have multi-line # string literals, so this is the only way to keep long strings readable. It @@ -97,7 +97,13 @@ for (token_type, regex) in TOKEN_REGEXEN: re_match = regex.match(self.body, pos) if re_match: + raw_token = re_match.group(0) token_content = next(g for g in re_match.groups() if g is not None) + if token_type == 'string_literal' and not raw_token.startswith('R"'): + # Remove the extra backslash in backslash sequences, but only in + # non-R strings. R-strings don't need escaping. + backslash_regex = re.compile(r'\\(\\|")') + token_content = backslash_regex.sub(r'\1', token_content) token = Token(token_type, token_content, re_match.end()) break
diff --git a/tools/traffic_annotation/scripts/annotation_tokenizer_test.py b/tools/traffic_annotation/scripts/annotation_tokenizer_test.py index b9db5233..faefc5aa 100755 --- a/tools/traffic_annotation/scripts/annotation_tokenizer_test.py +++ b/tools/traffic_annotation/scripts/annotation_tokenizer_test.py
@@ -96,6 +96,15 @@ self.assertEqual('world', tokenizer.maybe_advance('symbol')) self.assertEqual(None, tokenizer.maybe_advance('right_paren')) + def testEscaping(self): + tokenizer = Tokenizer( + ''' + "\\"abc \\\\\\" def \\\\\\"" + "string ends here:\\\\" this is not part of the string" + ''', 'foo.txt', 33) + self.assertEqual('"abc \\" def \\"', tokenizer.advance('string_literal')) + self.assertEqual('string ends here:\\', tokenizer.advance('string_literal')) + if __name__ == '__main__': unittest.main()
diff --git a/tools/traffic_annotation/scripts/test_data/ValidFile-stdout.txt b/tools/traffic_annotation/scripts/test_data/ValidFile-stdout.txt index dbac3cb..332b238 100644 --- a/tools/traffic_annotation/scripts/test_data/ValidFile-stdout.txt +++ b/tools/traffic_annotation/scripts/test_data/ValidFile-stdout.txt
@@ -8,7 +8,7 @@ sender: 'sender1' description: 'desc1' trigger: 'trigger1' -data: 'data1' +data: 'data1 contains \'quotes ' destination: GOOGLE_OWNED_SERVICE } policy { @@ -24,7 +24,32 @@ ==== ANNOTATION ENDS ==== ==== NEW ANNOTATION ==== ValidFile.java -39 +32 +Definition +id2 + +semantics { +sender: "sender1" +description: "desc1" +trigger: "trigger1 contains a backslash\ +" +data: "data1 contains \"quotes " +destination: GOOGLE_OWNED_SERVICE +} +policy { +cookies_allowed: NO +setting: "setting1" +chrome_policy { +SpellCheckServiceEnabled { +SpellCheckServiceEnabled: false +} +} +} +comments: "comment1" +==== ANNOTATION ENDS ==== +==== NEW ANNOTATION ==== +ValidFile.java +61 Definition test @@ -32,7 +57,7 @@ ==== ANNOTATION ENDS ==== ==== NEW ANNOTATION ==== ValidFile.java -38 +60 Definition missing @@ -40,7 +65,7 @@ ==== ANNOTATION ENDS ==== ==== NEW ANNOTATION ==== ValidFile.java -37 +59 Definition undefined
diff --git a/tools/traffic_annotation/scripts/test_data/ValidFile.java b/tools/traffic_annotation/scripts/test_data/ValidFile.java index 3df6c946..0aaa8e6 100644 --- a/tools/traffic_annotation/scripts/test_data/ValidFile.java +++ b/tools/traffic_annotation/scripts/test_data/ValidFile.java
@@ -14,7 +14,7 @@ + "sender: 'sender1'" + "description: 'desc1'" + "trigger: 'trigger1'" - + "data: 'data1'" + + "data: 'data1 contains \\'quotes '" + "destination: GOOGLE_OWNED_SERVICE" + "}" + "policy {" @@ -28,12 +28,34 @@ + "}" + "comments: 'comment1'"); + private static final NetworkTrafficAnnotationTag TRAFFIC_ANNOTATION_2 = + NetworkTrafficAnnotationTag.createComplete("id2", + "semantics {" + + "sender: \"sender1\"" + + "description: \"desc1\"" + + "trigger: \"trigger1 contains a backslash\\" + + "\"" + + "data: \"data1 contains \\\"quotes \"" + + "destination: GOOGLE_OWNED_SERVICE" + + "}" + + "policy {" + + "cookies_allowed: NO" + + "setting: \"setting1\"" + + "chrome_policy {" + + "SpellCheckServiceEnabled {" + + "SpellCheckServiceEnabled: false" + + "}" + + "}" + + "}" + + "comments: \"comment1\""); + private void doSomethingWith(NetworkTrafficAnnotationTag annotation) { // ... } public void fooBar() { doSomethingWith(TRAFFIC_ANNOTATION); + doSomethingWith(TRAFFIC_ANNOTATION_2); doSomethingWith(NetworkTrafficAnnotationTag.NO_TRAFFIC_ANNOTATION_YET); doSomethingWith(NetworkTrafficAnnotationTag.MISSING_TRAFFIC_ANNOTATION); doSomethingWith(NetworkTrafficAnnotationTag.TRAFFIC_ANNOTATION_FOR_TESTS);
diff --git a/ui/chromeos/styles/cros_colors.json5 b/ui/chromeos/styles/cros_colors.json5 index 98cd67f..14bcb97 100644 --- a/ui/chromeos/styles/cros_colors.json5 +++ b/ui/chromeos/styles/cros_colors.json5
@@ -121,6 +121,7 @@ text_highlight_color: { light: "rgba($google_blue_600_rgb, 0.3)", dark: "rgba($google_blue_400_rgb, 0.3)", + generate_per_mode: true, }, /* @@ -188,6 +189,7 @@ light: "$google_blue_50", dark: "rgba($google_blue_300_rgb, 0.3)", debug: "rgba($google_red_300_rgb, 0.3)", + generate_per_mode: true, }, highlight_color_error: { light: "$google_red_50",
diff --git a/ui/events/fuchsia/pointer_events_handler.cc b/ui/events/fuchsia/pointer_events_handler.cc index 2764d5d..1acbc32b1 100644 --- a/ui/events/fuchsia/pointer_events_handler.cc +++ b/ui/events/fuchsia/pointer_events_handler.cc
@@ -209,7 +209,7 @@ const auto& sample = event.pointer_sample(); auto timestamp = base::TimeTicks::FromZxTime(event.timestamp()); - PointerDetails pointer_details(EventPointerType::kTouch, sample.device_id()); + PointerDetails pointer_details(EventPointerType::kMouse, sample.device_id()); // View parameters can change mid-interaction; apply transform on the fly. auto logical = ViewportToViewCoordinates(sample.position_in_viewport(),
diff --git a/ui/events/fuchsia/pointer_events_handler_unittest.cc b/ui/events/fuchsia/pointer_events_handler_unittest.cc index 7a30714..4ffaff0f 100644 --- a/ui/events/fuchsia/pointer_events_handler_unittest.cc +++ b/ui/events/fuchsia/pointer_events_handler_unittest.cc
@@ -81,6 +81,8 @@ ASSERT_EQ(events.size(), 1u); EXPECT_TRUE(events[0]->IsTouchEvent()); + EXPECT_EQ(events[0]->AsTouchEvent()->pointer_details().pointer_type, + EventPointerType::kTouch); std::vector<fup::MouseEvent> mouse_events = MouseEventBuilder() @@ -94,6 +96,8 @@ ASSERT_EQ(events.size(), 2u); EXPECT_TRUE(events[1]->IsMouseEvent()); + EXPECT_EQ(events[1]->AsMouseEvent()->pointer_details().pointer_type, + EventPointerType::kMouse); } TEST_F(PointerEventsHandlerTest, Data_FuchsiaTimeVersusChromeTime) {
diff --git a/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js b/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js index 5fe5a92..9f078472 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js +++ b/ui/file_manager/file_manager/foreground/js/directory_tree_naming_controller.js
@@ -3,15 +3,14 @@ // found in the LICENSE file. import {assert} from 'chrome://resources/js/assert.m.js'; -import {AlertDialog} from 'chrome://resources/js/cr/ui/dialogs.m.js'; -import {getParentEntry} from '../../common/js/api.js'; import {util} from '../../common/js/util.js'; import {VolumeInfo} from '../../externs/volume_info.js'; import {DirectoryModel} from './directory_model.js'; -import {getRenameErrorMessage, renameEntry, validateExternalDriveName, validateFileName} from './file_rename.js'; +import {renameEntry, validateEntryName} from './file_rename.js'; import {DirectoryItem, DirectoryTree} from './ui/directory_tree.js'; +import {FilesAlertDialog} from './ui/files_alert_dialog.js'; /** * Naming controller for directory tree. @@ -20,7 +19,7 @@ /** * @param {!DirectoryModel} directoryModel * @param {!DirectoryTree} directoryTree - * @param {!AlertDialog} alertDialog + * @param {!FilesAlertDialog} alertDialog */ constructor(directoryModel, directoryTree, alertDialog) { /** @private @const {!DirectoryModel} */ @@ -29,7 +28,7 @@ /** @private @const {!DirectoryTree} */ this.directoryTree_ = directoryTree; - /** @private @const {!AlertDialog} */ + /** @private @const {!FilesAlertDialog} */ this.alertDialog_ = alertDialog; /** @private {?DirectoryItem} */ @@ -141,21 +140,14 @@ } try { - if (this.isRemovableRoot_) { - validateExternalDriveName( - newName, - assert(this.volumeInfo_ && this.volumeInfo_.diskFileSystemType)); - this.performExternalDriveRename_(entry, newName); - return; - } - const parentEntry = await getParentEntry(entry); - await validateFileName( - parentEntry, newName, - this.directoryModel_.getFileFilter().isHiddenFilesVisible()); + await validateEntryName( + entry, newName, + this.directoryModel_.getFileFilter().isHiddenFilesVisible(), + this.volumeInfo_, this.isRemovableRoot_); await this.performRename_(entry, newName); } catch (error) { - this.alertDialog_.show( - /** @type {string} */ (error.message), this.detach_.bind(this)); + await this.alertDialog_.showAsync(/** @type {string} */ (error.message)); + this.editing_ = true; } } @@ -176,12 +168,20 @@ // TODO(yawano): Rename might take time on some volumes. Optimistically show // new name in the UI before actual rename is completed. try { - const newEntry = await renameEntry(entry, newName); + const newEntry = await renameEntry( + entry, newName, this.volumeInfo_, this.isRemovableRoot_); // Put the new name in the .label element before detaching the // <input> to prevent showing the old name. this.getLabelElement_().textContent = newName; + // We currently don't have promises/callbacks for when removableRoots are + // successfully renamed, so we can't update their subdirectories or + // update the current directory to them at this point. + if (this.isRemovableRoot_) { + return; + } + this.currentDirectoryItem_.entry = newEntry; this.currentDirectoryItem_.updateSubDirectories(/* recursive= */ true); @@ -196,27 +196,10 @@ this.directoryModel_.setIgnoringCurrentDirectoryDeletion( /* ignore= */ false); - this.alertDialog_.show(getRenameErrorMessage( - /** @type {DOMError} */ (error), entry, newName)); + this.alertDialog_.show(/** @type {string} */ (error.message)); + } finally { + this.detach_(); } - - this.detach_(); - } - - /** - * Performs external drive rename operation. - * @param {!DirectoryEntry} entry - * @param {string} newName Validated name. - * @private - */ - performExternalDriveRename_(entry, newName) { - // Invoke external drive rename - chrome.fileManagerPrivate.renameVolume(this.volumeInfo_.volumeId, newName); - - // Put the new name in the .label element before detaching the <input> to - // prevent showing the old name. - this.getLabelElement_().textContent = newName; - this.detach_(); } /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_rename.js b/ui/file_manager/file_manager/foreground/js/file_rename.js index a75abfe..a69c8f5 100644 --- a/ui/file_manager/file_manager/foreground/js/file_rename.js +++ b/ui/file_manager/file_manager/foreground/js/file_rename.js
@@ -7,70 +7,71 @@ * by the files app frontend. */ +import {assert} from 'chrome://resources/js/assert.m.js'; + import {getEntry, getParentEntry, moveEntryTo, validatePathNameLength} from '../../common/js/api.js'; import {str, strf, util} from '../../common/js/util.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; +import {VolumeInfo} from '../../externs/volume_info.js'; /** - * Renames the entry to newName. - * @param {!Entry} entry The entry to be renamed. - * @param {string} newName The new name. - * @return {Promise<!Entry>} The renamed entry. + * Verifies name for file, folder, or removable root to be created or renamed. + * Names are restricted according to the target filesystem. + * + * @param {!Entry} entry The entry to be named. + * @param {string} name New file, folder, or removable root name. + * @param {boolean} areHiddenFilesVisible Whether to report hidden file + * name errors or not. + * @param {?VolumeInfo} volumeInfo Volume information about the target entry. + * @param {boolean} isRemovableRoot Whether the target is a removable root. + * @return {!Promise} Fulfills on success, throws error message otherwise. */ -export async function renameEntry(entry, newName) { - // Before moving, we need to check if there is an existing entry at - // parent/newName, since moveTo will overwrite it. - // Note that this way has some timing issue. After existing check, - // a new entry may be created in the background. However, there is no way not - // to overwrite the existing file, unfortunately. The risk should be low, - // assuming the unsafe period is very short. - - const parent = await getParentEntry(entry); - - try { - await getEntry(parent, newName, entry.isFile, {create: false}); - } catch (error) { - if (error.name == util.FileError.NOT_FOUND_ERR) { - return moveEntryTo(entry, parent, newName); - } - - // Unexpected error found. - throw error; +export async function validateEntryName( + entry, name, areHiddenFilesVisible, volumeInfo, isRemovableRoot) { + if (isRemovableRoot) { + const diskFileSystemType = volumeInfo && volumeInfo.diskFileSystemType; + validateExternalDriveName(name, assert(diskFileSystemType)); + } else { + const parentEntry = await getParentEntry(entry); + await validateFileName(parentEntry, name, areHiddenFilesVisible); } - - // The entry with the name already exists. - throw util.createDOMError(util.FileError.PATH_EXISTS_ERR); } /** - * Converts DOMError response from renameEntry() to error message - * @param {DOMError} error - * @param {!Entry} entry - * @param {string} newName - * @return {string} + * Verifies the user entered name for external drive to be + * renamed to. Name restrictions must correspond to the target filesystem + * restrictions. + * + * It also verifies that name length is in the limits of the filesystem. + * + * This function throws if the new label is invalid, else it completes. + * + * @param {string} name New external drive name. + * @param {!VolumeManagerCommon.FileSystemType} fileSystem */ -export function getRenameErrorMessage(error, entry, newName) { - if (error && - (error.name == util.FileError.PATH_EXISTS_ERR || - error.name == util.FileError.TYPE_MISMATCH_ERR)) { - // Check the existing entry is file or not. - // 1) If the entry is a file: - // a) If we get PATH_EXISTS_ERR, a file exists. - // b) If we get TYPE_MISMATCH_ERR, a directory exists. - // 2) If the entry is a directory: - // a) If we get PATH_EXISTS_ERR, a directory exists. - // b) If we get TYPE_MISMATCH_ERR, a file exists. - return strf( - (entry.isFile && error.name == util.FileError.PATH_EXISTS_ERR) || - (!entry.isFile && - error.name == util.FileError.TYPE_MISMATCH_ERR) ? - 'FILE_ALREADY_EXISTS' : - 'DIRECTORY_ALREADY_EXISTS', - newName); +export function validateExternalDriveName(name, fileSystem) { + // Verify if entered name for external drive respects restrictions + // provided by the target filesystem. + + const nameLength = name.length; + const lengthLimit = VolumeManagerCommon.FileSystemTypeVolumeNameLengthLimit; + + // Verify length for the target file system type. + if (lengthLimit.hasOwnProperty(fileSystem) && + nameLength > lengthLimit[fileSystem]) { + throw Error( + strf('ERROR_EXTERNAL_DRIVE_LONG_NAME', lengthLimit[fileSystem])); } - return strf( - 'ERROR_RENAMING', entry.name, util.getFileErrorString(error.name)); + // Checks if the name contains only alphanumeric characters or allowed + // special characters. This needs to stay in sync with + // cros-disks/filesystem_label.cc on the ChromeOS side. + const validCharRegex = /[a-zA-Z0-9 \!\#\$\%\&\(\)\-\@\^\_\`\{\}\~]/; + for (let i = 0; i < nameLength; i++) { + if (!validCharRegex.test(name[i])) { + throw Error(strf('ERROR_EXTERNAL_DRIVE_INVALID_CHARACTER', name[i])); + } + } } /** @@ -78,16 +79,16 @@ * renamed to. Name restrictions must correspond to File API restrictions * (see DOMFilePath::isValidPath). Curernt WebKit implementation is * out of date (spec is - * http://dev.w3.org/2009/dap/file-system/file-dir-sys.html, 8.3) and going to - * be fixed. Shows message box if the name is invalid. + * http://dev.w3.org/2009/dap/file-system/file-dir-sys.html, 8.3) and going + * to be fixed. Shows message box if the name is invalid. * * It also verifies if the name length is in the limit of the filesystem. * * @param {!DirectoryEntry} parentEntry The entry of the parent directory. * @param {string} name New file or folder name. - * @param {boolean} areHiddenFilesVisible Whether to report the hidden file name - * error or not. - * @return {Promise} Fulfills on success, throws error message otherwise. + * @param {boolean} areHiddenFilesVisible Whether to report the hidden file + * name error or not. + * @return {!Promise} Fulfills on success, throws error message otherwise. */ export async function validateFileName( parentEntry, name, areHiddenFilesVisible) { @@ -115,38 +116,85 @@ } /** - * Verifies the user entered name for external drive to be - * renamed to. Name restrictions must correspond to the target filesystem - * restrictions. - * - * It also verifies that name length is in the limits of the filesystem. - * - * This function throws if the new label is invalid, else it completes. - * - * @param {string} name New external drive name. - * @param {!VolumeManagerCommon.FileSystemType} fileSystem + * Renames file, folder, or removable root with newName. + * @param {!Entry} entry The entry to be renamed. + * @param {string} newName The new name. + * @param {?VolumeInfo} volumeInfo Volume information about the target entry. + * @param {boolean} isRemovableRoot Whether the target is a removable root. + * @return {!Promise<!Entry>} Resolves the renamed entry if successful, else + * throws error message. */ -export function validateExternalDriveName(name, fileSystem) { - // Verify if entered name for external drive respects restrictions provided by - // the target filesystem - - const nameLength = name.length; - const lengthLimit = VolumeManagerCommon.FileSystemTypeVolumeNameLengthLimit; - - // Verify length for the target file system type - if (lengthLimit.hasOwnProperty(fileSystem) && - nameLength > lengthLimit[fileSystem]) { - throw Error( - strf('ERROR_EXTERNAL_DRIVE_LONG_NAME', lengthLimit[fileSystem])); +export async function renameEntry(entry, newName, volumeInfo, isRemovableRoot) { + if (isRemovableRoot) { + chrome.fileManagerPrivate.renameVolume(volumeInfo.volumeId, newName); + return entry; } + return renameFile(entry, newName); +} - // Checks if the name contains only alphanumeric characters or allowed - // special characters. This needs to stay in sync with - // cros-disks/filesystem_label.cc on the ChromeOS side. - const validCharRegex = /[a-zA-Z0-9 \!\#\$\%\&\(\)\-\@\^\_\`\{\}\~]/; - for (let i = 0; i < nameLength; i++) { - if (!validCharRegex.test(name[i])) { - throw Error(strf('ERROR_EXTERNAL_DRIVE_INVALID_CHARACTER', name[i])); +/** + * Renames the entry to newName. + * @param {!Entry} entry The entry to be renamed. + * @param {string} newName The new name. + * @return {!Promise<!Entry>} Resolves the renamed entry if successful, else + * throws error message. + */ +export async function renameFile(entry, newName) { + try { + // Before moving, we need to check if there is an existing entry at + // parent/newName, since moveTo will overwrite it. + // Note that this way has a race condition. After existing check, + // a new entry may be created in the background. However, there is no way + // not to overwrite the existing file, unfortunately. The risk should be + // low, assuming the unsafe period is very short. + + const parent = await getParentEntry(entry); + + try { + await getEntry(parent, newName, entry.isFile, {create: false}); + } catch (error) { + if (error.name == util.FileError.NOT_FOUND_ERR) { + return moveEntryTo(entry, parent, newName); + } + + // Unexpected error found. + throw error; } + + // The entry with the name already exists. + throw util.createDOMError(util.FileError.PATH_EXISTS_ERR); + } catch (error) { + throw getRenameErrorMessage(error, entry, newName); } } + +/** + * Converts DOMError response from renameEntry() to error message. + * @param {DOMError} error + * @param {!Entry} entry + * @param {string} newName + * @return {!Error<string>} + */ +function getRenameErrorMessage(error, entry, newName) { + if (error && + (error.name == util.FileError.PATH_EXISTS_ERR || + error.name == util.FileError.TYPE_MISMATCH_ERR)) { + // Check the existing entry is file or not. + // 1) If the entry is a file: + // a) If we get PATH_EXISTS_ERR, a file exists. + // b) If we get TYPE_MISMATCH_ERR, a directory exists. + // 2) If the entry is a directory: + // a) If we get PATH_EXISTS_ERR, a directory exists. + // b) If we get TYPE_MISMATCH_ERR, a file exists. + return Error(strf( + (entry.isFile && error.name == util.FileError.PATH_EXISTS_ERR) || + (!entry.isFile && + error.name == util.FileError.TYPE_MISMATCH_ERR) ? + 'FILE_ALREADY_EXISTS' : + 'DIRECTORY_ALREADY_EXISTS', + newName)); + } + + return Error( + strf('ERROR_RENAMING', entry.name, util.getFileErrorString(error.name))); +}
diff --git a/ui/file_manager/file_manager/foreground/js/naming_controller.js b/ui/file_manager/file_manager/foreground/js/naming_controller.js index 1058d0d..7cc18973 100644 --- a/ui/file_manager/file_manager/foreground/js/naming_controller.js +++ b/ui/file_manager/file_manager/foreground/js/naming_controller.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {assert} from 'chrome://resources/js/assert.m.js'; -import {AlertDialog, ConfirmDialog} from 'chrome://resources/js/cr/ui/dialogs.m.js'; +import {ConfirmDialog} from 'chrome://resources/js/cr/ui/dialogs.m.js'; import {getFile} from '../../common/js/api.js'; import {strf, util} from '../../common/js/util.js'; @@ -11,8 +11,9 @@ import {FileFilter} from './directory_contents.js'; import {DirectoryModel} from './directory_model.js'; -import {getRenameErrorMessage, renameEntry, validateExternalDriveName, validateFileName} from './file_rename.js'; +import {renameEntry, validateEntryName, validateFileName} from './file_rename.js'; import {FileSelectionHandler} from './file_selection.js'; +import {FilesAlertDialog} from './ui/files_alert_dialog.js'; import {ListContainer} from './ui/list_container.js'; /** @@ -21,7 +22,7 @@ export class NamingController { /** * @param {!ListContainer} listContainer - * @param {!AlertDialog} alertDialog + * @param {!FilesAlertDialog} alertDialog * @param {!ConfirmDialog} confirmDialog * @param {!DirectoryModel} directoryModel * @param {!FileFilter} fileFilter @@ -33,7 +34,7 @@ /** @private @const {!ListContainer} */ this.listContainer_ = listContainer; - /** @private @const {!AlertDialog} */ + /** @private @const {!FilesAlertDialog} */ this.alertDialog_ = alertDialog; /** @private @const {!ConfirmDialog} */ @@ -80,13 +81,11 @@ try { await validateFileName( parentEntry, name, this.fileFilter_.isHiddenFilesVisible()); + return true; } catch (error) { - await new Promise( - (resolve) => this.alertDialog_.show( - /** @type {string} */ (error), resolve)); + await this.alertDialog_.showAsync(/** @type {string} */ (error.message)); return false; } - return true; } /** @@ -282,40 +281,23 @@ const volumeInfo = this.volumeInfo_; const isRemovableRoot = this.isRemovableRoot_; - let isValid = false; - input.validation_ = true; - if (isRemovableRoot) { - try { - const diskFileSystemType = - assert(volumeInfo && volumeInfo.diskFileSystemType); - validateExternalDriveName(newName, diskFileSystemType); - isValid = true; - } catch (error) { - isValid = false; - await new Promise( - (resolve) => this.alertDialog_.show( - /** @type {string} */ (error.message), resolve)); - } - } else { - // TODO(mtomasz): this.getCurrentDirectoryEntry() might not return the - // actual parent if the directory content is a search result. Fix it to do - // proper validation. - isValid = await this.validateFileName( - /** @type {!DirectoryEntry} */ ( - this.directoryModel_.getCurrentDirEntry()), - newName); - } + try { + input.validation_ = true; + await validateEntryName( + entry, newName, false, volumeInfo, isRemovableRoot); + } catch (error) { + await this.alertDialog_.showAsync(/** @type {string} */ (error.message)); - input.validation_ = false; - - if (!isValid) { // Cancel rename if it fails to restore focus from alert dialog. // Otherwise, just cancel the commitment and continue to rename. if (document.activeElement != input) { this.cancelRename_(); } + return; + } finally { + input.validation_ = false; } // Validation succeeded. Do renaming. @@ -330,12 +312,11 @@ nameNode.textContent = newName; try { - let newEntry; - if (isRemovableRoot) { - newEntry = entry; - chrome.fileManagerPrivate.renameVolume(volumeInfo.volumeId, newName); - } else { - newEntry = await renameEntry(entry, newName); + const newEntry = + await renameEntry(entry, newName, volumeInfo, isRemovableRoot); + + // RemovableRoot doesn't have a callback to report renaming is done. + if (!isRemovableRoot) { await this.directoryModel_.onRenameEntry(entry, assert(newEntry)); } @@ -357,8 +338,7 @@ this.listContainer_.endBatchUpdates(); // Show error dialog. - const message = getRenameErrorMessage(error, entry, newName); - this.alertDialog_.show(message); + this.alertDialog_.show(error.message); } }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/files_alert_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/files_alert_dialog.js index c303b299..b73d586 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/files_alert_dialog.js +++ b/ui/file_manager/file_manager/foreground/js/ui/files_alert_dialog.js
@@ -66,4 +66,13 @@ this.frame.classList.toggle('no-title', !title); super.showHtml(title, message, ...args); } + + /** + * Async version of show(). + * @param {string} title + * @returns {!Promise<void>} Resolves when dismissed. + */ + showAsync(title) { + return new Promise(resolve => this.show(title, resolve)); + } }
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 2661841..437960d 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -434,6 +434,8 @@ "test/test_viewporter.h", "test/test_wayland_server_thread.cc", "test/test_wayland_server_thread.h", + "test/test_wp_pointer_gestures.cc", + "test/test_wp_pointer_gestures.h", "test/test_xdg_popup.cc", "test/test_xdg_popup.h", "test/test_zcr_text_input_extension.cc", @@ -464,6 +466,7 @@ "//third_party/wayland-protocols:gtk_primary_selection_protocol", "//third_party/wayland-protocols:linux_dmabuf_protocol", "//third_party/wayland-protocols:linux_explicit_synchronization_protocol", + "//third_party/wayland-protocols:pointer_gestures_protocol", "//third_party/wayland-protocols:presentation_time_protocol", "//third_party/wayland-protocols:primary_selection_protocol", "//third_party/wayland-protocols:text_input_extension_protocol", @@ -494,6 +497,7 @@ "host/wayland_window_manager_unittests.cc", "host/wayland_window_unittest.cc", "host/wayland_zaura_shell_unittest.cc", + "host/wayland_zwp_pointer_gestures_unittest.cc", "test/wayland_drag_drop_test.cc", "test/wayland_drag_drop_test.h", "test/wayland_test.cc",
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h index e8c036e8..911275d 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.h +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
@@ -219,6 +219,10 @@ return wayland_zwp_pointer_constraints_.get(); } + WaylandZwpPointerGestures* wayland_zwp_pointer_gestures() const { + return wayland_zwp_pointer_gestures_.get(); + } + WaylandZwpRelativePointerManager* wayland_zwp_relative_pointer_manager() const { return wayland_zwp_relative_pointer_manager_.get();
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc index 5c29233..103313f 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.cc +++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -425,11 +425,11 @@ const gfx::Vector2dF& delta, base::TimeTicks timestamp, int device_id, - absl::optional<float> scale) { + absl::optional<float> scale_delta) { GestureEventDetails details(event_type); details.set_device_type(GestureDeviceType::DEVICE_TOUCHPAD); - if (scale) - details.set_scale(*scale); + if (scale_delta) + details.set_scale(*scale_delta); auto location = pointer_location_ + delta; GestureEvent event(location.x(), location.y(), 0 /* flags */, timestamp,
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h index 6768bf2..ff314b1 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.h +++ b/ui/ozone/platform/wayland/host/wayland_event_source.h
@@ -128,7 +128,7 @@ const gfx::Vector2dF& delta, base::TimeTicks timestamp, int device_id, - absl::optional<float> scale) override; + absl::optional<float> scale_delta) override; // WaylandZwpRelativePointerManager::Delegate: void SetRelativePointerMotionEnabled(bool enabled) override;
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.cc b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.cc index 8a90ebe..fdc4dbf5 100644 --- a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.cc +++ b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.cc
@@ -87,13 +87,15 @@ uint32_t time, struct wl_surface* surface, uint32_t fingers) { - auto* thiz = static_cast<WaylandZwpPointerGestures*>(data); + auto* self = static_cast<WaylandZwpPointerGestures*>(data); base::TimeTicks timestamp = base::TimeTicks() + base::Milliseconds(time); - thiz->delegate_->OnPinchEvent(ET_GESTURE_PINCH_BEGIN, + self->current_scale_ = 1; + + self->delegate_->OnPinchEvent(ET_GESTURE_PINCH_BEGIN, gfx::Vector2dF() /*delta*/, timestamp, - thiz->obj_.id()); + self->obj_.id()); } // static @@ -105,14 +107,23 @@ wl_fixed_t dy, wl_fixed_t scale, wl_fixed_t rotation) { - auto* thiz = static_cast<WaylandZwpPointerGestures*>(data); + auto* self = static_cast<WaylandZwpPointerGestures*>(data); + + // During the pinch zoom session, libinput sends the current scale relative to + // the start of the session. On the other hand, the compositor expects the + // change of the scale relative to the previous update in form of a multiplier + // applied to the current value. + // See https://crbug.com/1283652 + const auto new_scale = wl_fixed_to_double(scale); + const auto scale_delta = new_scale / self->current_scale_; + self->current_scale_ = new_scale; base::TimeTicks timestamp = base::TimeTicks() + base::Milliseconds(time); gfx::Vector2dF delta = {static_cast<float>(wl_fixed_to_double(dx)), static_cast<float>(wl_fixed_to_double(dy))}; - thiz->delegate_->OnPinchEvent(ET_GESTURE_PINCH_UPDATE, delta, timestamp, - thiz->obj_.id(), wl_fixed_to_double(scale)); + self->delegate_->OnPinchEvent(ET_GESTURE_PINCH_UPDATE, delta, timestamp, + self->obj_.id(), scale_delta); } void WaylandZwpPointerGestures::OnPinchEnd( @@ -121,13 +132,13 @@ uint32_t serial, uint32_t time, int32_t cancelled) { - auto* thiz = static_cast<WaylandZwpPointerGestures*>(data); + auto* self = static_cast<WaylandZwpPointerGestures*>(data); base::TimeTicks timestamp = base::TimeTicks() + base::Milliseconds(time); - thiz->delegate_->OnPinchEvent(ET_GESTURE_PINCH_END, + self->delegate_->OnPinchEvent(ET_GESTURE_PINCH_END, gfx::Vector2dF() /*delta*/, timestamp, - thiz->obj_.id()); + self->obj_.id()); } } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h index 884deb1..de8e4e2 100644 --- a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h +++ b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h
@@ -70,17 +70,25 @@ wl::Object<zwp_pointer_gestures_v1> obj_; wl::Object<zwp_pointer_gesture_pinch_v1> pinch_; + double current_scale_ = 1; WaylandConnection* const connection_; Delegate* const delegate_; }; class WaylandZwpPointerGestures::Delegate { public: - virtual void OnPinchEvent(EventType event_type, - const gfx::Vector2dF& delta, - base::TimeTicks timestamp, - int device_id, - absl::optional<float> scale = absl::nullopt) = 0; + // Handles the events coming during the pinch zoom session. + // |event_type| is one of ET_GESTURE_PINCH_### members. + // |delta| is empty on the BEGIN and END, and shows the movement of the centre + // of the gesture compared to the previous event. + // |scale_delta| is the change to the scale compared to the previous event, to + // be applied as multiplier (as the compositor expects it). + virtual void OnPinchEvent( + EventType event_type, + const gfx::Vector2dF& delta, + base::TimeTicks timestamp, + int device_id, + absl::optional<float> scale_delta = absl::nullopt) = 0; }; } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures_unittest.cc b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures_unittest.cc new file mode 100644 index 0000000..c9a84951 --- /dev/null +++ b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures_unittest.cc
@@ -0,0 +1,129 @@ +// Copyright 2022 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 <pointer-gestures-unstable-v1-server-protocol.h> +#include <wayland-util.h> + +#include "ui/events/event.h" +#include "ui/events/platform/platform_event_observer.h" +#include "ui/ozone/platform/wayland/host/wayland_event_source.h" +#include "ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h" +#include "ui/ozone/platform/wayland/test/mock_surface.h" +#include "ui/ozone/platform/wayland/test/wayland_test.h" + +namespace ui { + +namespace { + +// Observes events, filters the pinch zoom updates, and records the latest +// update to the scale. +class PinchEventScaleRecorder : public PlatformEventObserver { + public: + PinchEventScaleRecorder() { + PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); + } + + PinchEventScaleRecorder(const PinchEventScaleRecorder&) = delete; + PinchEventScaleRecorder& operator=(const PinchEventScaleRecorder&) = delete; + + ~PinchEventScaleRecorder() override { + PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this); + } + + double latest_scale_update() const { return latest_scale_update_; } + + protected: + // PlatformEventObserver: + void WillProcessEvent(const PlatformEvent& event) override { + if (!event->IsGestureEvent()) + return; + + const GestureEvent* const gesture = event->AsGestureEvent(); + if (!gesture->IsPinchEvent() || gesture->type() != ET_GESTURE_PINCH_UPDATE) + return; + + latest_scale_update_ = gesture->details().scale(); + } + + void DidProcessEvent(const PlatformEvent& event) override {} + + double latest_scale_update_ = 1.0; +}; + +} // namespace + +class WaylandPointerGesturesTest : public WaylandTest { + public: + WaylandPointerGesturesTest() = default; + WaylandPointerGesturesTest(const WaylandPointerGesturesTest&) = delete; + WaylandPointerGesturesTest& operator=(const WaylandPointerGesturesTest&) = + delete; + ~WaylandPointerGesturesTest() override = default; + + void SetUp() override { + WaylandTest::SetUp(); + + // Pointer capability is required for gesture objects to be initialised. + wl_seat_send_capabilities(server_.seat()->resource(), + WL_SEAT_CAPABILITY_POINTER); + + Sync(); + + ASSERT_TRUE(connection_->wayland_zwp_pointer_gestures()); + } +}; + +// Tests that scale in pinch zoom events is fixed to the progression expected by +// the compositor. +// +// During the pinch zoom session, libinput sends the current scale relative to +// the start of the session. The compositor, however, expects every update to +// have the relative change of the scale, compared to the previous update in +// form of a multiplier applied to the current value. The factor is fixed at +// the low level immediately after values are received from the server via +// WaylandZwpPointerGestures methods. +// +// See https://crbug.com/1283652 +TEST_P(WaylandPointerGesturesTest, PinchZoomScale) { + auto* const mock_surface = server_.GetObject<wl::MockSurface>( + window_->root_surface()->GetSurfaceId()); + + PinchEventScaleRecorder observer; + + auto* pinch_resource = server_.wp_pointer_gestures().pinch()->resource(); + zwp_pointer_gesture_pinch_v1_send_begin(pinch_resource, + /* serial */ 0, + /* time */ 0, + mock_surface->resource(), + /* fingers */ 2); + Sync(); + + constexpr double kScales[] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.4, + 1.3, 1.2, 1.1, 1.0, 0.9, 0.8, 0.7, + 0.6, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + auto previous_scale = kScales[0]; + for (auto scale : kScales) { + zwp_pointer_gesture_pinch_v1_send_update( + pinch_resource, /* time */ 0, /* dx */ 0, /* dy */ 0, + wl_fixed_from_double(scale), /* rotation */ 0); + Sync(); + // The conversion from double to fixed and back is necessary because it + // happens during the roundtrip, and it creates significant error. + EXPECT_FLOAT_EQ( + observer.latest_scale_update(), + wl_fixed_to_double(wl_fixed_from_double(scale)) / previous_scale); + previous_scale = wl_fixed_to_double(wl_fixed_from_double(scale)); + } +} + +INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest, + WaylandPointerGesturesTest, + testing::Values(wl::ServerConfig{ + .shell_version = wl::ShellVersion::kStable})); +INSTANTIATE_TEST_SUITE_P(XdgVersionV6Test, + WaylandPointerGesturesTest, + testing::Values(wl::ServerConfig{ + .shell_version = wl::ShellVersion::kV6})); + +} // namespace ui
diff --git a/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc b/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc index ae8b653..2450c2e 100644 --- a/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc +++ b/ui/ozone/platform/wayland/test/test_wayland_server_thread.cc
@@ -98,6 +98,8 @@ return false; if (!surface_augmenter_.Initialize(display_.get())) return false; + if (!wp_pointer_gestures_.Initialize(display_.get())) + return false; client_ = wl_client_create(display_.get(), server_fd.release()); if (!client_)
diff --git a/ui/ozone/platform/wayland/test/test_wayland_server_thread.h b/ui/ozone/platform/wayland/test/test_wayland_server_thread.h index 7684293..33ed4b5 100644 --- a/ui/ozone/platform/wayland/test/test_wayland_server_thread.h +++ b/ui/ozone/platform/wayland/test/test_wayland_server_thread.h
@@ -27,6 +27,7 @@ #include "ui/ozone/platform/wayland/test/test_subcompositor.h" #include "ui/ozone/platform/wayland/test/test_surface_augmenter.h" #include "ui/ozone/platform/wayland/test/test_viewporter.h" +#include "ui/ozone/platform/wayland/test/test_wp_pointer_gestures.h" #include "ui/ozone/platform/wayland/test/test_zcr_text_input_extension.h" #include "ui/ozone/platform/wayland/test/test_zwp_linux_explicit_synchronization.h" #include "ui/ozone/platform/wayland/test/test_zwp_text_input_manager.h" @@ -121,6 +122,8 @@ return primary_selection_device_manager_.get(); } + TestWpPointerGestures& wp_pointer_gestures() { return wp_pointer_gestures_; } + void set_output_delegate(OutputDelegate* delegate) { output_delegate_ = delegate; } @@ -160,6 +163,7 @@ TestZwpLinuxExplicitSynchronizationV1 zwp_linux_explicit_synchronization_v1_; MockZwpLinuxDmabufV1 zwp_linux_dmabuf_v1_; MockWpPresentation wp_presentation_; + TestWpPointerGestures wp_pointer_gestures_; std::unique_ptr<TestSelectionDeviceManager> primary_selection_device_manager_; std::vector<std::unique_ptr<GlobalObject>> globals_;
diff --git a/ui/ozone/platform/wayland/test/test_wp_pointer_gestures.cc b/ui/ozone/platform/wayland/test/test_wp_pointer_gestures.cc new file mode 100644 index 0000000..ae606fb --- /dev/null +++ b/ui/ozone/platform/wayland/test/test_wp_pointer_gestures.cc
@@ -0,0 +1,65 @@ +// Copyright 2022 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 "ui/ozone/platform/wayland/test/test_wp_pointer_gestures.h" + +#include <pointer-gestures-unstable-v1-server-protocol.h> +#include <wayland-server-core.h> + +#include "base/logging.h" +#include "base/notreached.h" + +namespace wl { + +namespace { + +const struct zwp_pointer_gesture_pinch_v1_interface kTestPinchImpl = { + DestroyResource}; + +constexpr uint32_t kInterfaceVersion = 1; + +} // namespace + +const struct zwp_pointer_gestures_v1_interface kInterfaceImpl = { + TestWpPointerGestures::GetSwipeGesture, + TestWpPointerGestures::GetPinchGesture, + DestroyResource, +}; + +TestWpPointerGestures::TestWpPointerGestures() + : GlobalObject(&zwp_pointer_gestures_v1_interface, + &kInterfaceImpl, + kInterfaceVersion) {} + +TestWpPointerGestures::~TestWpPointerGestures() = default; + +// static +void TestWpPointerGestures::GetSwipeGesture(struct wl_client* client, + struct wl_resource* resource, + uint32_t id, + struct wl_resource* pointer) { + NOTIMPLEMENTED_LOG_ONCE(); +} + +// static +void TestWpPointerGestures::GetPinchGesture( + struct wl_client* client, + struct wl_resource* pointer_gestures_resource, + uint32_t id, + struct wl_resource* pointer) { + wl_resource* pinch_gesture_resource = + CreateResourceWithImpl<TestPinchGesture>( + client, &zwp_pointer_gesture_pinch_v1_interface, 1, &kTestPinchImpl, + id); + + GetUserDataAs<TestWpPointerGestures>(pointer_gestures_resource)->pinch_ = + GetUserDataAs<TestPinchGesture>(pinch_gesture_resource); +} + +TestPinchGesture::TestPinchGesture(wl_resource* resource) + : ServerObject(resource) {} + +TestPinchGesture::~TestPinchGesture() = default; + +} // namespace wl
diff --git a/ui/ozone/platform/wayland/test/test_wp_pointer_gestures.h b/ui/ozone/platform/wayland/test/test_wp_pointer_gestures.h new file mode 100644 index 0000000..d275dee9 --- /dev/null +++ b/ui/ozone/platform/wayland/test/test_wp_pointer_gestures.h
@@ -0,0 +1,50 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_WP_POINTER_GESTURES_H_ +#define UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_WP_POINTER_GESTURES_H_ + +#include "ui/ozone/platform/wayland/test/global_object.h" +#include "ui/ozone/platform/wayland/test/server_object.h" + +struct wl_client; +struct wl_resource; + +namespace wl { + +class TestPinchGesture : public ServerObject { + public: + explicit TestPinchGesture(wl_resource* resource); + TestPinchGesture(const TestPinchGesture&) = delete; + TestPinchGesture& operator=(const TestPinchGesture&) = delete; + ~TestPinchGesture() override; +}; + +// Manage zwp_linux_dmabuf_v1 object. +class TestWpPointerGestures : public GlobalObject { + public: + TestWpPointerGestures(); + TestWpPointerGestures(const TestWpPointerGestures&) = delete; + TestWpPointerGestures& operator=(const TestWpPointerGestures&) = delete; + ~TestWpPointerGestures() override; + + TestPinchGesture* pinch() const { return pinch_; } + + static void GetSwipeGesture(struct wl_client* client, + struct wl_resource* resource, + uint32_t id, + struct wl_resource* pointer); + + static void GetPinchGesture(struct wl_client* client, + struct wl_resource* pointer_gestures_resource, + uint32_t id, + struct wl_resource* pointer); + + private: + TestPinchGesture* pinch_; +}; + +} // namespace wl + +#endif // UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_WP_POINTER_GESTURES_H_
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js index 52f8e51..5d78049 100644 --- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js +++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js
@@ -221,6 +221,9 @@ /** @private {?ConfirmCodeCallback} */ this.confirmCodeCallback_ = null; + + /** @private {?function()} */ + this.onBluetoothDiscoveryStartedCallbackForTest_ = null; } ready() { @@ -275,6 +278,13 @@ /** @override */ onBluetoothDiscoveryStarted(handler) { this.devicePairingHandler_ = handler; + + // Inform tests that onBluetoothDiscoveryStarted() has been called. This is + // to ensure tests don't progress until |devicePairingHandler_| has been + // set. + if (this.onBluetoothDiscoveryStartedCallbackForTest_) { + this.onBluetoothDiscoveryStartedCallbackForTest_(); + } } /** @override */ @@ -283,6 +293,18 @@ // selection page. this.bluetoothDiscoveryDelegateReceiver_.$.close(); this.selectedPageId_ = BluetoothPairingSubpageId.DEVICE_SELECTION_PAGE; + this.devicePairingHandler_ = null; + } + + /** + * Returns a promise that will be resolved the next time + * onBluetoothDiscoveryStarted() is called. + * @return {Promise} + */ + waitForOnBluetoothDiscoveryStartedForTest() { + return new Promise((resolve) => { + this.onBluetoothDiscoveryStartedCallbackForTest_ = resolve; + }); } /** @@ -334,7 +356,8 @@ * @private */ pairDevice_(device) { - assert(this.devicePairingHandler_); + assert( + this.devicePairingHandler_, 'devicePairingHandler_ has not been set.'); this.pairingDelegateReceiver_ = new chromeos.bluetoothConfig.mojom.DevicePairingDelegateReceiver(this);