Features:
[chromium-blink-merge.git] / chrome / browser / extensions / api / cast_channel / cast_channel_api.cc
blob4f216c9dfed2a2428ecf4e38a4e3d4b8b81ebe72
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"
16 #include "url/gurl.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;
32 namespace {
33 const long kUnknownChannelId = -1;
34 } // namespace
36 CastChannelAPI::CastChannelAPI(Profile* profile)
37 : profile_(profile) {
38 DCHECK(profile_);
41 // static
42 CastChannelAPI* CastChannelAPI::Get(Profile* profile) {
43 return ProfileKeyedAPIFactory<CastChannelAPI>::GetForProfile(profile);
46 static base::LazyInstance<ProfileKeyedAPIFactory<CastChannelAPI> > g_factory =
47 LAZY_INSTANCE_INITIALIZER;
49 // static
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());
93 return true;
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));
103 return manager_;
106 CastSocket* CastChannelAsyncApiFunction::GetSocket(long channel_id) {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
108 DCHECK(!socket_);
109 DCHECK_EQ(channel_id_, kUnknownChannelId);
110 CastSocket* socket = GetSocketManager()->Get(extension_->id(), channel_id);
111 if (socket) {
112 socket_ = socket;
113 channel_id_ = channel_id;
115 return socket;
118 void CastChannelAsyncApiFunction::RemoveSocketIfError() {
119 if (error_ != cast_channel::CHANNEL_ERROR_NONE)
120 RemoveSocket();
123 void CastChannelAsyncApiFunction::RemoveSocket() {
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
125 DCHECK(socket_);
126 DCHECK(channel_id_ != kUnknownChannelId);
127 GetSocketManager()->Remove(extension_->id(), channel_id_);
128 channel_id_ = kUnknownChannelId;
129 socket_ = NULL;
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() {
139 DCHECK(socket_);
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);
154 error_ = error;
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());
169 return true;
172 void CastChannelOpenFunction::AsyncWorkStart() {
173 DCHECK(api_);
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();
184 } else {
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());
199 return true;
202 void CastChannelSendFunction::AsyncWorkStart() {
203 if (!GetSocket(params_->channel.channel_id)) {
204 SetResultFromError("",
205 cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID);
206 AsyncWorkCompleted();
207 return;
209 socket_->SendMessage(params_->message,
210 base::Bind(&CastChannelSendFunction::OnSend, this));
213 void CastChannelSendFunction::OnSend(int result) {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
215 if (result < 0) {
216 SetResultFromError("",
217 cast_channel::CHANNEL_ERROR_SOCKET_ERROR);
218 } else {
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());
232 return true;
235 void CastChannelCloseFunction::AsyncWorkStart() {
236 if (!GetSocket(params_->channel.channel_id)) {
237 SetResultFromError("", cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID);
238 AsyncWorkCompleted();
239 return;
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;
247 if (result < 0) {
248 SetResultFromError("", cast_channel::CHANNEL_ERROR_SOCKET_ERROR);
249 RemoveSocketIfError();
250 } else {
251 SetResultFromSocket();
252 RemoveSocket();
254 AsyncWorkCompleted();
257 } // namespace extensions