Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / dial / dial_api.cc
blobcc9f1c61a6087855e45d05df14747e54ed07793d
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.
5 #include "chrome/browser/extensions/api/dial/dial_api.h"
7 #include <vector>
9 #include "base/time/time.h"
10 #include "chrome/browser/extensions/api/dial/dial_api_factory.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/common/extensions/api/dial.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "extensions/browser/event_router.h"
15 #include "extensions/browser/extension_system.h"
17 using base::TimeDelta;
18 using content::BrowserThread;
20 namespace {
22 // How often to poll for devices.
23 const int kDialRefreshIntervalSecs = 120;
25 // We prune a device if it does not respond after this time.
26 const int kDialExpirationSecs = 240;
28 // The maximum number of devices retained at once in the registry.
29 const size_t kDialMaxDevices = 256;
31 } // namespace
33 namespace extensions {
35 namespace dial = api::dial;
37 DialAPI::DialAPI(Profile* profile)
38 : RefcountedKeyedService(
39 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)),
40 profile_(profile) {
41 EventRouter::Get(profile)
42 ->RegisterObserver(this, dial::OnDeviceList::kEventName);
45 DialAPI::~DialAPI() {}
47 DialRegistry* DialAPI::dial_registry() {
48 DCHECK_CURRENTLY_ON(BrowserThread::IO);
49 if (!dial_registry_.get()) {
50 dial_registry_.reset(new DialRegistry(this,
51 TimeDelta::FromSeconds(kDialRefreshIntervalSecs),
52 TimeDelta::FromSeconds(kDialExpirationSecs),
53 kDialMaxDevices));
55 return dial_registry_.get();
58 void DialAPI::OnListenerAdded(const EventListenerInfo& details) {
59 DCHECK_CURRENTLY_ON(BrowserThread::UI);
60 BrowserThread::PostTask(
61 BrowserThread::IO, FROM_HERE,
62 base::Bind(&DialAPI::NotifyListenerAddedOnIOThread, this));
65 void DialAPI::OnListenerRemoved(const EventListenerInfo& details) {
66 DCHECK_CURRENTLY_ON(BrowserThread::UI);
67 BrowserThread::PostTask(
68 BrowserThread::IO, FROM_HERE,
69 base::Bind(&DialAPI::NotifyListenerRemovedOnIOThread, this));
72 void DialAPI::NotifyListenerAddedOnIOThread() {
73 DCHECK_CURRENTLY_ON(BrowserThread::IO);
74 VLOG(2) << "DIAL device event listener added.";
75 dial_registry()->OnListenerAdded();
78 void DialAPI::NotifyListenerRemovedOnIOThread() {
79 DCHECK_CURRENTLY_ON(BrowserThread::IO);
80 VLOG(2) << "DIAL device event listener removed";
81 dial_registry()->OnListenerRemoved();
84 void DialAPI::OnDialDeviceEvent(const DialRegistry::DeviceList& devices) {
85 DCHECK_CURRENTLY_ON(BrowserThread::IO);
86 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
87 base::Bind(&DialAPI::SendEventOnUIThread, this, devices));
90 void DialAPI::OnDialError(const DialRegistry::DialErrorCode code) {
91 DCHECK_CURRENTLY_ON(BrowserThread::IO);
92 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
93 base::Bind(&DialAPI::SendErrorOnUIThread, this, code));
96 void DialAPI::SendEventOnUIThread(const DialRegistry::DeviceList& devices) {
97 DCHECK_CURRENTLY_ON(BrowserThread::UI);
99 std::vector<linked_ptr<api::dial::DialDevice> > args;
100 for (DialRegistry::DeviceList::const_iterator it = devices.begin();
101 it != devices.end(); ++it) {
102 linked_ptr<api::dial::DialDevice> api_device =
103 make_linked_ptr(new api::dial::DialDevice);
104 it->FillDialDevice(api_device.get());
105 args.push_back(api_device);
107 scoped_ptr<base::ListValue> results = api::dial::OnDeviceList::Create(args);
108 scoped_ptr<Event> event(new Event(events::DIAL_ON_DEVICE_LIST,
109 dial::OnDeviceList::kEventName,
110 results.Pass()));
111 EventRouter::Get(profile_)->BroadcastEvent(event.Pass());
114 void DialAPI::SendErrorOnUIThread(const DialRegistry::DialErrorCode code) {
115 DCHECK_CURRENTLY_ON(BrowserThread::UI);
117 api::dial::DialError dial_error;
118 switch (code) {
119 case DialRegistry::DIAL_NO_LISTENERS:
120 dial_error.code = api::dial::DIAL_ERROR_CODE_NO_LISTENERS;
121 break;
122 case DialRegistry::DIAL_NO_INTERFACES:
123 dial_error.code = api::dial::DIAL_ERROR_CODE_NO_VALID_NETWORK_INTERFACES;
124 break;
125 case DialRegistry::DIAL_CELLULAR_NETWORK:
126 dial_error.code = api::dial::DIAL_ERROR_CODE_CELLULAR_NETWORK;
127 break;
128 case DialRegistry::DIAL_NETWORK_DISCONNECTED:
129 dial_error.code = api::dial::DIAL_ERROR_CODE_NETWORK_DISCONNECTED;
130 break;
131 case DialRegistry::DIAL_SOCKET_ERROR:
132 dial_error.code = api::dial::DIAL_ERROR_CODE_SOCKET_ERROR;
133 break;
134 default:
135 dial_error.code = api::dial::DIAL_ERROR_CODE_UNKNOWN;
136 break;
139 scoped_ptr<base::ListValue> results = api::dial::OnError::Create(dial_error);
140 scoped_ptr<Event> event(new Event(events::DIAL_ON_ERROR,
141 dial::OnError::kEventName, results.Pass()));
142 EventRouter::Get(profile_)->BroadcastEvent(event.Pass());
145 void DialAPI::ShutdownOnUIThread() {}
147 namespace api {
149 DialDiscoverNowFunction::DialDiscoverNowFunction()
150 : dial_(NULL), result_(false) {
153 bool DialDiscoverNowFunction::Prepare() {
154 DCHECK_CURRENTLY_ON(BrowserThread::UI);
155 DCHECK(browser_context());
156 dial_ = DialAPIFactory::GetForBrowserContext(browser_context()).get();
157 return true;
160 void DialDiscoverNowFunction::Work() {
161 DCHECK_CURRENTLY_ON(BrowserThread::IO);
162 result_ = dial_->dial_registry()->DiscoverNow();
165 bool DialDiscoverNowFunction::Respond() {
166 DCHECK_CURRENTLY_ON(BrowserThread::UI);
167 SetResult(new base::FundamentalValue(result_));
168 return true;
171 } // namespace api
173 } // namespace extensions