diff --git a/chrome/browser/chromeos/drive/OWNERS b/chrome/browser/chromeos/drive/OWNERS index 9df9e4f..2563657 100644 --- a/chrome/browser/chromeos/drive/OWNERS +++ b/chrome/browser/chromeos/drive/OWNERS
@@ -2,5 +2,4 @@ hidehiko@chromium.org hirono@chromium.org kinaba@chromium.org -mtomasz@chromium.org yoshiki@chromium.org
diff --git a/chrome/browser/chromeos/extensions/file_manager/OWNERS b/chrome/browser/chromeos/extensions/file_manager/OWNERS index 5f9e355..b1654a9 100644 --- a/chrome/browser/chromeos/extensions/file_manager/OWNERS +++ b/chrome/browser/chromeos/extensions/file_manager/OWNERS
@@ -2,5 +2,4 @@ fukino@chromium.org hirono@chromium.org kinaba@chromium.org -mtomasz@chromium.org yoshiki@chromium.org
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/OWNERS b/chrome/browser/chromeos/extensions/file_system_provider/OWNERS index 4eab6e4..4de4587c 100644 --- a/chrome/browser/chromeos/extensions/file_system_provider/OWNERS +++ b/chrome/browser/chromeos/extensions/file_system_provider/OWNERS
@@ -1 +1,2 @@ -mtomasz@chromium.org +fukino@chromium.org +yamaguchi@chromium.org
diff --git a/chrome/browser/chromeos/file_manager/OWNERS b/chrome/browser/chromeos/file_manager/OWNERS index 82f9484..3dd2532 100644 --- a/chrome/browser/chromeos/file_manager/OWNERS +++ b/chrome/browser/chromeos/file_manager/OWNERS
@@ -1,5 +1,4 @@ fukino@chromium.org hirono@chromium.org kinaba@chromium.org -mtomasz@chromium.org yoshiki@chromium.org
diff --git a/chrome/browser/chromeos/file_system_provider/OWNERS b/chrome/browser/chromeos/file_system_provider/OWNERS index 4eab6e4..4de4587c 100644 --- a/chrome/browser/chromeos/file_system_provider/OWNERS +++ b/chrome/browser/chromeos/file_system_provider/OWNERS
@@ -1 +1,2 @@ -mtomasz@chromium.org +fukino@chromium.org +yamaguchi@chromium.org
diff --git a/chrome/browser/chromeos/fileapi/OWNERS b/chrome/browser/chromeos/fileapi/OWNERS index 4eab6e4..af611691 100644 --- a/chrome/browser/chromeos/fileapi/OWNERS +++ b/chrome/browser/chromeos/fileapi/OWNERS
@@ -1 +1,3 @@ -mtomasz@chromium.org +fukino@chromium.org +yamaguchi@chromium.org +
diff --git a/chrome/browser/chromeos/smb_client/OWNERS b/chrome/browser/chromeos/smb_client/OWNERS index 2d8049a..9a71e3b2 100644 --- a/chrome/browser/chromeos/smb_client/OWNERS +++ b/chrome/browser/chromeos/smb_client/OWNERS
@@ -1,5 +1,4 @@ set noparent allenvic@chromium.org baileyberro@chromium.org -mtomasz@chromium.org zentaro@chromium.org
diff --git a/chrome/browser/drive/OWNERS b/chrome/browser/drive/OWNERS index aec41e60..7ca29178 100644 --- a/chrome/browser/drive/OWNERS +++ b/chrome/browser/drive/OWNERS
@@ -3,5 +3,4 @@ hidehiko@chromium.org hirono@chromium.org kinaba@chromium.org -mtomasz@chromium.org yoshiki@chromium.org
diff --git a/chrome/browser/extensions/api/file_system/OWNERS b/chrome/browser/extensions/api/file_system/OWNERS index ac81da7..64f6677 100644 --- a/chrome/browser/extensions/api/file_system/OWNERS +++ b/chrome/browser/extensions/api/file_system/OWNERS
@@ -1,3 +1,2 @@ benwells@chromium.org -mtomasz@chromium.org sammc@chromium.org
diff --git a/chrome/browser/extensions/api/webstore_widget_private/OWNERS b/chrome/browser/extensions/api/webstore_widget_private/OWNERS index f8d2da3d..655a976 100644 --- a/chrome/browser/extensions/api/webstore_widget_private/OWNERS +++ b/chrome/browser/extensions/api/webstore_widget_private/OWNERS
@@ -3,5 +3,4 @@ # chrome/browser/chromeos/file_manager/OWNERS hirono@chromium.org kinaba@chromium.org -mtomasz@chromium.org yoshiki@chromium.org
diff --git a/chrome/browser/resources/chromeos/zip_archiver/OWNERS b/chrome/browser/resources/chromeos/zip_archiver/OWNERS index 77f7614..191333e 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/OWNERS +++ b/chrome/browser/resources/chromeos/zip_archiver/OWNERS
@@ -1,2 +1 @@ yawano@chromium.org -mtomasz@chromium.org
diff --git a/chrome/common/extensions/api/OWNERS b/chrome/common/extensions/api/OWNERS index dbad8fa0..1a183d1 100644 --- a/chrome/common/extensions/api/OWNERS +++ b/chrome/common/extensions/api/OWNERS
@@ -15,6 +15,7 @@ per-file automation*.idl=dmazzoni@chromium.org per-file automation*.idl=dtseng@chromium.org per-file automation*.idl=nektar@chromium.org -per-file file_manager_private*.idl=mtomasz@chromium.org +per-file file_manager_private*.idl=fukino@chromium.org +per-file file_manager_private*.idl=yamaguchi@chromium.org # COMPONENT: Platform>Extensions>API
diff --git a/chrome/renderer/resources/extensions/OWNERS b/chrome/renderer/resources/extensions/OWNERS index 6e983f13..1e03873f 100644 --- a/chrome/renderer/resources/extensions/OWNERS +++ b/chrome/renderer/resources/extensions/OWNERS
@@ -6,7 +6,8 @@ per-file automation_custom_bindings.js=dtseng@chromium.org per-file automation_custom_bindings.js=nektar@chromium.org per-file enterprise_platform_keys*=emaxx@chromium.org -per-file file_manager_private_custom_bindings.js=mtomasz@chromium.org +per-file file_manager_private_custom_bindings.js=fukino@chromium.org +per-file file_manager_private_custom_bindings.js=yamaguchi@chromium.org per-file image_util.js=dewittj@chromium.org per-file media_galleries*.js=file://chrome/browser/media_galleries/OWNERS per-file media_router_bindings.js=file://chrome/browser/media/router/OWNERS
diff --git a/chrome/test/data/extensions/api_test/file_browser/OWNERS b/chrome/test/data/extensions/api_test/file_browser/OWNERS index f17c9865..2eb77e1 100644 --- a/chrome/test/data/extensions/api_test/file_browser/OWNERS +++ b/chrome/test/data/extensions/api_test/file_browser/OWNERS
@@ -1,4 +1,3 @@ # This should match ui/file_manager/file_manager/OWNERS hirono@chromium.org -mtomasz@chromium.org yoshiki@chromium.org
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index b7c03c1..9fa8e46c 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -10210.0.0 \ No newline at end of file +10213.0.0 \ No newline at end of file
diff --git a/components/chrome_apps/webstore_widget/OWNERS b/components/chrome_apps/webstore_widget/OWNERS index c0edc54..2537d91 100644 --- a/components/chrome_apps/webstore_widget/OWNERS +++ b/components/chrome_apps/webstore_widget/OWNERS
@@ -1,5 +1,4 @@ fukino@chromium.org hirono@chromium.org -mtomasz@chromium.org tbarzic@chromium.org yoshiki@chromium.org
diff --git a/components/drive/OWNERS b/components/drive/OWNERS index aec41e60..7ca29178 100644 --- a/components/drive/OWNERS +++ b/components/drive/OWNERS
@@ -3,5 +3,4 @@ hidehiko@chromium.org hirono@chromium.org kinaba@chromium.org -mtomasz@chromium.org yoshiki@chromium.org
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 87988955..5b77db4 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1317,6 +1317,8 @@ "renderer_host/media/audio_input_device_manager.h", "renderer_host/media/audio_input_renderer_host.cc", "renderer_host/media/audio_input_renderer_host.h", + "renderer_host/media/audio_input_stream_handle.cc", + "renderer_host/media/audio_input_stream_handle.h", "renderer_host/media/audio_input_sync_writer.cc", "renderer_host/media/audio_input_sync_writer.h", "renderer_host/media/audio_output_authorization_handler.cc", @@ -1350,6 +1352,8 @@ "renderer_host/media/media_stream_track_metrics_host.h", "renderer_host/media/media_stream_ui_proxy.cc", "renderer_host/media/media_stream_ui_proxy.h", + "renderer_host/media/render_frame_audio_input_stream_factory.cc", + "renderer_host/media/render_frame_audio_input_stream_factory.h", "renderer_host/media/render_frame_audio_output_stream_factory.cc", "renderer_host/media/render_frame_audio_output_stream_factory.h", "renderer_host/media/renderer_audio_output_stream_factory_context.h",
diff --git a/content/browser/renderer_host/media/audio_input_stream_handle.cc b/content/browser/renderer_host/media/audio_input_stream_handle.cc new file mode 100644 index 0000000..202e20c --- /dev/null +++ b/content/browser/renderer_host/media/audio_input_stream_handle.cc
@@ -0,0 +1,71 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/media/audio_input_stream_handle.h" + +#include <utility> + +#include "base/bind_helpers.h" +#include "mojo/public/cpp/bindings/interface_request.h" + +namespace content { + +namespace { + +media::mojom::AudioInputStreamClientPtr CreatePtrAndStoreRequest( + media::mojom::AudioInputStreamClientRequest* request_out) { + media::mojom::AudioInputStreamClientPtr ptr; + *request_out = mojo::MakeRequest(&ptr); + return ptr; +} + +} // namespace + +AudioInputStreamHandle::AudioInputStreamHandle( + mojom::RendererAudioInputStreamFactoryClientPtr client, + media::MojoAudioInputStream::CreateDelegateCallback + create_delegate_callback, + DeleterCallback deleter_callback) + : deleter_callback_(std::move(deleter_callback)), + client_(std::move(client)), + stream_ptr_(), + stream_client_request_(), + stream_(mojo::MakeRequest(&stream_ptr_), + CreatePtrAndStoreRequest(&stream_client_request_), + std::move(create_delegate_callback), + base::BindOnce(&AudioInputStreamHandle::OnCreated, + base::Unretained(this)), + base::BindOnce(&AudioInputStreamHandle::CallDeleter, + base::Unretained(this))) { + // Unretained is safe since |this| owns |stream_| and |client_|. + DCHECK(client_); + DCHECK(deleter_callback_); + client_.set_connection_error_handler(base::BindOnce( + &AudioInputStreamHandle::CallDeleter, base::Unretained(this))); +} + +AudioInputStreamHandle::~AudioInputStreamHandle() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +void AudioInputStreamHandle::OnCreated( + mojo::ScopedSharedBufferHandle shared_buffer, + mojo::ScopedHandle socket_descriptor, + bool initially_muted) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(client_); + DCHECK(deleter_callback_) + << "|deleter_callback_| was called, but |this| hasn't been destructed!"; + client_->StreamCreated( + std::move(stream_ptr_), std::move(stream_client_request_), + std::move(shared_buffer), std::move(socket_descriptor), initially_muted); +} + +void AudioInputStreamHandle::CallDeleter() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(deleter_callback_); + std::move(deleter_callback_).Run(this); +} + +} // namespace content
diff --git a/content/browser/renderer_host/media/audio_input_stream_handle.h b/content/browser/renderer_host/media/audio_input_stream_handle.h new file mode 100644 index 0000000..4f57adf --- /dev/null +++ b/content/browser/renderer_host/media/audio_input_stream_handle.h
@@ -0,0 +1,54 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_STREAM_HANDLE_H_ +#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_STREAM_HANDLE_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "base/sequence_checker.h" +#include "content/common/content_export.h" +#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" +#include "media/mojo/interfaces/audio_input_stream.mojom.h" +#include "media/mojo/services/mojo_audio_input_stream.h" +#include "mojo/public/cpp/system/buffer.h" +#include "mojo/public/cpp/system/handle.h" + +namespace content { + +// This class creates a MojoAudioInputStream and forwards the OnCreated event +// to a RendererAudioInputStreamFactoryClient. +class CONTENT_EXPORT AudioInputStreamHandle { + public: + using DeleterCallback = base::OnceCallback<void(AudioInputStreamHandle*)>; + + // |deleter_callback| will be called when encountering an error, in which + // case |this| should be synchronously destructed by its owner. + AudioInputStreamHandle(mojom::RendererAudioInputStreamFactoryClientPtr client, + media::MojoAudioInputStream::CreateDelegateCallback + create_delegate_callback, + DeleterCallback deleter_callback); + + ~AudioInputStreamHandle(); + + private: + void OnCreated(mojo::ScopedSharedBufferHandle shared_buffer, + mojo::ScopedHandle socket_descriptor, + bool initially_muted); + + void CallDeleter(); + + SEQUENCE_CHECKER(sequence_checker_); + DeleterCallback deleter_callback_; + mojom::RendererAudioInputStreamFactoryClientPtr client_; + media::mojom::AudioInputStreamPtr stream_ptr_; + media::mojom::AudioInputStreamClientRequest stream_client_request_; + media::MojoAudioInputStream stream_; + + DISALLOW_COPY_AND_ASSIGN(AudioInputStreamHandle); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_STREAM_HANDLE_H_
diff --git a/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc b/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc new file mode 100644 index 0000000..1a95520 --- /dev/null +++ b/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
@@ -0,0 +1,173 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/media/audio_input_stream_handle.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/memory/shared_memory.h" +#include "base/memory/shared_memory_handle.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/sync_socket.h" +#include "base/test/mock_callback.h" +#include "media/audio/audio_input_delegate.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +namespace { + +using testing::StrictMock; +using testing::Mock; +using testing::Test; + +class FakeAudioInputDelegate : public media::AudioInputDelegate { + public: + FakeAudioInputDelegate() {} + + ~FakeAudioInputDelegate() override {} + + int GetStreamId() override { return 0; }; + void OnRecordStream() override{}; + void OnSetVolume(double volume) override{}; + + private: + DISALLOW_COPY_AND_ASSIGN(FakeAudioInputDelegate); +}; + +class MockRendererAudioInputStreamFactoryClient + : public mojom::RendererAudioInputStreamFactoryClient { + public: + MOCK_METHOD0(Created, void()); + + void StreamCreated(media::mojom::AudioInputStreamPtr input_stream, + media::mojom::AudioInputStreamClientRequest client_request, + mojo::ScopedSharedBufferHandle shared_buffer, + mojo::ScopedHandle socket_descriptor, + bool initially_muted) override { + input_stream_ = std::move(input_stream); + client_request_ = std::move(client_request); + Created(); + } + + private: + media::mojom::AudioInputStreamPtr input_stream_; + media::mojom::AudioInputStreamClientRequest client_request_; +}; + +using MockDeleter = + base::MockCallback<base::OnceCallback<void(AudioInputStreamHandle*)>>; + +// Creates a fake delegate and saves the provided event handler in +// |event_handler_out|. +std::unique_ptr<media::AudioInputDelegate> CreateFakeDelegate( + media::AudioInputDelegate::EventHandler** event_handler_out, + media::AudioInputDelegate::EventHandler* event_handler) { + *event_handler_out = event_handler; + return std::make_unique<FakeAudioInputDelegate>(); +} + +} // namespace + +class AudioInputStreamHandleTest : public Test { + public: + AudioInputStreamHandleTest() + : client_binding_(&client_, mojo::MakeRequest(&client_ptr_)), + handle_(std::make_unique<AudioInputStreamHandle>( + std::move(client_ptr_), + base::BindOnce(&CreateFakeDelegate, &event_handler_), + deleter_.Get())), + local_(std::make_unique<base::CancelableSyncSocket>()), + remote_(std::make_unique<base::CancelableSyncSocket>()) { + // Wait for |event_handler| to be set. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(event_handler_); + + const size_t kSize = 1234; + base::SharedMemoryCreateOptions shmem_options; + shmem_options.size = kSize; + shmem_options.share_read_only = true; + shared_memory_.Create(shmem_options); + shared_memory_.Map(kSize); + EXPECT_TRUE( + base::CancelableSyncSocket::CreatePair(local_.get(), remote_.get())); + } + + void SendCreatedNotification() { + const int kIrrelevantStreamId = 0; + const bool kInitiallyMuted = false; + event_handler_->OnStreamCreated(kIrrelevantStreamId, &shared_memory_, + std::move(remote_), kInitiallyMuted); + } + + MockRendererAudioInputStreamFactoryClient* client() { return &client_; } + + void UnbindClientBinding() { client_binding_.Unbind(); } + + void ExpectHandleWillCallDeleter() { + EXPECT_CALL(deleter_, Run(handle_.release())) + .WillOnce(testing::DeleteArg<0>()); + } + + // Note: Must call ExpectHandleWillCallDeleter() first. + void VerifyDeleterWasCalled() { + EXPECT_TRUE(Mock::VerifyAndClear(&deleter_)); + } + + private: + base::MessageLoop message_loop_; + StrictMock<MockRendererAudioInputStreamFactoryClient> client_; + mojom::RendererAudioInputStreamFactoryClientPtr client_ptr_; + mojo::Binding<mojom::RendererAudioInputStreamFactoryClient> client_binding_; + StrictMock<MockDeleter> deleter_; + media::AudioInputDelegate::EventHandler* event_handler_ = nullptr; + std::unique_ptr<AudioInputStreamHandle> handle_; + + base::SharedMemory shared_memory_; + std::unique_ptr<base::CancelableSyncSocket> local_; + std::unique_ptr<base::CancelableSyncSocket> remote_; +}; + +TEST_F(AudioInputStreamHandleTest, CreateStream) { + EXPECT_CALL(*client(), Created()); + + SendCreatedNotification(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(Mock::VerifyAndClear(client())); +} + +TEST_F(AudioInputStreamHandleTest, + DestructClientBeforeCreationFinishes_CancelsStreamCreation) { + ExpectHandleWillCallDeleter(); + + UnbindClientBinding(); + base::RunLoop().RunUntilIdle(); + + VerifyDeleterWasCalled(); +} + +TEST_F(AudioInputStreamHandleTest, + CreateStreamAndDisconnectClient_DestroysStream) { + EXPECT_CALL(*client(), Created()); + + SendCreatedNotification(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(Mock::VerifyAndClear(client())); + + ExpectHandleWillCallDeleter(); + + UnbindClientBinding(); + base::RunLoop().RunUntilIdle(); + + VerifyDeleterWasCalled(); +} + +} // namespace content
diff --git a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc new file mode 100644 index 0000000..531d94f --- /dev/null +++ b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc
@@ -0,0 +1,128 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h" + +#include <utility> + +#include "base/task_runner_util.h" +#include "content/browser/media/media_internals.h" +#include "content/browser/renderer_host/media/media_stream_manager.h" +#include "media/base/audio_parameters.h" + +namespace content { + +// static +std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle, + BrowserThread::DeleteOnIOThread> +RenderFrameAudioInputStreamFactoryHandle::CreateFactory( + RenderFrameAudioInputStreamFactory::CreateDelegateCallback + create_delegate_callback, + content::MediaStreamManager* media_stream_manager, + mojom::RendererAudioInputStreamFactoryRequest request) { + std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle, + BrowserThread::DeleteOnIOThread> + handle(new RenderFrameAudioInputStreamFactoryHandle( + std::move(create_delegate_callback), media_stream_manager)); + // Unretained is safe since |*handle| must be posted to the IO thread prior to + // deletion. + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&RenderFrameAudioInputStreamFactoryHandle::Init, + base::Unretained(handle.get()), std::move(request))); + return handle; +} + +RenderFrameAudioInputStreamFactoryHandle:: + ~RenderFrameAudioInputStreamFactoryHandle() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); +} + +RenderFrameAudioInputStreamFactoryHandle:: + RenderFrameAudioInputStreamFactoryHandle( + RenderFrameAudioInputStreamFactory::CreateDelegateCallback + create_delegate_callback, + MediaStreamManager* media_stream_manager) + : impl_(std::move(create_delegate_callback), media_stream_manager), + binding_(&impl_) {} + +void RenderFrameAudioInputStreamFactoryHandle::Init( + mojom::RendererAudioInputStreamFactoryRequest request) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + binding_.Bind(std::move(request)); +} + +RenderFrameAudioInputStreamFactory::RenderFrameAudioInputStreamFactory( + CreateDelegateCallback create_delegate_callback, + MediaStreamManager* media_stream_manager) + : create_delegate_callback_(std::move(create_delegate_callback)), + media_stream_manager_(media_stream_manager), + audio_log_(MediaInternals::GetInstance()->CreateAudioLog( + media::AudioLogFactory::AUDIO_INPUT_CONTROLLER)), + weak_ptr_factory_(this) { + DCHECK(create_delegate_callback_); + // No thread-hostile state has been initialized yet, so we don't have to bind + // to this specific thread. +} + +RenderFrameAudioInputStreamFactory::~RenderFrameAudioInputStreamFactory() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); +} + +void RenderFrameAudioInputStreamFactory::CreateStream( + mojom::RendererAudioInputStreamFactoryClientPtr client, + int32_t session_id, + const media::AudioParameters& audio_params, + bool automatic_gain_control, + uint32_t shared_memory_count) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + +#if defined(OS_CHROMEOS) + if (audio_params.channel_layout() == + media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) { + media_stream_manager_->audio_input_device_manager() + ->RegisterKeyboardMicStream(base::BindOnce( + &RenderFrameAudioInputStreamFactory::DoCreateStream, + weak_ptr_factory_.GetWeakPtr(), std::move(client), session_id, + audio_params, automatic_gain_control, shared_memory_count)); + return; + } +#endif + DoCreateStream(std::move(client), session_id, audio_params, + automatic_gain_control, shared_memory_count, + AudioInputDeviceManager::KeyboardMicRegistration()); +} + +void RenderFrameAudioInputStreamFactory::DoCreateStream( + mojom::RendererAudioInputStreamFactoryClientPtr client, + int session_id, + const media::AudioParameters& audio_params, + bool automatic_gain_control, + uint32_t shared_memory_count, + AudioInputDeviceManager::KeyboardMicRegistration + keyboard_mic_registration) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + int stream_id = ++next_stream_id_; + + // Unretained is safe since |this| owns |streams_|. + streams_.insert(std::make_unique<AudioInputStreamHandle>( + std::move(client), + base::BindOnce( + create_delegate_callback_, + base::Unretained(media_stream_manager_->audio_input_device_manager()), + audio_log_.get(), std::move(keyboard_mic_registration), + shared_memory_count, stream_id, session_id, automatic_gain_control, + audio_params), + base::BindOnce(&RenderFrameAudioInputStreamFactory::RemoveStream, + weak_ptr_factory_.GetWeakPtr()))); +} + +void RenderFrameAudioInputStreamFactory::RemoveStream( + AudioInputStreamHandle* stream) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + streams_.erase(stream); +} + +} // namespace content
diff --git a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h new file mode 100644 index 0000000..2985ba2b --- /dev/null +++ b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h
@@ -0,0 +1,128 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_ +#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_ + +#include <cstdint> +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/containers/flat_set.h" +#include "base/containers/unique_ptr_comparator.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "build/build_config.h" +#include "content/browser/renderer_host/media/audio_input_device_manager.h" +#include "content/browser/renderer_host/media/audio_input_stream_handle.h" +#include "content/common/content_export.h" +#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" +#include "content/public/browser/browser_thread.h" +#include "media/audio/audio_input_delegate.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace media { +class AudioParameters; +class AudioLog; +} // namespace media + +namespace content { + +class MediaStreamManager; + +// Handles a RendererAudioInputStreamFactory request for a render frame host, +// using the provided RendererAudioInputStreamFactoryContext. This class may +// be constructed on any thread, but must be used on the IO thread after that, +// and also destructed on the IO thread. +class CONTENT_EXPORT RenderFrameAudioInputStreamFactory + : public mojom::RendererAudioInputStreamFactory { + public: + using CreateDelegateCallback = + base::RepeatingCallback<std::unique_ptr<media::AudioInputDelegate>( + AudioInputDeviceManager* audio_input_device_manager, + media::AudioLog* audio_log, + AudioInputDeviceManager::KeyboardMicRegistration + keyboard_mic_registration, + uint32_t shared_memory_count, + int stream_id, + int session_id, + bool automatic_gain_control, + const media::AudioParameters& parameters, + media::AudioInputDelegate::EventHandler* event_handler)>; + + RenderFrameAudioInputStreamFactory( + CreateDelegateCallback create_delegate_callback, + MediaStreamManager* media_stream_manager); + + ~RenderFrameAudioInputStreamFactory() override; + + private: + using InputStreamSet = base::flat_set<std::unique_ptr<AudioInputStreamHandle>, + base::UniquePtrComparator>; + + // mojom::RendererAudioInputStreamFactory implementation. + void CreateStream(mojom::RendererAudioInputStreamFactoryClientPtr client, + int32_t session_id, + const media::AudioParameters& audio_params, + bool automatic_gain_control, + uint32_t shared_memory_count) override; + + void DoCreateStream(mojom::RendererAudioInputStreamFactoryClientPtr client, + int session_id, + const media::AudioParameters& audio_params, + bool automatic_gain_control, + uint32_t shared_memory_count, + AudioInputDeviceManager::KeyboardMicRegistration + keyboard_mic_registration); + + void RemoveStream(AudioInputStreamHandle* input_stream); + + const CreateDelegateCallback create_delegate_callback_; + MediaStreamManager* media_stream_manager_; + const std::unique_ptr<media::AudioLog> audio_log_; + + InputStreamSet streams_; + int next_stream_id_ = 0; + + base::WeakPtrFactory<RenderFrameAudioInputStreamFactory> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioInputStreamFactory); +}; + +// This class is a convenient bundle of factory and binding. +// It can be created on any thread, but should be destroyed on the IO thread +// (hence the DeleteOnIOThread pointer). +class CONTENT_EXPORT RenderFrameAudioInputStreamFactoryHandle { + public: + static std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle, + BrowserThread::DeleteOnIOThread> + CreateFactory(RenderFrameAudioInputStreamFactory::CreateDelegateCallback + create_delegate_callback, + MediaStreamManager* media_stream_manager, + mojom::RendererAudioInputStreamFactoryRequest request); + + ~RenderFrameAudioInputStreamFactoryHandle(); + + private: + RenderFrameAudioInputStreamFactoryHandle( + RenderFrameAudioInputStreamFactory::CreateDelegateCallback + create_delegate_callback, + MediaStreamManager* media_stream_manager); + + void Init(mojom::RendererAudioInputStreamFactoryRequest request); + + RenderFrameAudioInputStreamFactory impl_; + mojo::Binding<mojom::RendererAudioInputStreamFactory> binding_; + + DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioInputStreamFactoryHandle); +}; + +using UniqueAudioInputStreamFactoryPtr = + std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle, + BrowserThread::DeleteOnIOThread>; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_
diff --git a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc new file mode 100644 index 0000000..68b691f --- /dev/null +++ b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
@@ -0,0 +1,161 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h" + +#include <limits> +#include <utility> + +#include "base/bind.h" +#include "base/memory/shared_memory.h" +#include "base/memory/shared_memory_handle.h" +#include "base/optional.h" +#include "base/run_loop.h" +#include "base/sync_socket.h" +#include "content/browser/renderer_host/media/audio_input_device_manager.h" +#include "content/browser/renderer_host/media/media_stream_manager.h" +#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/test/test_browser_context.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "media/audio/audio_system_impl.h" +#include "media/audio/mock_audio_manager.h" +#include "media/audio/test_audio_thread.h" +#include "media/base/audio_parameters.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +namespace { + +using testing::Test; + +const size_t kShmemSize = 1234; +const int kSessionId = 234; +const bool kAGC = false; +const uint32_t kSharedMemoryCount = 345; +const int kSampleFrequency = 44100; +const int kBitsPerSample = 16; +const int kSamplesPerBuffer = kSampleFrequency / 100; +const bool kInitiallyMuted = false; + +media::AudioParameters GetTestAudioParameters() { + return media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::CHANNEL_LAYOUT_MONO, kSampleFrequency, + kBitsPerSample, kSamplesPerBuffer); +} + +class FakeAudioInputDelegate : public media::AudioInputDelegate { + public: + FakeAudioInputDelegate() {} + + ~FakeAudioInputDelegate() override {} + + int GetStreamId() override { return 0; }; + void OnRecordStream() override{}; + void OnSetVolume(double volume) override{}; + + private: + DISALLOW_COPY_AND_ASSIGN(FakeAudioInputDelegate); +}; + +class FakeAudioInputStreamClient : public media::mojom::AudioInputStreamClient { + public: + void OnMutedStateChanged(bool is_muted) override {} + void OnError() override {} +}; + +class MockRendererAudioInputStreamFactoryClient + : public mojom::RendererAudioInputStreamFactoryClient { + public: + MOCK_METHOD0(Created, void()); + + void StreamCreated(media::mojom::AudioInputStreamPtr input_stream, + media::mojom::AudioInputStreamClientRequest client_request, + mojo::ScopedSharedBufferHandle shared_buffer, + mojo::ScopedHandle socket_descriptor, + bool initially_muted) override { + Created(); + } +}; + +// Creates a fake delegate and saves the provided event handler in +// |event_handler_out|. +std::unique_ptr<media::AudioInputDelegate> CreateFakeDelegate( + media::AudioInputDelegate::EventHandler** event_handler_out, + AudioInputDeviceManager* audio_input_device_manager, + media::AudioLog* audio_log, + AudioInputDeviceManager::KeyboardMicRegistration keyboard_mic_registration, + uint32_t shared_memory_count, + int stream_id, + int session_id, + bool automatic_gain_control, + const media::AudioParameters& parameters, + media::AudioInputDelegate::EventHandler* event_handler) { + *event_handler_out = event_handler; + return std::make_unique<FakeAudioInputDelegate>(); +} + +} // namespace + +class RenderFrameAudioInputStreamFactoryTest : public testing::Test { + public: + RenderFrameAudioInputStreamFactoryTest() + : thread_bundle_(base::in_place), + audio_manager_(std::make_unique<media::TestAudioThread>()), + audio_system_(&audio_manager_), + media_stream_manager_(&audio_system_, audio_manager_.GetTaskRunner()), + client_binding_(&client_, mojo::MakeRequest(&client_ptr_)), + factory_handle_(RenderFrameAudioInputStreamFactoryHandle::CreateFactory( + base::BindRepeating(&CreateFakeDelegate, &event_handler_), + &media_stream_manager_, + mojo::MakeRequest(&factory_ptr_))) {} + + ~RenderFrameAudioInputStreamFactoryTest() override { + audio_manager_.Shutdown(); + thread_bundle_.reset(); + } + + base::Optional<TestBrowserThreadBundle> thread_bundle_; + media::MockAudioManager audio_manager_; + media::AudioSystemImpl audio_system_; + MediaStreamManager media_stream_manager_; + mojom::RendererAudioInputStreamFactoryPtr factory_ptr_; + media::mojom::AudioInputStreamPtr stream_ptr_; + MockRendererAudioInputStreamFactoryClient client_; + mojom::RendererAudioInputStreamFactoryClientPtr client_ptr_; + media::AudioInputDelegate::EventHandler* event_handler_ = nullptr; + mojo::Binding<mojom::RendererAudioInputStreamFactoryClient> client_binding_; + UniqueAudioInputStreamFactoryPtr factory_handle_; +}; + +TEST_F(RenderFrameAudioInputStreamFactoryTest, CreateStream) { + factory_ptr_->CreateStream(std::move(client_ptr_), kSessionId, + GetTestAudioParameters(), kAGC, + kSharedMemoryCount); + + // Wait for delegate to be created and |event_handler| set. + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(event_handler_); + base::SharedMemoryCreateOptions shmem_options; + shmem_options.size = kShmemSize; + shmem_options.share_read_only = true; + base::SharedMemory shared_memory; + shared_memory.Create(shmem_options); + shared_memory.Map(kShmemSize); + auto local = std::make_unique<base::CancelableSyncSocket>(); + auto remote = std::make_unique<base::CancelableSyncSocket>(); + ASSERT_TRUE( + base::CancelableSyncSocket::CreatePair(local.get(), remote.get())); + event_handler_->OnStreamCreated(/*stream_id, irrelevant*/ 0, &shared_memory, + std::move(remote), kInitiallyMuted); + + EXPECT_CALL(client_, Created()); + base::RunLoop().RunUntilIdle(); +} + +} // namespace content
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc index 7135214..52d36b2 100644 --- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc +++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc
@@ -75,22 +75,12 @@ void RenderFrameAudioOutputStreamFactory::RequestDeviceAuthorization( media::mojom::AudioOutputStreamProviderRequest stream_provider_request, - int64_t session_id, + int32_t session_id, const std::string& device_id, RequestDeviceAuthorizationCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); const base::TimeTicks auth_start_time = base::TimeTicks::Now(); - if (!base::IsValueInRangeForNumericType<int>(session_id)) { - mojo::ReportBadMessage("session_id is not in integer range"); - // Note: We must call the callback even though we are killing the renderer. - // This is mandated by mojo. - std::move(callback).Run( - media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED, - media::AudioParameters::UnavailableDeviceParams(), std::string()); - return; - } - context_->RequestDeviceAuthorization( render_frame_id_, session_id, device_id, base::BindOnce( @@ -143,11 +133,7 @@ media::mojom::AudioOutputStreamProvider* stream_provider) { DCHECK(thread_checker_.CalledOnValidThread()); - base::EraseIf( - stream_providers_, - [stream_provider]( - const std::unique_ptr<media::mojom::AudioOutputStreamProvider>& - other) { return other.get() == stream_provider; }); + stream_providers_.erase(stream_provider); } } // namespace content
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h index 0f75bdc7..4f598ad 100644 --- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h +++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h
@@ -9,6 +9,7 @@ #include <string> #include "base/containers/flat_set.h" +#include "base/containers/unique_ptr_comparator.h" #include "base/threading/thread_checker.h" #include "content/common/content_export.h" #include "content/common/media/renderer_audio_output_stream_factory.mojom.h" @@ -33,12 +34,13 @@ private: using OutputStreamProviderSet = - base::flat_set<std::unique_ptr<media::mojom::AudioOutputStreamProvider>>; + base::flat_set<std::unique_ptr<media::mojom::AudioOutputStreamProvider>, + base::UniquePtrComparator>; // mojom::RendererAudioOutputStreamFactory implementation. void RequestDeviceAuthorization( media::mojom::AudioOutputStreamProviderRequest stream_provider, - int64_t session_id, + int32_t session_id, const std::string& device_id, RequestDeviceAuthorizationCallback callback) override;
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc index 6603b1c..f6940e2 100644 --- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc +++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
@@ -19,7 +19,6 @@ #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "media/base/audio_parameters.h" -#include "mojo/edk/embedder/embedder.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/system/platform_handle.h" #include "testing/gmock/include/gmock/gmock.h" @@ -343,38 +342,4 @@ EXPECT_TRUE(delegate_is_destructed); } -TEST(RenderFrameAudioOutputStreamFactoryTest, OutOfRangeSessionId_BadMessage) { - // This test checks that we get a bad message if session_id is too large - // to fit in an integer. This ensures that we don't overflow when casting the - // int64_t to an int - if (sizeof(int) >= sizeof(int64_t)) { - // In this case, any int64_t would fit in an int, and the case we are - // checking for is impossible. - return; - } - - bool got_bad_message = false; - mojo::edk::SetDefaultProcessErrorCallback( - base::Bind([](bool* got_bad_message, - const std::string& s) { *got_bad_message = true; }, - &got_bad_message)); - - TestBrowserThreadBundle thread_bundle; - - AudioOutputStreamProviderPtr output_provider; - auto factory_context = std::make_unique<MockContext>(true); - auto factory_ptr = factory_context->CreateFactory(); - - int64_t session_id = std::numeric_limits<int>::max(); - ++session_id; - - EXPECT_FALSE(got_bad_message); - factory_ptr->RequestDeviceAuthorization( - mojo::MakeRequest(&output_provider), session_id, "default", - base::BindOnce([](media::OutputDeviceStatus, - const media::AudioParameters&, const std::string&) {})); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(got_bad_message); -} - } // namespace content
diff --git a/content/browser/webauth/cbor/cbor_reader.cc b/content/browser/webauth/cbor/cbor_reader.cc index 893a4e7..e61565c 100644 --- a/content/browser/webauth/cbor/cbor_reader.cc +++ b/content/browser/webauth/cbor/cbor_reader.cc
@@ -231,7 +231,7 @@ } bool CBORReader::HasValidUTF8Format(const std::string& string_data) { - if (!base::IsStringUTF8(string_data.data())) { + if (!base::IsStringUTF8(string_data)) { error_code_ = DecoderError::INVALID_UTF8; return false; }
diff --git a/content/browser/webauth/cbor/cbor_reader_unittest.cc b/content/browser/webauth/cbor/cbor_reader_unittest.cc index 0df2d1c..fe3a99f 100644 --- a/content/browser/webauth/cbor/cbor_reader_unittest.cc +++ b/content/browser/webauth/cbor/cbor_reader_unittest.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "content/browser/webauth/cbor/cbor_reader.h" -#include "base/strings/stringprintf.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -112,8 +111,7 @@ for (const StringTestCase& test_case : kStringTestCases) { testing::Message scope_message; - scope_message << "testing string value : " - << base::StringPrintf("%s", test_case.value.data()); + scope_message << "testing string value : " << test_case.value; SCOPED_TRACE(scope_message); base::Optional<CBORValue> cbor = CBORReader::Read(test_case.cbor_data); @@ -123,6 +121,50 @@ } } +TEST(CBORReaderTest, TestReadStringWithNUL) { + static const struct { + const std::string value; + const std::vector<uint8_t> cbor_data; + } kStringTestCases[] = { + {std::string("string_without_nul"), + {0x72, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x77, 0x69, 0x74, 0x68, + 0x6F, 0x75, 0x74, 0x5F, 0x6E, 0x75, 0x6C}}, + {std::string("nul_terminated_string\0", 22), + {0x76, 0x6E, 0x75, 0x6C, 0x5F, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x61, + 0x74, 0x65, 0x64, 0x5F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00}}, + {std::string("embedded\0nul", 12), + {0x6C, 0x65, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x00, 0x6E, 0x75, + 0x6C}}, + {std::string("trailing_nuls\0\0", 15), + {0x6F, 0x74, 0x72, 0x61, 0x69, 0x6C, 0x69, 0x6E, 0x67, 0x5F, 0x6E, 0x75, + 0x6C, 0x73, 0x00, 0x00}}, + }; + + for (const auto& test_case : kStringTestCases) { + SCOPED_TRACE(testing::Message() + << "testing string with nul bytes :" << test_case.value); + + base::Optional<CBORValue> cbor = CBORReader::Read(test_case.cbor_data); + ASSERT_TRUE(cbor.has_value()); + ASSERT_EQ(cbor.value().type(), CBORValue::Type::STRING); + EXPECT_EQ(cbor.value().GetString(), test_case.value); + } +} + +TEST(CBORReaderTest, TestReadStringWithInvalidByteSequenceAfterNUL) { + // UTF-8 validation should not stop at the first NUL character in the string. + // That is, a string with an invalid byte sequence should fail UTF-8 + // validation even if the invalid character is located after one or more NUL + // characters. Here, 0xA6 is an unexpected continuation byte. + static const std::vector<uint8_t> string_with_invalid_continuation_byte = { + 0x63, 0x00, 0x00, 0xA6}; + CBORReader::DecoderError error_code; + base::Optional<CBORValue> cbor = + CBORReader::Read(string_with_invalid_continuation_byte, &error_code); + EXPECT_FALSE(cbor.has_value()); + EXPECT_EQ(error_code, CBORReader::DecoderError::INVALID_UTF8); +} + TEST(CBORReaderTest, TestReadArray) { static const std::vector<uint8_t> kArrayTestCaseCbor = { // clang-format off
diff --git a/content/browser/webauth/cbor/cbor_values.h b/content/browser/webauth/cbor/cbor_values.h index 3e993d90..83bbd49 100644 --- a/content/browser/webauth/cbor/cbor_values.h +++ b/content/browser/webauth/cbor/cbor_values.h
@@ -109,6 +109,7 @@ // These will all fatally assert if the type doesn't match. uint64_t GetUnsigned() const; const BinaryValue& GetBytestring() const; + // Returned string may contain NUL characters. const std::string& GetString() const; const ArrayValue& GetArray() const; const MapValue& GetMap() const;
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 44b4789..bd8ad82 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -557,6 +557,7 @@ "leveldb_wrapper.mojom", "manifest_observer.mojom", "media/media_stream.mojom", + "media/renderer_audio_input_stream_factory.mojom", "media/renderer_audio_output_stream_factory.mojom", "memory_coordinator.mojom", "native_types.mojom",
diff --git a/content/common/media/renderer_audio_input_stream_factory.mojom b/content/common/media/renderer_audio_input_stream_factory.mojom new file mode 100644 index 0000000..f74174a4 --- /dev/null +++ b/content/common/media/renderer_audio_input_stream_factory.mojom
@@ -0,0 +1,36 @@ +// 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. + +module content.mojom; + +import "media/mojo/interfaces/audio_input_stream.mojom"; +import "media/mojo/interfaces/audio_parameters.mojom"; +import "media/mojo/interfaces/media_types.mojom"; + +// This interface is used by the renderer to ask the browser to create input +// streams. The renderer supplies the desired audio parameters, and a client +// to send the stream to when it's ready. The lifetime of the stream is limited +// by the lifetime of the client. +interface RendererAudioInputStreamFactory { + CreateStream( + RendererAudioInputStreamFactoryClient client, + int32 session_id, + media.mojom.AudioParameters params, + bool automatic_gain_control, + uint32 shared_memory_count); +}; + +interface RendererAudioInputStreamFactoryClient { + // Called when a stream has been created. Will only be called once for every + // CreateStream call. + // TODO(crbug.com/787806): There are plans to allow this function to be called + // serveral times in the future. If the stream is terminated e.g. due to the + // process hosting it crashing, this function should be called again with a + // fresh stream. + StreamCreated( + media.mojom.AudioInputStream stream, + media.mojom.AudioInputStreamClient& client_request, + handle<shared_buffer> shared_buffer, handle socket_descriptor, + bool initially_muted); +};
diff --git a/content/common/media/renderer_audio_output_stream_factory.mojom b/content/common/media/renderer_audio_output_stream_factory.mojom index d099278..71195456 100644 --- a/content/common/media/renderer_audio_output_stream_factory.mojom +++ b/content/common/media/renderer_audio_output_stream_factory.mojom
@@ -17,7 +17,7 @@ // (in case of an error). RequestDeviceAuthorization( media.mojom.AudioOutputStreamProvider& stream_provider_request, - int64 session_id, + int32 session_id, string device_id) => (media.mojom.OutputDeviceStatus state, media.mojom.AudioParameters output_params,
diff --git a/content/renderer/media/audio_ipc_factory_unittest.cc b/content/renderer/media/audio_ipc_factory_unittest.cc index 88b1773..a8caa5c 100644 --- a/content/renderer/media/audio_ipc_factory_unittest.cc +++ b/content/renderer/media/audio_ipc_factory_unittest.cc
@@ -41,7 +41,7 @@ void RequestDeviceAuthorization( media::mojom::AudioOutputStreamProviderRequest stream_provider, - int64_t session_id, + int32_t session_id, const std::string& device_id, RequestDeviceAuthorizationCallback callback) override { std::move(callback).Run(
diff --git a/content/renderer/media/mojo_audio_output_ipc.cc b/content/renderer/media/mojo_audio_output_ipc.cc index 7013306..13eb0d09 100644 --- a/content/renderer/media/mojo_audio_output_ipc.cc +++ b/content/renderer/media/mojo_audio_output_ipc.cc
@@ -176,6 +176,8 @@ return false; } + static_assert(sizeof(int) == sizeof(int32_t), + "sizeof(int) == sizeof(int32_t)"); factory->RequestDeviceAuthorization(MakeProviderRequest(), session_id, device_id, std::move(callback)); return true;
diff --git a/content/renderer/media/mojo_audio_output_ipc_unittest.cc b/content/renderer/media/mojo_audio_output_ipc_unittest.cc index c5624ace..6e7d20d 100644 --- a/content/renderer/media/mojo_audio_output_ipc_unittest.cc +++ b/content/renderer/media/mojo_audio_output_ipc_unittest.cc
@@ -98,7 +98,7 @@ void RequestDeviceAuthorization( media::mojom::AudioOutputStreamProviderRequest stream_provider_request, - int64_t session_id, + int32_t session_id, const std::string& device_id, RequestDeviceAuthorizationCallback callback) override { EXPECT_EQ(session_id, expected_session_id_); @@ -119,7 +119,7 @@ } void PrepareProviderForAuthorization( - int64_t session_id, + int32_t session_id, const std::string& device_id, std::unique_ptr<TestStreamProvider> provider) { EXPECT_FALSE(expect_request_); @@ -130,7 +130,7 @@ std::swap(provider_, provider); } - void RefuseNextRequest(int64_t session_id, const std::string& device_id) { + void RefuseNextRequest(int32_t session_id, const std::string& device_id) { EXPECT_FALSE(expect_request_); expect_request_ = true; expected_session_id_ = session_id; @@ -158,7 +158,7 @@ mojom::RendererAudioOutputStreamFactory* get() { return this_proxy_.get(); } bool expect_request_; - int64_t expected_session_id_; + int32_t expected_session_id_; std::string expected_device_id_; mojom::RendererAudioOutputStreamFactoryPtr this_proxy_;
diff --git a/content/shell/test_runner/pixel_dump.cc b/content/shell/test_runner/pixel_dump.cc index bf55f681..837ce15 100644 --- a/content/shell/test_runner/pixel_dump.cc +++ b/content/shell/test_runner/pixel_dump.cc
@@ -153,7 +153,7 @@ base::OnceCallback<void(const SkBitmap&)> callback) { DCHECK(web_frame); DCHECK(!callback.is_null()); - web_frame->GetTaskRunner(blink::TaskType::kUnthrottled) + web_frame->GetTaskRunner(blink::TaskType::kInternalTest) ->PostTask(FROM_HERE, base::BindOnce(&CapturePixelsForPrinting, base::Unretained(web_frame), base::Passed(std::move(callback))));
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index a170958..a3991b0 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1368,6 +1368,7 @@ "../browser/renderer_host/media/audio_input_delegate_impl_unittest.cc", "../browser/renderer_host/media/audio_input_device_manager_unittest.cc", "../browser/renderer_host/media/audio_input_renderer_host_unittest.cc", + "../browser/renderer_host/media/audio_input_stream_handle_unittest.cc", "../browser/renderer_host/media/audio_input_sync_writer_unittest.cc", "../browser/renderer_host/media/audio_output_authorization_handler_unittest.cc", "../browser/renderer_host/media/audio_output_delegate_impl_unittest.cc", @@ -1384,6 +1385,7 @@ "../browser/renderer_host/media/media_stream_ui_proxy_unittest.cc", "../browser/renderer_host/media/mock_video_capture_provider.cc", "../browser/renderer_host/media/mock_video_capture_provider.h", + "../browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc", "../browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc", "../browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc", "../browser/renderer_host/media/service_video_capture_provider_unittest.cc",
diff --git a/extensions/browser/api/file_system/OWNERS b/extensions/browser/api/file_system/OWNERS index ac81da7..64f6677 100644 --- a/extensions/browser/api/file_system/OWNERS +++ b/extensions/browser/api/file_system/OWNERS
@@ -1,3 +1,2 @@ benwells@chromium.org -mtomasz@chromium.org sammc@chromium.org
diff --git a/media/capture/video/chromeos/camera_device_context.cc b/media/capture/video/chromeos/camera_device_context.cc index 15cb775..8a8e3d6 100644 --- a/media/capture/video/chromeos/camera_device_context.cc +++ b/media/capture/video/chromeos/camera_device_context.cc
@@ -8,7 +8,10 @@ CameraDeviceContext::CameraDeviceContext( std::unique_ptr<VideoCaptureDevice::Client> client) - : state_(State::kStopped), rotation_(0), client_(std::move(client)) { + : state_(State::kStopped), + sensor_orientation_(0), + screen_rotation_(0), + client_(std::move(client)) { DCHECK(client_); DETACH_FROM_SEQUENCE(sequence_checker_); } @@ -45,14 +48,23 @@ const VideoCaptureFormat& frame_format, base::TimeTicks reference_time, base::TimeDelta timestamp) { - client_->OnIncomingCapturedData(data, length, frame_format, rotation_, + int total_rotation = (sensor_orientation_ + screen_rotation_) % 360; + client_->OnIncomingCapturedData(data, length, frame_format, total_rotation, reference_time, timestamp); } -void CameraDeviceContext::SetRotation(int rotation) { +void CameraDeviceContext::SetSensorOrientation(int sensor_orientation) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0); - rotation_ = rotation; + DCHECK(sensor_orientation >= 0 && sensor_orientation < 360 && + sensor_orientation % 90 == 0); + sensor_orientation_ = sensor_orientation; +} + +void CameraDeviceContext::SetScreenRotation(int screen_rotation) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(screen_rotation >= 0 && screen_rotation < 360 && + screen_rotation % 90 == 0); + screen_rotation_ = screen_rotation; } } // namespace media
diff --git a/media/capture/video/chromeos/camera_device_context.h b/media/capture/video/chromeos/camera_device_context.h index 33f950d..5b537284 100644 --- a/media/capture/video/chromeos/camera_device_context.h +++ b/media/capture/video/chromeos/camera_device_context.h
@@ -112,7 +112,9 @@ base::TimeTicks reference_time, base::TimeDelta timestamp); - void SetRotation(int rotation); + void SetSensorOrientation(int sensor_orientation); + + void SetScreenRotation(int screen_rotation); private: friend class StreamBufferManagerTest; @@ -122,8 +124,14 @@ // The state the CameraDeviceDelegate currently is in. State state_; - // Clockwise rotation in degrees. This value should be 0, 90, 180, or 270. - int rotation_; + // Clockwise angle through which the output image needs to be rotated to be + // upright on the device screen in its native orientation. This value should + // be 0, 90, 180, or 270. + int sensor_orientation_; + + // Clockwise screen rotation in degrees. This value should be 0, 90, 180, or + // 270. + int screen_rotation_; std::unique_ptr<VideoCaptureDevice::Client> client_;
diff --git a/media/capture/video/chromeos/camera_device_delegate.cc b/media/capture/video/chromeos/camera_device_delegate.cc index 68550c9..714cf5e 100644 --- a/media/capture/video/chromeos/camera_device_delegate.cc +++ b/media/capture/video/chromeos/camera_device_delegate.cc
@@ -136,7 +136,7 @@ void CameraDeviceDelegate::SetRotation(int rotation) { DCHECK(ipc_task_runner_->BelongsToCurrentThread()); DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0); - device_context_->SetRotation(rotation); + device_context_->SetScreenRotation(rotation); } base::WeakPtr<CameraDeviceDelegate> CameraDeviceDelegate::GetWeakPtr() { @@ -203,6 +203,20 @@ return; } static_metadata_ = std::move(camera_info->static_camera_characteristics); + + const arc::mojom::CameraMetadataEntryPtr* sensor_orientation = + GetMetadataEntry( + static_metadata_, + arc::mojom::CameraMetadataTag::ANDROID_SENSOR_ORIENTATION); + if (sensor_orientation) { + device_context_->SetSensorOrientation( + *reinterpret_cast<int32_t*>((*sensor_orientation)->data.data())); + } else { + device_context_->SetErrorState( + FROM_HERE, "Camera is missing required sensor orientation info"); + return; + } + // |device_ops_| is bound after the MakeRequest call. arc::mojom::Camera3DeviceOpsRequest device_ops_request = mojo::MakeRequest(&device_ops_);
diff --git a/media/capture/video/chromeos/camera_device_delegate_unittest.cc b/media/capture/video/chromeos/camera_device_delegate_unittest.cc index 1cc27e5c..2c9da84 100644 --- a/media/capture/video/chromeos/camera_device_delegate_unittest.cc +++ b/media/capture/video/chromeos/camera_device_delegate_unittest.cc
@@ -154,6 +154,16 @@ arc::mojom::CameraInfoPtr camera_info = arc::mojom::CameraInfo::New(); arc::mojom::CameraMetadataPtr static_metadata = arc::mojom::CameraMetadata::New(); + arc::mojom::CameraMetadataEntryPtr entry = + arc::mojom::CameraMetadataEntry::New(); + entry->index = 0; + entry->tag = arc::mojom::CameraMetadataTag::ANDROID_SENSOR_ORIENTATION; + entry->type = arc::mojom::EntryType::TYPE_INT32; + entry->count = 1; + entry->data = std::vector<uint8_t>(4, 0); + static_metadata->entries = + std::vector<arc::mojom::CameraMetadataEntryPtr>(); + static_metadata->entries->push_back(std::move(entry)); switch (camera_id) { case 0: camera_info->facing = arc::mojom::CameraFacing::CAMERA_FACING_FRONT;
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp index 17929aa..b0508f0 100644 --- a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp +++ b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
@@ -244,7 +244,7 @@ parent_frame_task_runners_.Get()); worker_thread_->WaitForInit(); worker_loading_task_runner_ = - worker_thread_->GetTaskRunner(TaskType::kUnspecedLoading); + worker_thread_->GetTaskRunner(TaskType::kInternalTest); } void OnServeRequests() override { testing::RunPendingTasks(); }
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp index 00db69e..90f4cd0 100644 --- a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp +++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp
@@ -193,8 +193,8 @@ global_scope_->SetModuleResponsesMapProxyForTesting( WorkletModuleResponsesMapProxy::Create( new WorkletModuleResponsesMap(modulator_->Fetcher()), - GetDocument().GetTaskRunner(TaskType::kUnspecedLoading), - global_scope_->GetTaskRunner(TaskType::kUnspecedLoading))); + GetDocument().GetTaskRunner(TaskType::kInternalTest), + global_scope_->GetTaskRunner(TaskType::kInternalTest))); } void ModuleScriptLoaderTest::TestFetchDataURL(
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp index 10d5781..c77d173 100644 --- a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp +++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
@@ -49,7 +49,7 @@ EXPECT_TRUE(IsCurrentThread()); GlobalScope()->CountFeature(feature); GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); } @@ -64,17 +64,17 @@ EXPECT_TRUE(console_message.Contains("deprecated")); GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); } void TestTaskRunner() { EXPECT_TRUE(IsCurrentThread()); scoped_refptr<WebTaskRunner> task_runner = - GlobalScope()->GetTaskRunner(TaskType::kUnspecedTimer); + GlobalScope()->GetTaskRunner(TaskType::kInternalTest); EXPECT_TRUE(task_runner->RunsTasksInCurrentSequence()); GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); } }; @@ -223,7 +223,7 @@ // on the Document. EXPECT_FALSE(UseCounter::IsCounted(GetDocument(), kFeature1)); GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&DedicatedWorkerThreadForTest::CountFeature, @@ -234,7 +234,7 @@ // API use should be reported to the Document only one time. See comments in // DedicatedWorkerObjectProxyForTest::CountFeature. GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&DedicatedWorkerThreadForTest::CountFeature, @@ -248,7 +248,7 @@ // UseCounter on the Document. EXPECT_FALSE(UseCounter::IsCounted(GetDocument(), kFeature2)); GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&DedicatedWorkerThreadForTest::CountDeprecation, @@ -259,7 +259,7 @@ // API use should be reported to the Document only one time. See comments in // DedicatedWorkerObjectProxyForTest::CountDeprecation. GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&DedicatedWorkerThreadForTest::CountDeprecation, @@ -272,7 +272,7 @@ WorkerMessagingProxy()->StartWithSourceCode(source_code); GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&DedicatedWorkerThreadForTest::TestTaskRunner, CrossThreadUnretained(GetWorkerThread())));
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp b/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp index 3cf05a4..afc53c00 100644 --- a/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp +++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp
@@ -135,7 +135,7 @@ TEST_F(MainThreadWorkletTest, TaskRunner) { scoped_refptr<WebTaskRunner> task_runner = - global_scope_->GetTaskRunner(TaskType::kUnthrottled); + global_scope_->GetTaskRunner(TaskType::kInternalTest); EXPECT_TRUE(task_runner->RunsTasksInCurrentSequence()); }
diff --git a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp index c43f4a7..048712f 100644 --- a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp +++ b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp
@@ -27,10 +27,10 @@ ParentFrameTaskRunners::ParentFrameTaskRunners(LocalFrame* frame) : ContextLifecycleObserver(frame ? frame->GetDocument() : nullptr) { // For now we only support very limited task types. - for (auto type : - {TaskType::kUnspecedTimer, TaskType::kUnspecedLoading, - TaskType::kNetworking, TaskType::kPostedMessage, - TaskType::kCanvasBlobSerialization, TaskType::kUnthrottled}) { + for (auto type : {TaskType::kUnspecedTimer, TaskType::kUnspecedLoading, + TaskType::kNetworking, TaskType::kPostedMessage, + TaskType::kCanvasBlobSerialization, TaskType::kUnthrottled, + TaskType::kInternalTest}) { auto task_runner = frame ? frame->GetTaskRunner(type) : Platform::Current()->MainThread()->GetWebTaskRunner();
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp index d983e695..60e5902f 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp +++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp
@@ -84,7 +84,7 @@ EXPECT_TRUE(global_scope->GetSecurityOrigin()->IsUnique()); EXPECT_FALSE(global_scope->DocumentSecurityOrigin()->IsUnique()); GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); } @@ -108,7 +108,7 @@ IntegrityMetadataSet(), kParserInserted)); GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); } @@ -117,7 +117,7 @@ EXPECT_TRUE(IsCurrentThread()); GlobalScope()->CountFeature(feature); GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); } @@ -132,17 +132,17 @@ EXPECT_TRUE(console_message.Contains("deprecated")); GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); } void TestTaskRunner() { EXPECT_TRUE(IsCurrentThread()); scoped_refptr<WebTaskRunner> task_runner = - GlobalScope()->GetTaskRunner(TaskType::kUnspecedTimer); + GlobalScope()->GetTaskRunner(TaskType::kInternalTest); EXPECT_TRUE(task_runner->RunsTasksInCurrentSequence()); GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); } @@ -232,7 +232,7 @@ MessagingProxy()->Start(); GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&ThreadedWorkletThreadForTest::TestSecurityOrigin, @@ -252,7 +252,7 @@ MessagingProxy()->Start(); GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind( &ThreadedWorkletThreadForTest::TestContentSecurityPolicy, @@ -270,7 +270,7 @@ // on the Document. EXPECT_FALSE(UseCounter::IsCounted(GetDocument(), kFeature1)); GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&ThreadedWorkletThreadForTest::CountFeature, @@ -281,7 +281,7 @@ // API use should be reported to the Document only one time. See comments in // ThreadedWorkletGlobalScopeForTest::CountFeature. GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&ThreadedWorkletThreadForTest::CountFeature, @@ -295,7 +295,7 @@ // UseCounter on the Document. EXPECT_FALSE(UseCounter::IsCounted(GetDocument(), kFeature2)); GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&ThreadedWorkletThreadForTest::CountDeprecation, @@ -306,7 +306,7 @@ // API use should be reported to the Document only one time. See comments in // ThreadedWorkletGlobalScopeForTest::CountDeprecation. GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(&ThreadedWorkletThreadForTest::CountDeprecation, @@ -318,7 +318,7 @@ MessagingProxy()->Start(); GetWorkerThread() - ->GetTaskRunner(TaskType::kUnspecedTimer) + ->GetTaskRunner(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&ThreadedWorkletThreadForTest::TestTaskRunner, CrossThreadUnretained(GetWorkerThread())));
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp index f45ff5cc..3e4b95f3 100644 --- a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
@@ -58,7 +58,7 @@ // Notify the main thread that the debugger task is waiting for the signal. worker_thread->GetParentFrameTaskRunners() - ->Get(TaskType::kUnspecedTimer) + ->Get(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop)); waitable_event->Wait(); }
diff --git a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletGlobalScopeTest.cpp b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletGlobalScopeTest.cpp index 985af3a..23207f5a 100644 --- a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletGlobalScopeTest.cpp +++ b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletGlobalScopeTest.cpp
@@ -78,7 +78,7 @@ void RunTestOnWorkletThread(TestCalback callback) { std::unique_ptr<WorkerThread> worklet = CreateAnimationWorkletThread(); WaitableEvent waitable_event; - worklet->GetTaskRunner(TaskType::kUnthrottled) + worklet->GetTaskRunner(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(callback, CrossThreadUnretained(this), CrossThreadUnretained(worklet.get()),
diff --git a/third_party/WebKit/Source/modules/speech/testing/PlatformSpeechSynthesizerMock.cpp b/third_party/WebKit/Source/modules/speech/testing/PlatformSpeechSynthesizerMock.cpp index 94899da..61cfb35 100644 --- a/third_party/WebKit/Source/modules/speech/testing/PlatformSpeechSynthesizerMock.cpp +++ b/third_party/WebKit/Source/modules/speech/testing/PlatformSpeechSynthesizerMock.cpp
@@ -46,11 +46,11 @@ ExecutionContext* context) : PlatformSpeechSynthesizer(client), speaking_error_occurred_timer_( - context->GetTaskRunner(TaskType::kUnspecedTimer), + context->GetTaskRunner(TaskType::kInternalTest), this, &PlatformSpeechSynthesizerMock::SpeakingErrorOccurred), speaking_finished_timer_( - context->GetTaskRunner(TaskType::kUnspecedTimer), + context->GetTaskRunner(TaskType::kInternalTest), this, &PlatformSpeechSynthesizerMock::SpeakingFinished) {}
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp index 4e5e058..d8618b0 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp
@@ -84,7 +84,7 @@ void RunBasicTest(WorkerThread* thread) { WaitableEvent waitable_event; - thread->GetTaskRunner(TaskType::kUnthrottled) + thread->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind( @@ -96,7 +96,7 @@ void RunSimpleProcessTest(WorkerThread* thread) { WaitableEvent waitable_event; - thread->GetTaskRunner(TaskType::kUnthrottled) + thread->GetTaskRunner(TaskType::kInternalTest) ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&AudioWorkletGlobalScopeTest:: RunSimpleProcessTestOnWorkletThread, @@ -108,7 +108,7 @@ void RunParsingTest(WorkerThread* thread) { WaitableEvent waitable_event; - thread->GetTaskRunner(TaskType::kUnthrottled) + thread->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind( @@ -120,7 +120,7 @@ void RunParsingParameterDescriptorTest(WorkerThread* thread) { WaitableEvent waitable_event; - thread->GetTaskRunner(TaskType::kUnthrottled) + thread->GetTaskRunner(TaskType::kInternalTest) ->PostTask( BLINK_FROM_HERE, CrossThreadBind(
diff --git a/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h b/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h index a59a5b7..a9b6b05d 100644 --- a/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h +++ b/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h
@@ -106,7 +106,7 @@ } scoped_refptr<WebTaskRunner> GetLoadingTaskRunner() override { - return frame_scheduler_->GetTaskRunner(TaskType::kUnspecedLoading); + return frame_scheduler_->GetTaskRunner(TaskType::kInternalTest); } private:
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.cc index a0d27a77..3c8975ef 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler.cc
@@ -56,6 +56,7 @@ case TaskType::kUnspecedTimer: case TaskType::kUnspecedLoading: case TaskType::kUnthrottled: + case TaskType::kInternalTest: // UnthrottledTaskRunner is generally discouraged in future. // TODO(nhiroki): Identify which tasks can be throttled / suspendable and // move them into other task runners. See also comments in
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc index 62ff5e4..8d820b4 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc
@@ -51,7 +51,7 @@ // Helper for posting a task. void PostTestTask(std::vector<std::string>* run_order, const std::string& task_descriptor) { - global_scope_scheduler_->GetTaskRunner(TaskType::kUnthrottled) + global_scope_scheduler_->GetTaskRunner(TaskType::kInternalTest) ->PostTask(FROM_HERE, WTF::Bind(&AppendToVectorTestTask, WTF::Unretained(run_order), task_descriptor));
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc index 1e93634..1e42413 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -260,6 +260,7 @@ case TaskType::kMediaElementEvent: return WebTaskRunnerImpl::Create(PausableTaskQueue(), type); case TaskType::kUnthrottled: + case TaskType::kInternalTest: return WebTaskRunnerImpl::Create(UnpausableTaskQueue(), type); case TaskType::kCount: NOTREACHED();
diff --git a/third_party/WebKit/public/platform/TaskType.h b/third_party/WebKit/public/platform/TaskType.h index e5734bd0..918227c 100644 --- a/third_party/WebKit/public/platform/TaskType.h +++ b/third_party/WebKit/public/platform/TaskType.h
@@ -10,6 +10,10 @@ // A list of task sources known to Blink according to the spec. // This enum is used for a histogram and it should not be re-numbered. enum class TaskType : unsigned { + /////////////////////////////////////// + // Speced tasks should use one of the following task types + /////////////////////////////////////// + // Speced tasks and related internal tasks should be posted to one of // the following task runners. These task runners may be throttled. @@ -108,6 +112,10 @@ // The task runner may be throttled. kMiscPlatformAPI = 22, + /////////////////////////////////////// + // The following task types are DEPRECATED! Use kInternal* instead. + /////////////////////////////////////// + // Other internal tasks that cannot fit any of the above task runners // can be posted here, but the usage is not encouraged. The task runner // may be throttled. @@ -121,7 +129,14 @@ // should be very limited. kUnthrottled = 25, - kCount = 26, + /////////////////////////////////////// + // Not-speced tasks should use one of the following task types + /////////////////////////////////////// + + // Tasks for tests or mock objects. + kInternalTest = 26, + + kCount = 27, }; } // namespace blink
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 9aeb4dd..849d3ab 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -36140,6 +36140,7 @@ <int value="23" label="UnspecedTimer"/> <int value="24" label="UnspecedLoading"/> <int value="25" label="Unthrottled"/> + <int value="26" label="InternalTest"/> </enum> <enum name="RendererSchedulerThreadType">