1 // Copyright (c) 2012 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.
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/logging.h"
10 #include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
11 #include "ppapi/c/pp_errors.h"
12 #include "ppapi/host/host_message_context.h"
13 #include "ppapi/host/ppapi_host.h"
14 #include "ppapi/host/resource_host.h"
15 #include "ppapi/proxy/ppapi_message_utils.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/proxy/resource_message_params.h"
18 #include "ppapi/proxy/resource_message_test_sink.h"
19 #include "ppapi/shared_impl/ppapi_permissions.h"
20 #include "testing/gtest/include/gtest/gtest.h"
26 class TestDelegate
: public PepperDeviceEnumerationHostHelper::Delegate
{
28 TestDelegate() : last_used_id_(0) {
31 virtual ~TestDelegate() {
32 CHECK(callbacks_
.empty());
35 virtual int EnumerateDevices(
36 PP_DeviceType_Dev
/* type */,
37 const EnumerateDevicesCallback
& callback
) OVERRIDE
{
39 callbacks_
[last_used_id_
] = callback
;
43 virtual void StopEnumerateDevices(int request_id
) OVERRIDE
{
44 std::map
<int, EnumerateDevicesCallback
>::iterator iter
=
45 callbacks_
.find(request_id
);
46 CHECK(iter
!= callbacks_
.end());
47 callbacks_
.erase(iter
);
50 // Returns false if |request_id| is not found.
51 bool SimulateEnumerateResult(
54 const std::vector
<ppapi::DeviceRefData
>& devices
) {
55 std::map
<int, EnumerateDevicesCallback
>::iterator iter
=
56 callbacks_
.find(request_id
);
57 if (iter
== callbacks_
.end())
60 iter
->second
.Run(request_id
, succeeded
, devices
);
64 size_t GetRegisteredCallbackCount() const { return callbacks_
.size(); }
66 int last_used_id() const { return last_used_id_
; }
69 std::map
<int, EnumerateDevicesCallback
> callbacks_
;
72 DISALLOW_COPY_AND_ASSIGN(TestDelegate
);
75 class PepperDeviceEnumerationHostHelperTest
: public testing::Test
{
77 PepperDeviceEnumerationHostHelperTest()
78 : ppapi_host_(&sink_
, ppapi::PpapiPermissions()),
79 resource_host_(&ppapi_host_
, 12345, 67890),
80 device_enumeration_(&resource_host_
, &delegate_
,
81 PP_DEVICETYPE_DEV_AUDIOCAPTURE
) {
84 virtual ~PepperDeviceEnumerationHostHelperTest() {}
86 void SimulateMonitorDeviceChangeReceived(uint32_t callback_id
) {
87 PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange
msg(callback_id
);
88 ppapi::proxy::ResourceMessageCallParams
call_params(
89 resource_host_
.pp_resource(), 123);
90 ppapi::host::HostMessageContext
context(call_params
);
91 int32_t result
= PP_ERROR_FAILED
;
92 ASSERT_TRUE(device_enumeration_
.HandleResourceMessage(
93 msg
, &context
, &result
));
94 EXPECT_EQ(PP_OK
, result
);
97 void CheckNotifyDeviceChangeMessage(
99 const std::vector
<ppapi::DeviceRefData
>& expected
) {
100 ppapi::proxy::ResourceMessageReplyParams reply_params
;
101 IPC::Message reply_msg
;
102 ASSERT_TRUE(sink_
.GetFirstResourceReplyMatching(
103 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange::ID
,
104 &reply_params
, &reply_msg
));
105 sink_
.ClearMessages();
107 EXPECT_EQ(PP_OK
, reply_params
.result());
109 uint32_t reply_callback_id
= 0;
110 std::vector
<ppapi::DeviceRefData
> reply_data
;
111 ASSERT_TRUE(ppapi::UnpackMessage
<
112 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange
>(
113 reply_msg
, &reply_callback_id
, &reply_data
));
114 EXPECT_EQ(callback_id
, reply_callback_id
);
115 EXPECT_EQ(expected
, reply_data
);
118 TestDelegate delegate_
;
119 ppapi::proxy::ResourceMessageTestSink sink_
;
120 ppapi::host::PpapiHost ppapi_host_
;
121 ppapi::host::ResourceHost resource_host_
;
122 PepperDeviceEnumerationHostHelper device_enumeration_
;
125 DISALLOW_COPY_AND_ASSIGN(PepperDeviceEnumerationHostHelperTest
);
130 TEST_F(PepperDeviceEnumerationHostHelperTest
, EnumerateDevices
) {
131 PpapiHostMsg_DeviceEnumeration_EnumerateDevices msg
;
132 ppapi::proxy::ResourceMessageCallParams
call_params(
133 resource_host_
.pp_resource(), 123);
134 ppapi::host::HostMessageContext
context(call_params
);
135 int32_t result
= PP_ERROR_FAILED
;
136 ASSERT_TRUE(device_enumeration_
.HandleResourceMessage(msg
, &context
,
138 EXPECT_EQ(PP_OK_COMPLETIONPENDING
, result
);
140 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
141 int request_id
= delegate_
.last_used_id();
143 std::vector
<ppapi::DeviceRefData
> data
;
144 ppapi::DeviceRefData data_item
;
145 data_item
.type
= PP_DEVICETYPE_DEV_AUDIOCAPTURE
;
146 data_item
.name
= "name_1";
147 data_item
.id
= "id_1";
148 data
.push_back(data_item
);
149 data_item
.type
= PP_DEVICETYPE_DEV_VIDEOCAPTURE
;
150 data_item
.name
= "name_2";
151 data_item
.id
= "id_2";
152 data
.push_back(data_item
);
153 ASSERT_TRUE(delegate_
.SimulateEnumerateResult(request_id
, true, data
));
155 // StopEnumerateDevices() should have been called since the EnumerateDevices
156 // message is not a persistent request.
157 EXPECT_EQ(0U, delegate_
.GetRegisteredCallbackCount());
159 // A reply message should have been sent to the test sink.
160 ppapi::proxy::ResourceMessageReplyParams reply_params
;
161 IPC::Message reply_msg
;
162 ASSERT_TRUE(sink_
.GetFirstResourceReplyMatching(
163 PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply::ID
,
164 &reply_params
, &reply_msg
));
166 EXPECT_EQ(call_params
.sequence(), reply_params
.sequence());
167 EXPECT_EQ(PP_OK
, reply_params
.result());
169 std::vector
<ppapi::DeviceRefData
> reply_data
;
170 ASSERT_TRUE(ppapi::UnpackMessage
<
171 PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply
>(
172 reply_msg
, &reply_data
));
173 EXPECT_EQ(data
, reply_data
);
176 TEST_F(PepperDeviceEnumerationHostHelperTest
, MonitorDeviceChange
) {
177 uint32_t callback_id
= 456;
178 SimulateMonitorDeviceChangeReceived(callback_id
);
180 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
181 int request_id
= delegate_
.last_used_id();
183 std::vector
<ppapi::DeviceRefData
> data
;
184 ASSERT_TRUE(delegate_
.SimulateEnumerateResult(request_id
, true, data
));
186 // StopEnumerateDevices() shouldn't be called because the MonitorDeviceChange
187 // message is a persistent request.
188 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
190 CheckNotifyDeviceChangeMessage(callback_id
, data
);
192 ppapi::DeviceRefData data_item
;
193 data_item
.type
= PP_DEVICETYPE_DEV_AUDIOCAPTURE
;
194 data_item
.name
= "name_1";
195 data_item
.id
= "id_1";
196 data
.push_back(data_item
);
197 data_item
.type
= PP_DEVICETYPE_DEV_VIDEOCAPTURE
;
198 data_item
.name
= "name_2";
199 data_item
.id
= "id_2";
200 data
.push_back(data_item
);
201 ASSERT_TRUE(delegate_
.SimulateEnumerateResult(request_id
, true, data
));
202 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
204 CheckNotifyDeviceChangeMessage(callback_id
, data
);
206 uint32_t callback_id2
= 789;
207 SimulateMonitorDeviceChangeReceived(callback_id2
);
209 // StopEnumerateDevice() should have been called for the previous request.
210 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
211 int request_id2
= delegate_
.last_used_id();
213 data_item
.type
= PP_DEVICETYPE_DEV_AUDIOCAPTURE
;
214 data_item
.name
= "name_3";
215 data_item
.id
= "id_3";
216 data
.push_back(data_item
);
217 ASSERT_TRUE(delegate_
.SimulateEnumerateResult(request_id2
, true, data
));
219 CheckNotifyDeviceChangeMessage(callback_id2
, data
);
221 PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange msg
;
222 ppapi::proxy::ResourceMessageCallParams
call_params(
223 resource_host_
.pp_resource(), 123);
224 ppapi::host::HostMessageContext
context(call_params
);
225 int32_t result
= PP_ERROR_FAILED
;
226 ASSERT_TRUE(device_enumeration_
.HandleResourceMessage(
227 msg
, &context
, &result
));
228 EXPECT_EQ(PP_OK
, result
);
230 EXPECT_EQ(0U, delegate_
.GetRegisteredCallbackCount());
233 } // namespace content