Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: chrome/browser/extensions/api/mdns/mdns_api.cc

Issue 668983003: Enable chrome.mdns for Chrome Apps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Squash all changes into a single git commit Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/extensions/api/mdns/mdns_api_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/mdns/mdns_api.h" 5 #include "chrome/browser/extensions/api/mdns/mdns_api.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "chrome/browser/extensions/extension_service.h" 10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/common/extensions/api/mdns.h" 11 #include "chrome/common/extensions/api/mdns.h"
12 #include "extensions/browser/extension_registry.h"
12 13
13 namespace extensions { 14 namespace extensions {
14 15
15 namespace mdns = api::mdns; 16 namespace mdns = api::mdns;
16 17
17 namespace { 18 namespace {
18 19
19 // Whitelisted mDNS service types. 20 // Whitelisted mDNS service types.
20 const char kCastServiceType[] = "_googlecast._tcp.local"; 21 const char kCastServiceType[] = "_googlecast._tcp.local";
21 const char kPrivetServiceType[] = "_privet._tcp.local"; 22 const char kPrivetServiceType[] = "_privet._tcp.local";
22 const char kTestServiceType[] = "_testing._tcp.local"; 23 const char kTestServiceType[] = "_testing._tcp.local";
23 24
24 bool IsServiceTypeWhitelisted(const std::string& service_type) { 25 bool IsServiceTypeWhitelisted(const std::string& service_type) {
25 return service_type == kCastServiceType || 26 return service_type == kCastServiceType ||
26 service_type == kPrivetServiceType || 27 service_type == kPrivetServiceType ||
27 service_type == kTestServiceType; 28 service_type == kTestServiceType;
28 } 29 }
29 30
30 } // namespace 31 } // namespace
31 32
32 MDnsAPI::MDnsAPI(content::BrowserContext* context) : browser_context_(context) { 33 MDnsAPI::MDnsAPI(content::BrowserContext* context) : browser_context_(context) {
33 DCHECK(browser_context_); 34 DCHECK(browser_context_);
34 EventRouter::Get(context) 35 extensions::EventRouter* event_router = EventRouter::Get(context);
35 ->RegisterObserver(this, mdns::OnServiceList::kEventName); 36 DCHECK(event_router);
37 event_router->RegisterObserver(this, mdns::OnServiceList::kEventName);
36 } 38 }
37 39
38 MDnsAPI::~MDnsAPI() { 40 MDnsAPI::~MDnsAPI() {
39 if (dns_sd_registry_.get()) { 41 if (dns_sd_registry_.get()) {
40 dns_sd_registry_->RemoveObserver(this); 42 dns_sd_registry_->RemoveObserver(this);
41 } 43 }
42 } 44 }
43 45
44 // static 46 // static
45 MDnsAPI* MDnsAPI::Get(content::BrowserContext* context) { 47 MDnsAPI* MDnsAPI::Get(content::BrowserContext* context) {
46 return BrowserContextKeyedAPIFactory<MDnsAPI>::Get(context); 48 return BrowserContextKeyedAPIFactory<MDnsAPI>::Get(context);
47 } 49 }
48 50
49 static base::LazyInstance<BrowserContextKeyedAPIFactory<MDnsAPI> > g_factory = 51 static base::LazyInstance<BrowserContextKeyedAPIFactory<MDnsAPI> > g_factory =
50 LAZY_INSTANCE_INITIALIZER; 52 LAZY_INSTANCE_INITIALIZER;
51 53
52 // static 54 // static
53 BrowserContextKeyedAPIFactory<MDnsAPI>* MDnsAPI::GetFactoryInstance() { 55 BrowserContextKeyedAPIFactory<MDnsAPI>* MDnsAPI::GetFactoryInstance() {
54 return g_factory.Pointer(); 56 return g_factory.Pointer();
55 } 57 }
56 58
57 void MDnsAPI::SetDnsSdRegistryForTesting( 59 void MDnsAPI::SetDnsSdRegistryForTesting(
58 scoped_ptr<DnsSdRegistry> dns_sd_registry) { 60 scoped_ptr<DnsSdRegistry> dns_sd_registry) {
59 dns_sd_registry_ = dns_sd_registry.Pass(); 61 dns_sd_registry_ = dns_sd_registry.Pass();
62 if (dns_sd_registry_.get())
63 dns_sd_registry_.get()->AddObserver(this);
60 } 64 }
61 65
62 DnsSdRegistry* MDnsAPI::dns_sd_registry() { 66 DnsSdRegistry* MDnsAPI::dns_sd_registry() {
63 DCHECK(thread_checker_.CalledOnValidThread()); 67 DCHECK(thread_checker_.CalledOnValidThread());
64 if (!dns_sd_registry_.get()) { 68 if (!dns_sd_registry_.get()) {
65 dns_sd_registry_.reset(new extensions::DnsSdRegistry()); 69 dns_sd_registry_.reset(new extensions::DnsSdRegistry());
66 dns_sd_registry_->AddObserver(this); 70 dns_sd_registry_->AddObserver(this);
67 } 71 }
68 return dns_sd_registry_.get(); 72 return dns_sd_registry_.get();
69 } 73 }
70 74
71 void MDnsAPI::OnListenerAdded(const EventListenerInfo& details) { 75 void MDnsAPI::OnListenerAdded(const EventListenerInfo& details) {
72 DCHECK(thread_checker_.CalledOnValidThread()); 76 DCHECK(thread_checker_.CalledOnValidThread());
73 UpdateMDnsListeners(details); 77 UpdateMDnsListeners(details);
74 } 78 }
75 79
76 void MDnsAPI::OnListenerRemoved(const EventListenerInfo& details) { 80 void MDnsAPI::OnListenerRemoved(const EventListenerInfo& details) {
77 DCHECK(thread_checker_.CalledOnValidThread()); 81 DCHECK(thread_checker_.CalledOnValidThread());
78 UpdateMDnsListeners(details); 82 UpdateMDnsListeners(details);
79 } 83 }
80 84
81 void MDnsAPI::UpdateMDnsListeners(const EventListenerInfo& details) { 85 void MDnsAPI::UpdateMDnsListeners(const EventListenerInfo& details) {
82 std::set<std::string> new_service_types; 86 std::set<std::string> new_service_types;
83 87
84 // Check all listeners for service type filers. 88 // Check all listeners for service type filters.
85 const EventListenerMap::ListenerList& listeners = 89 const EventListenerMap::ListenerList& listeners =
86 extensions::EventRouter::Get(browser_context_) 90 extensions::EventRouter::Get(browser_context_)
87 ->listeners() 91 ->listeners()
88 .GetEventListenersByName(details.event_name); 92 .GetEventListenersByName(details.event_name);
89 for (EventListenerMap::ListenerList::const_iterator it = listeners.begin(); 93 for (EventListenerMap::ListenerList::const_iterator it = listeners.begin();
90 it != listeners.end(); ++it) { 94 it != listeners.end(); ++it) {
91 base::DictionaryValue* filter = ((*it)->filter()); 95 base::DictionaryValue* filter = ((*it)->filter());
92 96
93 std::string filter_value; 97 std::string filter_value;
94 filter->GetStringASCII(kEventFilterServiceTypeKey, &filter_value); 98 filter->GetStringASCII(kEventFilterServiceTypeKey, &filter_value);
95 if (filter_value.empty()) 99 if (filter_value.empty())
96 continue; 100 continue;
101
102 const Extension* extension = ExtensionRegistry::Get(browser_context_)->
103 enabled_extensions().GetByID((*it)->extension_id());
104 // Don't listen for services associated only with disabled extensions.
105 if (!extension)
106 continue;
107
108 // Platform apps may query for all services; other types of extensions are
109 // restricted to a whitelist.
110 if (!extension->is_platform_app() &&
111 !IsServiceTypeWhitelisted(filter_value))
112 continue;
113
97 new_service_types.insert(filter_value); 114 new_service_types.insert(filter_value);
98 } 115 }
99 116
100 // Find all the added and removed service types since last update. 117 // Find all the added and removed service types since last update.
101 std::set<std::string> added_service_types = 118 std::set<std::string> added_service_types =
102 base::STLSetDifference<std::set<std::string> >( 119 base::STLSetDifference<std::set<std::string> >(
103 new_service_types, service_types_); 120 new_service_types, service_types_);
104 std::set<std::string> removed_service_types = 121 std::set<std::string> removed_service_types =
105 base::STLSetDifference<std::set<std::string> >( 122 base::STLSetDifference<std::set<std::string> >(
106 service_types_, new_service_types); 123 service_types_, new_service_types);
107 124
108 // Update the registry. 125 // Update the registry.
109 DnsSdRegistry* registry = dns_sd_registry(); 126 DnsSdRegistry* registry = dns_sd_registry();
110 for (std::set<std::string>::iterator it = added_service_types.begin(); 127 for (const auto& srv : added_service_types) {
111 it != added_service_types.end(); ++it) { 128 registry->RegisterDnsSdListener(srv);
112 if (IsServiceTypeWhitelisted(*it))
113 registry->RegisterDnsSdListener(*it);
114 } 129 }
115 for (std::set<std::string>::iterator it = removed_service_types.begin(); 130 for (const auto& srv : removed_service_types) {
116 it != removed_service_types.end(); ++it) { 131 registry->UnregisterDnsSdListener(srv);
117 if (IsServiceTypeWhitelisted(*it))
118 registry->UnregisterDnsSdListener(*it);
119 } 132 }
120
121 service_types_ = new_service_types; 133 service_types_ = new_service_types;
122 } 134 }
123 135
124 void MDnsAPI::OnDnsSdEvent(const std::string& service_type, 136 void MDnsAPI::OnDnsSdEvent(const std::string& service_type,
125 const DnsSdRegistry::DnsSdServiceList& services) { 137 const DnsSdRegistry::DnsSdServiceList& services) {
126 DCHECK(thread_checker_.CalledOnValidThread()); 138 DCHECK(thread_checker_.CalledOnValidThread());
127 139
128 std::vector<linked_ptr<mdns::MDnsService> > args; 140 std::vector<linked_ptr<mdns::MDnsService> > args;
129 for (DnsSdRegistry::DnsSdServiceList::const_iterator it = services.begin(); 141 for (DnsSdRegistry::DnsSdServiceList::const_iterator it = services.begin();
130 it != services.end(); ++it) { 142 it != services.end(); ++it) {
131 linked_ptr<mdns::MDnsService> mdns_service = 143 linked_ptr<mdns::MDnsService> mdns_service =
132 make_linked_ptr(new mdns::MDnsService); 144 make_linked_ptr(new mdns::MDnsService);
133 mdns_service->service_name = (*it).service_name; 145 mdns_service->service_name = (*it).service_name;
134 mdns_service->service_host_port = (*it).service_host_port; 146 mdns_service->service_host_port = (*it).service_host_port;
135 mdns_service->ip_address = (*it).ip_address; 147 mdns_service->ip_address = (*it).ip_address;
136 mdns_service->service_data = (*it).service_data; 148 mdns_service->service_data = (*it).service_data;
137 args.push_back(mdns_service); 149 args.push_back(mdns_service);
138 } 150 }
139 151
140 scoped_ptr<base::ListValue> results = mdns::OnServiceList::Create(args); 152 scoped_ptr<base::ListValue> results = mdns::OnServiceList::Create(args);
141 scoped_ptr<Event> event( 153 scoped_ptr<Event> event(
142 new Event(mdns::OnServiceList::kEventName, results.Pass())); 154 new Event(mdns::OnServiceList::kEventName, results.Pass()));
143 event->restrict_to_browser_context = browser_context_; 155 event->restrict_to_browser_context = browser_context_;
144 event->filter_info.SetServiceType(service_type); 156 event->filter_info.SetServiceType(service_type);
145 157
146 VLOG(1) << "Broadcasting OnServiceList event: " << event.get();
147
148 // TODO(justinlin): To avoid having listeners without filters getting all 158 // TODO(justinlin): To avoid having listeners without filters getting all
149 // events, modify API to have this event require filters. 159 // events, modify API to have this event require filters.
160 // TODO(reddaly): If event isn't on whitelist, ensure it does not get
161 // broadcast to extensions.
150 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); 162 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
151 } 163 }
152 164
153 } // namespace extensions 165 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/extensions/api/mdns/mdns_api_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698