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.
5 #include "chrome/browser/extensions/api/cast_channel/cast_channel_api.h"
7 #include "base/values.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h"
10 #include "chrome/browser/extensions/event_router.h"
11 #include "chrome/browser/extensions/extension_system.h"
12 #include "chrome/browser/net/chrome_net_log.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "net/base/net_errors.h"
18 namespace extensions
{
20 namespace Close
= cast_channel::Close
;
21 namespace OnError
= cast_channel::OnError
;
22 namespace OnMessage
= cast_channel::OnMessage
;
23 namespace Open
= cast_channel::Open
;
24 namespace Send
= cast_channel::Send
;
25 using cast_channel::CastSocket
;
26 using cast_channel::ChannelError
;
27 using cast_channel::ChannelInfo
;
28 using cast_channel::MessageInfo
;
29 using cast_channel::ReadyState
;
30 using content::BrowserThread
;
33 const long kUnknownChannelId
= -1;
36 CastChannelAPI::CastChannelAPI(Profile
* profile
)
42 CastChannelAPI
* CastChannelAPI::Get(Profile
* profile
) {
43 return ProfileKeyedAPIFactory
<CastChannelAPI
>::GetForProfile(profile
);
46 static base::LazyInstance
<ProfileKeyedAPIFactory
<CastChannelAPI
> > g_factory
=
47 LAZY_INSTANCE_INITIALIZER
;
50 ProfileKeyedAPIFactory
<CastChannelAPI
>* CastChannelAPI::GetFactoryInstance() {
51 return &g_factory
.Get();
54 void CastChannelAPI::OnError(const CastSocket
* socket
,
55 cast_channel::ChannelError error
) {
56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
57 ChannelInfo channel_info
;
58 socket
->FillChannelInfo(&channel_info
);
59 channel_info
.error_state
= error
;
60 scoped_ptr
<base::ListValue
> results
= OnError::Create(channel_info
);
61 scoped_ptr
<Event
> event(new Event(OnError::kEventName
, results
.Pass()));
62 extensions::ExtensionSystem::Get(profile_
)->event_router()->
63 DispatchEventToExtension(socket
->owner_extension_id(), event
.Pass());
65 // Destroy the socket that caused the error.
66 ApiResourceManager
<CastSocket
>* manager
=
67 ApiResourceManager
<CastSocket
>::Get(profile_
);
68 manager
->Remove(socket
->owner_extension_id(), socket
->id());
71 void CastChannelAPI::OnMessage(const CastSocket
* socket
,
72 const MessageInfo
& message_info
) {
73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
74 ChannelInfo channel_info
;
75 socket
->FillChannelInfo(&channel_info
);
76 scoped_ptr
<base::ListValue
> results
=
77 OnMessage::Create(channel_info
, message_info
);
78 scoped_ptr
<Event
> event(new Event(OnMessage::kEventName
, results
.Pass()));
79 extensions::ExtensionSystem::Get(profile_
)->event_router()->
80 DispatchEventToExtension(socket
->owner_extension_id(), event
.Pass());
83 CastChannelAPI::~CastChannelAPI() {}
85 CastChannelAsyncApiFunction::CastChannelAsyncApiFunction()
86 : socket_(NULL
), channel_id_(kUnknownChannelId
), manager_(NULL
),
87 error_(cast_channel::CHANNEL_ERROR_NONE
) { }
89 CastChannelAsyncApiFunction::~CastChannelAsyncApiFunction() { }
91 bool CastChannelAsyncApiFunction::PrePrepare() {
92 manager_
= ApiResourceManager
<CastSocket
>::Get(profile());
96 bool CastChannelAsyncApiFunction::Respond() {
97 return error_
!= cast_channel::CHANNEL_ERROR_NONE
;
100 ApiResourceManager
<api::cast_channel::CastSocket
>*
101 CastChannelAsyncApiFunction::GetSocketManager() {
102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
106 CastSocket
* CastChannelAsyncApiFunction::GetSocket(long channel_id
) {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
109 DCHECK_EQ(channel_id_
, kUnknownChannelId
);
110 CastSocket
* socket
= GetSocketManager()->Get(extension_
->id(), channel_id
);
113 channel_id_
= channel_id
;
118 void CastChannelAsyncApiFunction::RemoveSocketIfError() {
119 if (error_
!= cast_channel::CHANNEL_ERROR_NONE
)
123 void CastChannelAsyncApiFunction::RemoveSocket() {
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
126 DCHECK(channel_id_
!= kUnknownChannelId
);
127 GetSocketManager()->Remove(extension_
->id(), channel_id_
);
128 channel_id_
= kUnknownChannelId
;
132 void CastChannelAsyncApiFunction::SetResultFromChannelInfo(
133 const ChannelInfo
& channel_info
) {
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
135 SetResult(channel_info
.ToValue().release());
138 void CastChannelAsyncApiFunction::SetResultFromSocket() {
140 ChannelInfo channel_info
;
141 socket_
->FillChannelInfo(&channel_info
);
142 error_
= socket_
->error_state();
143 SetResultFromChannelInfo(channel_info
);
146 void CastChannelAsyncApiFunction::SetResultFromError(
147 const std::string
& url
, ChannelError error
) {
148 ChannelInfo channel_info
;
149 channel_info
.channel_id
= channel_id_
;
150 channel_info
.url
= url
;
151 channel_info
.ready_state
= cast_channel::READY_STATE_CLOSED
;
152 channel_info
.error_state
= error
;
153 SetResultFromChannelInfo(channel_info
);
157 CastChannelOpenFunction::CastChannelOpenFunction() { }
159 CastChannelOpenFunction::~CastChannelOpenFunction() { }
161 bool CastChannelOpenFunction::PrePrepare() {
162 api_
= CastChannelAPI::Get(profile());
163 return CastChannelAsyncApiFunction::PrePrepare();
166 bool CastChannelOpenFunction::Prepare() {
167 params_
= Open::Params::Create(*args_
);
168 EXTENSION_FUNCTION_VALIDATE(params_
.get());
172 void CastChannelOpenFunction::AsyncWorkStart() {
174 socket_
= new CastSocket(extension_
->id(), GURL(params_
->url
),
175 api_
, g_browser_process
->net_log());
176 socket_
->Connect(base::Bind(&CastChannelOpenFunction::OnOpen
, this));
179 void CastChannelOpenFunction::OnOpen(int result
) {
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
181 if (result
== net::OK
) {
182 socket_
->set_id(GetSocketManager()->Add(socket_
));
183 SetResultFromSocket();
185 SetResultFromError(params_
->url
,
186 cast_channel::CHANNEL_ERROR_CONNECT_ERROR
);
188 RemoveSocketIfError();
189 AsyncWorkCompleted();
192 CastChannelSendFunction::CastChannelSendFunction() { }
194 CastChannelSendFunction::~CastChannelSendFunction() { }
196 bool CastChannelSendFunction::Prepare() {
197 params_
= Send::Params::Create(*args_
);
198 EXTENSION_FUNCTION_VALIDATE(params_
.get());
202 void CastChannelSendFunction::AsyncWorkStart() {
203 if (!GetSocket(params_
->channel
.channel_id
)) {
204 SetResultFromError("",
205 cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID
);
206 AsyncWorkCompleted();
209 socket_
->SendMessage(params_
->message
,
210 base::Bind(&CastChannelSendFunction::OnSend
, this));
213 void CastChannelSendFunction::OnSend(int result
) {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
216 SetResultFromError("",
217 cast_channel::CHANNEL_ERROR_SOCKET_ERROR
);
219 SetResultFromSocket();
221 RemoveSocketIfError();
222 AsyncWorkCompleted();
225 CastChannelCloseFunction::CastChannelCloseFunction() { }
227 CastChannelCloseFunction::~CastChannelCloseFunction() { }
229 bool CastChannelCloseFunction::Prepare() {
230 params_
= Close::Params::Create(*args_
);
231 EXTENSION_FUNCTION_VALIDATE(params_
.get());
235 void CastChannelCloseFunction::AsyncWorkStart() {
236 if (!GetSocket(params_
->channel
.channel_id
)) {
237 SetResultFromError("", cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID
);
238 AsyncWorkCompleted();
241 socket_
->Close(base::Bind(&CastChannelCloseFunction::OnClose
, this));
244 void CastChannelCloseFunction::OnClose(int result
) {
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
246 DVLOG(1) << "CastChannelCloseFunction::OnClose result = " << result
;
248 SetResultFromError("", cast_channel::CHANNEL_ERROR_SOCKET_ERROR
);
249 RemoveSocketIfError();
251 SetResultFromSocket();
254 AsyncWorkCompleted();
257 } // namespace extensions