1// Copyright 2013 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 "ppapi/proxy/locking_resource_releaser.h"
6#include "ppapi/proxy/plugin_message_filter.h"
7#include "ppapi/proxy/ppapi_messages.h"
8#include "ppapi/proxy/ppapi_proxy_test.h"
9#include "ppapi/proxy/talk_resource.h"
10#include "ppapi/thunk/thunk.h"
11
12namespace ppapi {
13namespace proxy {
14
15namespace {
16
17template <class ResultType>
18class MockCallbackBase {
19 public:
20  MockCallbackBase() : called_(false) {
21  }
22
23  bool called() {
24    return called_;
25  }
26
27  ResultType result() {
28    return result_;
29  }
30
31  void Reset() {
32    called_ = false;
33  }
34
35  static void Callback(void* user_data, ResultType result) {
36    MockCallbackBase* that = reinterpret_cast<MockCallbackBase*>(user_data);
37    that->called_ = true;
38    that->result_ = result;
39  }
40
41 private:
42  bool called_;
43  ResultType result_;
44};
45
46typedef MockCallbackBase<int32_t> MockCompletionCallback;
47typedef MockCallbackBase<PP_TalkEvent> TalkEventCallback;
48
49class TalkResourceTest : public PluginProxyTest {
50 public:
51  void SendReply(
52      uint32_t id,
53      const IPC::Message& reply,
54      int32_t result) {
55    IPC::Message msg;
56    ResourceMessageCallParams params;
57    ASSERT_TRUE(sink().GetFirstResourceCallMatching(id, &params, &msg));
58
59    ResourceMessageReplyParams reply_params(params.pp_resource(),
60                                            params.sequence());
61    reply_params.set_result(result);
62    PluginMessageFilter::DispatchResourceReplyForTest(reply_params, reply);
63  }
64};
65
66
67}  // namespace
68
69TEST_F(TalkResourceTest, GetPermission) {
70  const PPB_Talk_Private_1_0* talk = thunk::GetPPB_Talk_Private_1_0_Thunk();
71  LockingResourceReleaser res(talk->Create(pp_instance()));
72  MockCompletionCallback callback;
73
74  int32_t result = talk->GetPermission(
75      res.get(),
76      PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &callback));
77  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
78
79  ResourceMessageCallParams params;
80  IPC::Message msg;
81  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
82      PpapiHostMsg_Talk_RequestPermission::ID, &params, &msg));
83
84  ResourceMessageReplyParams reply_params(params.pp_resource(),
85                                          params.sequence());
86  reply_params.set_result(1);
87  PluginMessageFilter::DispatchResourceReplyForTest(
88      reply_params, PpapiPluginMsg_Talk_RequestPermissionReply());
89
90  ASSERT_TRUE(callback.called());
91  ASSERT_EQ(1, callback.result());
92}
93
94TEST_F(TalkResourceTest, RequestPermission) {
95  const PPB_Talk_Private_2_0* talk = thunk::GetPPB_Talk_Private_2_0_Thunk();
96  LockingResourceReleaser res(talk->Create(pp_instance()));
97  MockCompletionCallback callback;
98
99  int32_t result = talk->RequestPermission(
100      res.get(),
101      PP_TALKPERMISSION_REMOTING_CONTINUE,
102      PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &callback));
103  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
104
105  ResourceMessageCallParams params;
106  IPC::Message msg;
107  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
108      PpapiHostMsg_Talk_RequestPermission::ID, &params, &msg));
109
110  ResourceMessageReplyParams reply_params(params.pp_resource(),
111                                          params.sequence());
112  reply_params.set_result(1);
113  PluginMessageFilter::DispatchResourceReplyForTest(
114      reply_params, PpapiPluginMsg_Talk_RequestPermissionReply());
115
116  ASSERT_TRUE(callback.called());
117  ASSERT_EQ(1, callback.result());
118}
119
120TEST_F(TalkResourceTest, StartStopRemoting) {
121  const PPB_Talk_Private_2_0* talk = thunk::GetPPB_Talk_Private_2_0_Thunk();
122  LockingResourceReleaser res(talk->Create(pp_instance()));
123  MockCompletionCallback callback;
124  TalkEventCallback event_callback;
125
126  // Start
127  int32_t result = talk->StartRemoting(
128      res.get(),
129      &TalkEventCallback::Callback,
130      &event_callback,
131      PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &callback));
132  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
133
134  SendReply(PpapiHostMsg_Talk_StartRemoting::ID,
135            PpapiPluginMsg_Talk_StartRemotingReply(),
136            PP_OK);
137
138  ASSERT_TRUE(callback.called());
139  ASSERT_EQ(PP_OK, callback.result());
140
141  // Receive an event
142  ASSERT_FALSE(event_callback.called());
143  ResourceMessageReplyParams notify_params(res.get(), 0);
144  PluginMessageFilter::DispatchResourceReplyForTest(
145      notify_params, PpapiPluginMsg_Talk_NotifyEvent(PP_TALKEVENT_ERROR));
146  ASSERT_TRUE(event_callback.called());
147  ASSERT_EQ(PP_TALKEVENT_ERROR, event_callback.result());
148
149  // Stop
150  callback.Reset();
151  result = talk->StopRemoting(
152      res.get(),
153      PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &callback));
154  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
155
156  SendReply(PpapiHostMsg_Talk_StopRemoting::ID,
157           PpapiPluginMsg_Talk_StopRemotingReply(),
158           PP_OK);
159
160  ASSERT_TRUE(callback.called());
161  ASSERT_EQ(PP_OK, callback.result());
162
163  // Events should be discarded at this point
164  event_callback.Reset();
165  PluginMessageFilter::DispatchResourceReplyForTest(
166      notify_params, PpapiPluginMsg_Talk_NotifyEvent(PP_TALKEVENT_ERROR));
167  ASSERT_FALSE(event_callback.called());
168}
169
170}  // namespace proxy
171}  // namespace ppapi
172