-
Notifications
You must be signed in to change notification settings - Fork 6.6k
/
arc_camera_bridge.cc
155 lines (128 loc) · 5.32 KB
/
arc_camera_bridge.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/arc/camera/arc_camera_bridge.h"
#include <utility>
#include "base/bind.h"
#include "base/files/scoped_file.h"
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "chromeos/dbus/arc/arc_camera_client.h"
#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
#include "components/arc/session/arc_bridge_service.h"
#include "crypto/random.h"
#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/platform_handle.h"
namespace arc {
namespace {
// Singleton factory for ArcCameraBridge.
class ArcCameraBridgeFactory
: public internal::ArcBrowserContextKeyedServiceFactoryBase<
ArcCameraBridge,
ArcCameraBridgeFactory> {
public:
// Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
static constexpr const char* kName = "ArcCameraBridgeFactory";
static ArcCameraBridgeFactory* GetInstance() {
return base::Singleton<ArcCameraBridgeFactory>::get();
}
private:
friend base::DefaultSingletonTraits<ArcCameraBridgeFactory>;
ArcCameraBridgeFactory() = default;
~ArcCameraBridgeFactory() override = default;
};
} // namespace
// Runs the callback after verifying the connection to the service.
class ArcCameraBridge::PendingStartCameraServiceResult {
public:
PendingStartCameraServiceResult(
ArcCameraBridge* owner,
mojo::ScopedMessagePipeHandle pipe,
ArcCameraBridge::StartCameraServiceCallback callback)
: owner_(owner),
service_(
mojo::PendingRemote<mojom::CameraService>(std::move(pipe), 0u)),
callback_(std::move(callback)) {
service_.set_disconnect_handler(
base::BindOnce(&PendingStartCameraServiceResult::OnError,
weak_ptr_factory_.GetWeakPtr()));
service_.QueryVersion(
base::BindOnce(&PendingStartCameraServiceResult::OnVersionReady,
weak_ptr_factory_.GetWeakPtr()));
}
~PendingStartCameraServiceResult() = default;
private:
void OnVersionReady(uint32_t version) { Finish(); }
void OnError() {
LOG(ERROR) << "Failed to query the camera service version.";
// Run the callback anyways. The same error will be delivered to the Android
// side error handler.
Finish();
}
// Runs the callback and removes this object from the owner.
void Finish() {
DCHECK(callback_);
std::move(callback_).Run(service_.Unbind());
// Destructs |this|.
owner_->pending_start_camera_service_results_.erase(this);
}
ArcCameraBridge* const owner_;
mojo::Remote<mojom::CameraService> service_;
ArcCameraBridge::StartCameraServiceCallback callback_;
base::WeakPtrFactory<PendingStartCameraServiceResult> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(PendingStartCameraServiceResult);
};
// static
ArcCameraBridge* ArcCameraBridge::GetForBrowserContext(
content::BrowserContext* context) {
return ArcCameraBridgeFactory::GetForBrowserContext(context);
}
ArcCameraBridge::ArcCameraBridge(content::BrowserContext* context,
ArcBridgeService* bridge_service)
: arc_bridge_service_(bridge_service) {
arc_bridge_service_->camera()->SetHost(this);
}
ArcCameraBridge::~ArcCameraBridge() {
arc_bridge_service_->camera()->SetHost(nullptr);
}
void ArcCameraBridge::StartCameraService(StartCameraServiceCallback callback) {
char random_bytes[16];
crypto::RandBytes(random_bytes, 16);
std::string token = base::HexEncode(random_bytes, 16);
mojo::OutgoingInvitation invitation;
mojo::PlatformChannel channel;
mojo::ScopedMessagePipeHandle server_pipe =
invitation.AttachMessagePipe(token);
// Run the callback after verifying the connection to the service process.
auto pending_result = std::make_unique<PendingStartCameraServiceResult>(
this, std::move(server_pipe), std::move(callback));
auto* pending_result_ptr = pending_result.get();
pending_start_camera_service_results_[pending_result_ptr] =
std::move(pending_result);
mojo::OutgoingInvitation::Send(std::move(invitation),
base::kNullProcessHandle,
channel.TakeLocalEndpoint());
base::ScopedFD fd =
channel.TakeRemoteEndpoint().TakePlatformHandle().TakeFD();
chromeos::ArcCameraClient::Get()->StartService(
fd.get(), token, base::BindOnce([](bool success) {}));
}
void ArcCameraBridge::RegisterCameraHalClientLegacy(
mojo::PendingRemote<cros::mojom::CameraHalClient> client) {
media::CameraHalDispatcherImpl::GetInstance()->RegisterClient(
std::move(client));
}
void ArcCameraBridge::RegisterCameraHalClient(
mojo::PendingRemote<cros::mojom::CameraHalClient> client,
RegisterCameraHalClientCallback callback) {
auto* dispatcher = media::CameraHalDispatcherImpl::GetInstance();
auto type = cros::mojom::CameraClientType::ANDROID;
dispatcher->RegisterClientWithToken(
std::move(client), type, dispatcher->GetTokenForTrustedClient(type),
std::move(callback));
}
} // namespace arc