1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/image_capture/image_capture_impl.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/task/post_task.h"
12 #include "base/unguessable_token.h"
13 #include "content/browser/browser_main_loop.h"
14 #include "content/browser/renderer_host/media/media_stream_manager.h"
15 #include "content/browser/renderer_host/media/video_capture_manager.h"
16 #include "content/public/browser/browser_task_traits.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/common/content_features.h"
19 #include "media/base/bind_to_current_loop.h"
20 #include "media/capture/mojom/image_capture_types.h"
21 #include "media/capture/video/video_capture_device.h"
22 #include "mojo/public/cpp/bindings/callback_helpers.h"
23 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
24 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
25
26 namespace content {
27
28 namespace {
29
GetPhotoStateOnIOThread(const std::string & source_id,MediaStreamManager * media_stream_manager,ImageCaptureImpl::GetPhotoStateCallback callback)30 void GetPhotoStateOnIOThread(const std::string& source_id,
31 MediaStreamManager* media_stream_manager,
32 ImageCaptureImpl::GetPhotoStateCallback callback) {
33 DCHECK_CURRENTLY_ON(BrowserThread::IO);
34
35 const base::UnguessableToken session_id =
36 media_stream_manager->VideoDeviceIdToSessionId(source_id);
37 if (session_id.is_empty())
38 return;
39
40 media_stream_manager->video_capture_manager()->GetPhotoState(
41 session_id, std::move(callback));
42 }
43
SetOptionsOnIOThread(const std::string & source_id,MediaStreamManager * media_stream_manager,media::mojom::PhotoSettingsPtr settings,ImageCaptureImpl::SetOptionsCallback callback)44 void SetOptionsOnIOThread(const std::string& source_id,
45 MediaStreamManager* media_stream_manager,
46 media::mojom::PhotoSettingsPtr settings,
47 ImageCaptureImpl::SetOptionsCallback callback) {
48 DCHECK_CURRENTLY_ON(BrowserThread::IO);
49
50 const base::UnguessableToken session_id =
51 media_stream_manager->VideoDeviceIdToSessionId(source_id);
52 if (session_id.is_empty())
53 return;
54 media_stream_manager->video_capture_manager()->SetPhotoOptions(
55 session_id, std::move(settings), std::move(callback));
56 }
57
TakePhotoOnIOThread(const std::string & source_id,MediaStreamManager * media_stream_manager,ImageCaptureImpl::TakePhotoCallback callback)58 void TakePhotoOnIOThread(const std::string& source_id,
59 MediaStreamManager* media_stream_manager,
60 ImageCaptureImpl::TakePhotoCallback callback) {
61 DCHECK_CURRENTLY_ON(BrowserThread::IO);
62 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
63 "image_capture_impl.cc::TakePhotoOnIOThread",
64 TRACE_EVENT_SCOPE_PROCESS);
65
66 const base::UnguessableToken session_id =
67 media_stream_manager->VideoDeviceIdToSessionId(source_id);
68 if (session_id.is_empty())
69 return;
70
71 media_stream_manager->video_capture_manager()->TakePhoto(session_id,
72 std::move(callback));
73 }
74
75 } // anonymous namespace
76
ImageCaptureImpl()77 ImageCaptureImpl::ImageCaptureImpl() {}
78
~ImageCaptureImpl()79 ImageCaptureImpl::~ImageCaptureImpl() {}
80
81 // static
Create(mojo::PendingReceiver<media::mojom::ImageCapture> receiver)82 void ImageCaptureImpl::Create(
83 mojo::PendingReceiver<media::mojom::ImageCapture> receiver) {
84 mojo::MakeSelfOwnedReceiver(std::make_unique<ImageCaptureImpl>(),
85 std::move(receiver));
86 }
87
GetPhotoState(const std::string & source_id,GetPhotoStateCallback callback)88 void ImageCaptureImpl::GetPhotoState(const std::string& source_id,
89 GetPhotoStateCallback callback) {
90 DCHECK_CURRENTLY_ON(BrowserThread::UI);
91 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
92 "ImageCaptureImpl::GetPhotoState",
93 TRACE_EVENT_SCOPE_PROCESS);
94
95 GetPhotoStateCallback scoped_callback =
96 mojo::WrapCallbackWithDefaultInvokeIfNotRun(
97 media::BindToCurrentLoop(std::move(callback)),
98 mojo::CreateEmptyPhotoState());
99 base::PostTask(
100 FROM_HERE, {BrowserThread::IO},
101 base::BindOnce(&GetPhotoStateOnIOThread, source_id,
102 BrowserMainLoop::GetInstance()->media_stream_manager(),
103 std::move(scoped_callback)));
104 }
105
SetOptions(const std::string & source_id,media::mojom::PhotoSettingsPtr settings,SetOptionsCallback callback)106 void ImageCaptureImpl::SetOptions(const std::string& source_id,
107 media::mojom::PhotoSettingsPtr settings,
108 SetOptionsCallback callback) {
109 DCHECK_CURRENTLY_ON(BrowserThread::UI);
110 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
111 "ImageCaptureImpl::SetOptions",
112 TRACE_EVENT_SCOPE_PROCESS);
113
114 SetOptionsCallback scoped_callback =
115 mojo::WrapCallbackWithDefaultInvokeIfNotRun(
116 media::BindToCurrentLoop(std::move(callback)), false);
117 base::PostTask(
118 FROM_HERE, {BrowserThread::IO},
119 base::BindOnce(&SetOptionsOnIOThread, source_id,
120 BrowserMainLoop::GetInstance()->media_stream_manager(),
121 std::move(settings), std::move(scoped_callback)));
122 }
123
TakePhoto(const std::string & source_id,TakePhotoCallback callback)124 void ImageCaptureImpl::TakePhoto(const std::string& source_id,
125 TakePhotoCallback callback) {
126 DCHECK_CURRENTLY_ON(BrowserThread::UI);
127 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"),
128 "ImageCaptureImpl::TakePhoto",
129 TRACE_EVENT_SCOPE_PROCESS);
130
131 TakePhotoCallback scoped_callback =
132 mojo::WrapCallbackWithDefaultInvokeIfNotRun(
133 media::BindToCurrentLoop(std::move(callback)),
134 media::mojom::Blob::New());
135 base::PostTask(
136 FROM_HERE, {BrowserThread::IO},
137 base::BindOnce(&TakePhotoOnIOThread, source_id,
138 BrowserMainLoop::GetInstance()->media_stream_manager(),
139 std::move(scoped_callback)));
140 }
141
142 } // namespace content
143