Move the serial API to extensions/.
[chromium-blink-merge.git] / extensions / browser / api / serial / serial_event_dispatcher.cc
blob759fc32d5bd3c4c3957243a4277335c0ea974eb7
1 // Copyright 2014 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 "extensions/browser/api/serial/serial_event_dispatcher.h"
7 #include "extensions/browser/api/serial/serial_connection.h"
8 #include "extensions/browser/event_router.h"
9 #include "extensions/browser/extensions_browser_client.h"
11 namespace extensions {
13 namespace core_api {
15 namespace {
17 bool ShouldPauseOnReceiveError(serial::ReceiveError error) {
18 return error == serial::RECEIVE_ERROR_DEVICE_LOST ||
19 error == serial::RECEIVE_ERROR_SYSTEM_ERROR ||
20 error == serial::RECEIVE_ERROR_DISCONNECTED;
23 } // namespace
25 static base::LazyInstance<BrowserContextKeyedAPIFactory<SerialEventDispatcher> >
26 g_factory = LAZY_INSTANCE_INITIALIZER;
28 // static
29 BrowserContextKeyedAPIFactory<SerialEventDispatcher>*
30 SerialEventDispatcher::GetFactoryInstance() {
31 return g_factory.Pointer();
34 // static
35 SerialEventDispatcher* SerialEventDispatcher::Get(
36 content::BrowserContext* context) {
37 return BrowserContextKeyedAPIFactory<SerialEventDispatcher>::Get(context);
40 SerialEventDispatcher::SerialEventDispatcher(content::BrowserContext* context)
41 : thread_id_(SerialConnection::kThreadId), context_(context) {
42 ApiResourceManager<SerialConnection>* manager =
43 ApiResourceManager<SerialConnection>::Get(context_);
44 DCHECK(manager) << "No serial connection manager.";
45 connections_ = manager->data_;
48 SerialEventDispatcher::~SerialEventDispatcher() {
51 SerialEventDispatcher::ReceiveParams::ReceiveParams() {
54 SerialEventDispatcher::ReceiveParams::~ReceiveParams() {
57 void SerialEventDispatcher::PollConnection(const std::string& extension_id,
58 int connection_id) {
59 DCHECK_CURRENTLY_ON(thread_id_);
61 ReceiveParams params;
62 params.thread_id = thread_id_;
63 params.browser_context_id = context_;
64 params.extension_id = extension_id;
65 params.connections = connections_;
66 params.connection_id = connection_id;
68 StartReceive(params);
71 // static
72 void SerialEventDispatcher::StartReceive(const ReceiveParams& params) {
73 DCHECK_CURRENTLY_ON(params.thread_id);
75 SerialConnection* connection =
76 params.connections->Get(params.extension_id, params.connection_id);
77 if (!connection)
78 return;
79 DCHECK(params.extension_id == connection->owner_extension_id());
81 if (connection->paused())
82 return;
84 connection->Receive(base::Bind(&ReceiveCallback, params));
87 // static
88 void SerialEventDispatcher::ReceiveCallback(const ReceiveParams& params,
89 const std::string& data,
90 serial::ReceiveError error) {
91 DCHECK_CURRENTLY_ON(params.thread_id);
93 // Note that an error (e.g. timeout) does not necessarily mean that no data
94 // was read, so we may fire an onReceive regardless of any error code.
95 if (data.length() > 0) {
96 serial::ReceiveInfo receive_info;
97 receive_info.connection_id = params.connection_id;
98 receive_info.data = data;
99 scoped_ptr<base::ListValue> args = serial::OnReceive::Create(receive_info);
100 scoped_ptr<extensions::Event> event(
101 new extensions::Event(serial::OnReceive::kEventName, args.Pass()));
102 PostEvent(params, event.Pass());
105 if (error != serial::RECEIVE_ERROR_NONE) {
106 serial::ReceiveErrorInfo error_info;
107 error_info.connection_id = params.connection_id;
108 error_info.error = error;
109 scoped_ptr<base::ListValue> args =
110 serial::OnReceiveError::Create(error_info);
111 scoped_ptr<extensions::Event> event(
112 new extensions::Event(serial::OnReceiveError::kEventName, args.Pass()));
113 PostEvent(params, event.Pass());
114 if (ShouldPauseOnReceiveError(error)) {
115 SerialConnection* connection =
116 params.connections->Get(params.extension_id, params.connection_id);
117 if (connection)
118 connection->set_paused(true);
122 // Queue up the next read operation.
123 BrowserThread::PostTask(
124 params.thread_id, FROM_HERE, base::Bind(&StartReceive, params));
127 // static
128 void SerialEventDispatcher::PostEvent(const ReceiveParams& params,
129 scoped_ptr<extensions::Event> event) {
130 DCHECK_CURRENTLY_ON(params.thread_id);
132 BrowserThread::PostTask(BrowserThread::UI,
133 FROM_HERE,
134 base::Bind(&DispatchEvent,
135 params.browser_context_id,
136 params.extension_id,
137 base::Passed(event.Pass())));
140 // static
141 void SerialEventDispatcher::DispatchEvent(void* browser_context_id,
142 const std::string& extension_id,
143 scoped_ptr<extensions::Event> event) {
144 DCHECK_CURRENTLY_ON(BrowserThread::UI);
146 content::BrowserContext* context =
147 reinterpret_cast<content::BrowserContext*>(browser_context_id);
148 if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context))
149 return;
151 EventRouter* router = EventRouter::Get(context);
152 if (router)
153 router->DispatchEventToExtension(extension_id, event.Pass());
156 } // namespace core_api
158 } // namespace extensions