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"
21 #include "webkit/plugins/ppapi/mock_plugin_delegate.h"
27 class TestPluginDelegate
: public webkit::ppapi::MockPluginDelegate
{
29 TestPluginDelegate() : last_used_id_(0) {
32 virtual ~TestPluginDelegate() {
33 CHECK(callbacks_
.empty());
36 virtual int EnumerateDevices(
37 PP_DeviceType_Dev
/* type */,
38 const EnumerateDevicesCallback
& callback
) OVERRIDE
{
40 callbacks_
[last_used_id_
] = callback
;
44 virtual void StopEnumerateDevices(int request_id
) OVERRIDE
{
45 std::map
<int, EnumerateDevicesCallback
>::iterator iter
=
46 callbacks_
.find(request_id
);
47 CHECK(iter
!= callbacks_
.end());
48 callbacks_
.erase(iter
);
51 // Returns false if |request_id| is not found.
52 bool SimulateEnumerateResult(
55 const std::vector
<ppapi::DeviceRefData
>& devices
) {
56 std::map
<int, EnumerateDevicesCallback
>::iterator iter
=
57 callbacks_
.find(request_id
);
58 if (iter
== callbacks_
.end())
61 iter
->second
.Run(request_id
, succeeded
, devices
);
65 size_t GetRegisteredCallbackCount() const { return callbacks_
.size(); }
67 int last_used_id() const { return last_used_id_
; }
70 std::map
<int, EnumerateDevicesCallback
> callbacks_
;
73 DISALLOW_COPY_AND_ASSIGN(TestPluginDelegate
);
76 class TestResourceHost
: public ppapi::host::ResourceHost
,
77 public PepperDeviceEnumerationHostHelper::Delegate
{
79 TestResourceHost(ppapi::host::PpapiHost
* host
,
82 webkit::ppapi::PluginDelegate
* delegate
)
83 : ResourceHost(host
, instance
, resource
),
87 virtual ~TestResourceHost() {}
89 virtual webkit::ppapi::PluginDelegate
* GetPluginDelegate() OVERRIDE
{
94 webkit::ppapi::PluginDelegate
* delegate_
;
96 DISALLOW_COPY_AND_ASSIGN(TestResourceHost
);
99 class PepperDeviceEnumerationHostHelperTest
: public testing::Test
{
101 PepperDeviceEnumerationHostHelperTest()
102 : ppapi_host_(&sink_
, ppapi::PpapiPermissions()),
103 resource_host_(&ppapi_host_
, 12345, 67890, &delegate_
),
104 device_enumeration_(&resource_host_
, &resource_host_
,
105 PP_DEVICETYPE_DEV_AUDIOCAPTURE
) {
108 virtual ~PepperDeviceEnumerationHostHelperTest() {}
110 void SimulateMonitorDeviceChangeReceived(uint32_t callback_id
) {
111 PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange
msg(callback_id
);
112 ppapi::proxy::ResourceMessageCallParams
call_params(
113 resource_host_
.pp_resource(), 123);
114 ppapi::host::HostMessageContext
context(call_params
);
115 int32_t result
= PP_ERROR_FAILED
;
116 ASSERT_TRUE(device_enumeration_
.HandleResourceMessage(
117 msg
, &context
, &result
));
118 EXPECT_EQ(PP_OK
, result
);
121 void CheckNotifyDeviceChangeMessage(
122 uint32_t callback_id
,
123 const std::vector
<ppapi::DeviceRefData
>& expected
) {
124 ppapi::proxy::ResourceMessageReplyParams reply_params
;
125 IPC::Message reply_msg
;
126 ASSERT_TRUE(sink_
.GetFirstResourceReplyMatching(
127 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange::ID
,
128 &reply_params
, &reply_msg
));
129 sink_
.ClearMessages();
131 EXPECT_EQ(PP_OK
, reply_params
.result());
133 uint32_t reply_callback_id
= 0;
134 std::vector
<ppapi::DeviceRefData
> reply_data
;
135 ASSERT_TRUE(ppapi::UnpackMessage
<
136 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange
>(
137 reply_msg
, &reply_callback_id
, &reply_data
));
138 EXPECT_EQ(callback_id
, reply_callback_id
);
139 EXPECT_EQ(expected
, reply_data
);
142 TestPluginDelegate delegate_
;
143 ppapi::proxy::ResourceMessageTestSink sink_
;
144 ppapi::host::PpapiHost ppapi_host_
;
145 TestResourceHost resource_host_
;
146 PepperDeviceEnumerationHostHelper device_enumeration_
;
149 DISALLOW_COPY_AND_ASSIGN(PepperDeviceEnumerationHostHelperTest
);
154 TEST_F(PepperDeviceEnumerationHostHelperTest
, EnumerateDevices
) {
155 PpapiHostMsg_DeviceEnumeration_EnumerateDevices msg
;
156 ppapi::proxy::ResourceMessageCallParams
call_params(
157 resource_host_
.pp_resource(), 123);
158 ppapi::host::HostMessageContext
context(call_params
);
159 int32_t result
= PP_ERROR_FAILED
;
160 ASSERT_TRUE(device_enumeration_
.HandleResourceMessage(msg
, &context
,
162 EXPECT_EQ(PP_OK_COMPLETIONPENDING
, result
);
164 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
165 int request_id
= delegate_
.last_used_id();
167 std::vector
<ppapi::DeviceRefData
> data
;
168 ppapi::DeviceRefData data_item
;
169 data_item
.type
= PP_DEVICETYPE_DEV_AUDIOCAPTURE
;
170 data_item
.name
= "name_1";
171 data_item
.id
= "id_1";
172 data
.push_back(data_item
);
173 data_item
.type
= PP_DEVICETYPE_DEV_VIDEOCAPTURE
;
174 data_item
.name
= "name_2";
175 data_item
.id
= "id_2";
176 data
.push_back(data_item
);
177 ASSERT_TRUE(delegate_
.SimulateEnumerateResult(request_id
, true, data
));
179 // StopEnumerateDevices() should have been called since the EnumerateDevices
180 // message is not a persistent request.
181 EXPECT_EQ(0U, delegate_
.GetRegisteredCallbackCount());
183 // A reply message should have been sent to the test sink.
184 ppapi::proxy::ResourceMessageReplyParams reply_params
;
185 IPC::Message reply_msg
;
186 ASSERT_TRUE(sink_
.GetFirstResourceReplyMatching(
187 PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply::ID
,
188 &reply_params
, &reply_msg
));
190 EXPECT_EQ(call_params
.sequence(), reply_params
.sequence());
191 EXPECT_EQ(PP_OK
, reply_params
.result());
193 std::vector
<ppapi::DeviceRefData
> reply_data
;
194 ASSERT_TRUE(ppapi::UnpackMessage
<
195 PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply
>(
196 reply_msg
, &reply_data
));
197 EXPECT_EQ(data
, reply_data
);
200 TEST_F(PepperDeviceEnumerationHostHelperTest
, MonitorDeviceChange
) {
201 uint32_t callback_id
= 456;
202 SimulateMonitorDeviceChangeReceived(callback_id
);
204 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
205 int request_id
= delegate_
.last_used_id();
207 std::vector
<ppapi::DeviceRefData
> data
;
208 ASSERT_TRUE(delegate_
.SimulateEnumerateResult(request_id
, true, data
));
210 // StopEnumerateDevices() shouldn't be called because the MonitorDeviceChange
211 // message is a persistent request.
212 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
214 CheckNotifyDeviceChangeMessage(callback_id
, data
);
216 ppapi::DeviceRefData data_item
;
217 data_item
.type
= PP_DEVICETYPE_DEV_AUDIOCAPTURE
;
218 data_item
.name
= "name_1";
219 data_item
.id
= "id_1";
220 data
.push_back(data_item
);
221 data_item
.type
= PP_DEVICETYPE_DEV_VIDEOCAPTURE
;
222 data_item
.name
= "name_2";
223 data_item
.id
= "id_2";
224 data
.push_back(data_item
);
225 ASSERT_TRUE(delegate_
.SimulateEnumerateResult(request_id
, true, data
));
226 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
228 CheckNotifyDeviceChangeMessage(callback_id
, data
);
230 uint32_t callback_id2
= 789;
231 SimulateMonitorDeviceChangeReceived(callback_id2
);
233 // StopEnumerateDevice() should have been called for the previous request.
234 EXPECT_EQ(1U, delegate_
.GetRegisteredCallbackCount());
235 int request_id2
= delegate_
.last_used_id();
237 data_item
.type
= PP_DEVICETYPE_DEV_AUDIOCAPTURE
;
238 data_item
.name
= "name_3";
239 data_item
.id
= "id_3";
240 data
.push_back(data_item
);
241 ASSERT_TRUE(delegate_
.SimulateEnumerateResult(request_id2
, true, data
));
243 CheckNotifyDeviceChangeMessage(callback_id2
, data
);
245 PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange msg
;
246 ppapi::proxy::ResourceMessageCallParams
call_params(
247 resource_host_
.pp_resource(), 123);
248 ppapi::host::HostMessageContext
context(call_params
);
249 int32_t result
= PP_ERROR_FAILED
;
250 ASSERT_TRUE(device_enumeration_
.HandleResourceMessage(
251 msg
, &context
, &result
));
252 EXPECT_EQ(PP_OK
, result
);
254 EXPECT_EQ(0U, delegate_
.GetRegisteredCallbackCount());
257 } // namespace content