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

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: Add unit test for MDnsAPI 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
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 "base/profiler/scoped_profile.h" 10 #include "base/profiler/scoped_profile.h"
11 #include "chrome/browser/extensions/extension_service.h" 11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/common/extensions/api/mdns.h" 12 #include "chrome/common/extensions/api/mdns.h"
13 #include "extensions/browser/extension_registry.h"
13 14
14 namespace extensions { 15 namespace extensions {
15 16
16 namespace mdns = api::mdns; 17 namespace mdns = api::mdns;
17 18
18 namespace { 19 namespace {
19 20
20 // Whitelisted mDNS service types. 21 // Whitelisted mDNS service types.
21 const char kCastServiceType[] = "_googlecast._tcp.local"; 22 const char kCastServiceType[] = "_googlecast._tcp.local";
22 const char kPrivetServiceType[] = "_privet._tcp.local"; 23 const char kPrivetServiceType[] = "_privet._tcp.local";
23 const char kTestServiceType[] = "_testing._tcp.local"; 24 const char kTestServiceType[] = "_testing._tcp.local";
24 25
25 bool IsServiceTypeWhitelisted(const std::string& service_type) { 26 bool IsServiceTypeWhitelisted(const std::string& service_type) {
26 return service_type == kCastServiceType || 27 return service_type == kCastServiceType ||
27 service_type == kPrivetServiceType || 28 service_type == kPrivetServiceType ||
28 service_type == kTestServiceType; 29 service_type == kTestServiceType;
29 } 30 }
30 31
31 } // namespace 32 } // namespace
32 33
33 MDnsAPI::MDnsAPI(content::BrowserContext* context) : browser_context_(context) { 34 MDnsAPI::MDnsAPI(content::BrowserContext* context) : browser_context_(context) {
34 DCHECK(browser_context_); 35 DCHECK(browser_context_);
35 EventRouter::Get(context) 36 extensions::EventRouter* event_router = EventRouter::Get(context);
36 ->RegisterObserver(this, mdns::OnServiceList::kEventName); 37 DCHECK(event_router);
38 event_router->RegisterObserver(this, mdns::OnServiceList::kEventName);
37 } 39 }
38 40
39 MDnsAPI::~MDnsAPI() { 41 MDnsAPI::~MDnsAPI() {
40 if (dns_sd_registry_.get()) { 42 if (dns_sd_registry_.get()) {
41 dns_sd_registry_->RemoveObserver(this); 43 dns_sd_registry_->RemoveObserver(this);
42 } 44 }
43 } 45 }
44 46
45 // static 47 // static
46 MDnsAPI* MDnsAPI::Get(content::BrowserContext* context) { 48 MDnsAPI* MDnsAPI::Get(content::BrowserContext* context) {
47 return BrowserContextKeyedAPIFactory<MDnsAPI>::Get(context); 49 return BrowserContextKeyedAPIFactory<MDnsAPI>::Get(context);
48 } 50 }
49 51
50 static base::LazyInstance<BrowserContextKeyedAPIFactory<MDnsAPI> > g_factory = 52 static base::LazyInstance<BrowserContextKeyedAPIFactory<MDnsAPI> > g_factory =
51 LAZY_INSTANCE_INITIALIZER; 53 LAZY_INSTANCE_INITIALIZER;
52 54
53 // static 55 // static
54 BrowserContextKeyedAPIFactory<MDnsAPI>* MDnsAPI::GetFactoryInstance() { 56 BrowserContextKeyedAPIFactory<MDnsAPI>* MDnsAPI::GetFactoryInstance() {
55 return g_factory.Pointer(); 57 return g_factory.Pointer();
56 } 58 }
57 59
58 void MDnsAPI::SetDnsSdRegistryForTesting( 60 void MDnsAPI::SetDnsSdRegistryForTesting(
59 scoped_ptr<DnsSdRegistry> dns_sd_registry) { 61 scoped_ptr<DnsSdRegistry> dns_sd_registry) {
60 dns_sd_registry_ = dns_sd_registry.Pass(); 62 dns_sd_registry_ = dns_sd_registry.Pass();
63 if (dns_sd_registry_.get())
64 dns_sd_registry_.get()->AddObserver(this);
61 } 65 }
62 66
63 DnsSdRegistry* MDnsAPI::dns_sd_registry() { 67 DnsSdRegistry* MDnsAPI::dns_sd_registry() {
64 DCHECK(thread_checker_.CalledOnValidThread()); 68 DCHECK(thread_checker_.CalledOnValidThread());
65 if (!dns_sd_registry_.get()) { 69 if (!dns_sd_registry_.get()) {
66 dns_sd_registry_.reset(new extensions::DnsSdRegistry()); 70 dns_sd_registry_.reset(new extensions::DnsSdRegistry());
67 dns_sd_registry_->AddObserver(this); 71 dns_sd_registry_->AddObserver(this);
68 } 72 }
69 return dns_sd_registry_.get(); 73 return dns_sd_registry_.get();
70 } 74 }
71 75
72 void MDnsAPI::OnListenerAdded(const EventListenerInfo& details) { 76 void MDnsAPI::OnListenerAdded(const EventListenerInfo& details) {
73 // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed. 77 // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
74 tracked_objects::ScopedProfile tracking_profile( 78 tracked_objects::ScopedProfile tracking_profile(
75 FROM_HERE_WITH_EXPLICIT_FUNCTION("MDnsAPI::OnListenerAdded")); 79 FROM_HERE_WITH_EXPLICIT_FUNCTION("MDnsAPI::OnListenerAdded"));
76 80
77 DCHECK(thread_checker_.CalledOnValidThread()); 81 DCHECK(thread_checker_.CalledOnValidThread());
78 UpdateMDnsListeners(details); 82 UpdateMDnsListeners(details);
79 } 83 }
80 84
81 void MDnsAPI::OnListenerRemoved(const EventListenerInfo& details) { 85 void MDnsAPI::OnListenerRemoved(const EventListenerInfo& details) {
82 DCHECK(thread_checker_.CalledOnValidThread()); 86 DCHECK(thread_checker_.CalledOnValidThread());
83 UpdateMDnsListeners(details); 87 UpdateMDnsListeners(details);
84 } 88 }
85 89
86 void MDnsAPI::UpdateMDnsListeners(const EventListenerInfo& details) { 90 void MDnsAPI::UpdateMDnsListeners(const EventListenerInfo& details) {
87 std::set<std::string> new_service_types; 91 std::set<std::string> new_service_types;
88 92
89 // Check all listeners for service type filers. 93 // Check all listeners for service type filters.
90 const EventListenerMap::ListenerList& listeners = 94 const EventListenerMap::ListenerList& listeners =
91 extensions::EventRouter::Get(browser_context_) 95 extensions::EventRouter::Get(browser_context_)
92 ->listeners() 96 ->listeners()
93 .GetEventListenersByName(details.event_name); 97 .GetEventListenersByName(details.event_name);
94 for (EventListenerMap::ListenerList::const_iterator it = listeners.begin(); 98 for (EventListenerMap::ListenerList::const_iterator it = listeners.begin();
95 it != listeners.end(); ++it) { 99 it != listeners.end(); ++it) {
96 base::DictionaryValue* filter = ((*it)->filter()); 100 base::DictionaryValue* filter = ((*it)->filter());
97 101
98 std::string filter_value; 102 std::string filter_value;
99 filter->GetStringASCII(kEventFilterServiceTypeKey, &filter_value); 103 filter->GetStringASCII(kEventFilterServiceTypeKey, &filter_value);
100 if (filter_value.empty()) 104 if (filter_value.empty())
101 continue; 105 continue;
106
107 const Extension* extension = ExtensionRegistry::Get(browser_context_)->
108 enabled_extensions().GetByID((*it)->extension_id());
109 // Don't listen for services associated only with disabled extensions.
110 if (!extension)
111 continue;
112
113 // Platform apps may query for all services; other types of extensions are
114 // restricted to a whitelist.
115 if (!extension->is_platform_app() &&
116 !IsServiceTypeWhitelisted(filter_value))
117 continue;
118
102 new_service_types.insert(filter_value); 119 new_service_types.insert(filter_value);
103 } 120 }
104 121
105 // Find all the added and removed service types since last update. 122 // Find all the added and removed service types since last update.
106 std::set<std::string> added_service_types = 123 std::set<std::string> added_service_types =
107 base::STLSetDifference<std::set<std::string> >( 124 base::STLSetDifference<std::set<std::string> >(
108 new_service_types, service_types_); 125 new_service_types, service_types_);
109 std::set<std::string> removed_service_types = 126 std::set<std::string> removed_service_types =
110 base::STLSetDifference<std::set<std::string> >( 127 base::STLSetDifference<std::set<std::string> >(
111 service_types_, new_service_types); 128 service_types_, new_service_types);
112 129
113 // Update the registry. 130 // Update the registry.
114 DnsSdRegistry* registry = dns_sd_registry(); 131 DnsSdRegistry* registry = dns_sd_registry();
115 for (std::set<std::string>::iterator it = added_service_types.begin(); 132 for (std::set<std::string>::iterator it = added_service_types.begin();
Vitaly Buka (NO REVIEWS) 2015/03/18 19:07:00 maybe: for (const auto& srv: added_service_types)
Red Daly 2015/03/27 20:06:08 Done.
116 it != added_service_types.end(); ++it) { 133 it != added_service_types.end(); ++it) {
117 if (IsServiceTypeWhitelisted(*it)) 134 registry->RegisterDnsSdListener(*it);
118 registry->RegisterDnsSdListener(*it);
119 } 135 }
120 for (std::set<std::string>::iterator it = removed_service_types.begin(); 136 for (std::set<std::string>::iterator it = removed_service_types.begin();
121 it != removed_service_types.end(); ++it) { 137 it != removed_service_types.end(); ++it) {
122 if (IsServiceTypeWhitelisted(*it)) 138 registry->UnregisterDnsSdListener(*it);
123 registry->UnregisterDnsSdListener(*it);
124 } 139 }
125
126 service_types_ = new_service_types; 140 service_types_ = new_service_types;
127 } 141 }
128 142
129 void MDnsAPI::OnDnsSdEvent(const std::string& service_type, 143 void MDnsAPI::OnDnsSdEvent(const std::string& service_type,
130 const DnsSdRegistry::DnsSdServiceList& services) { 144 const DnsSdRegistry::DnsSdServiceList& services) {
131 DCHECK(thread_checker_.CalledOnValidThread()); 145 DCHECK(thread_checker_.CalledOnValidThread());
132 146
133 std::vector<linked_ptr<mdns::MDnsService> > args; 147 std::vector<linked_ptr<mdns::MDnsService> > args;
134 for (DnsSdRegistry::DnsSdServiceList::const_iterator it = services.begin(); 148 for (DnsSdRegistry::DnsSdServiceList::const_iterator it = services.begin();
135 it != services.end(); ++it) { 149 it != services.end(); ++it) {
136 linked_ptr<mdns::MDnsService> mdns_service = 150 linked_ptr<mdns::MDnsService> mdns_service =
137 make_linked_ptr(new mdns::MDnsService); 151 make_linked_ptr(new mdns::MDnsService);
138 mdns_service->service_name = (*it).service_name; 152 mdns_service->service_name = (*it).service_name;
139 mdns_service->service_host_port = (*it).service_host_port; 153 mdns_service->service_host_port = (*it).service_host_port;
140 mdns_service->ip_address = (*it).ip_address; 154 mdns_service->ip_address = (*it).ip_address;
141 mdns_service->service_data = (*it).service_data; 155 mdns_service->service_data = (*it).service_data;
142 args.push_back(mdns_service); 156 args.push_back(mdns_service);
143 } 157 }
144 158
145 scoped_ptr<base::ListValue> results = mdns::OnServiceList::Create(args); 159 scoped_ptr<base::ListValue> results = mdns::OnServiceList::Create(args);
146 scoped_ptr<Event> event( 160 scoped_ptr<Event> event(
147 new Event(mdns::OnServiceList::kEventName, results.Pass())); 161 new Event(mdns::OnServiceList::kEventName, results.Pass()));
148 event->restrict_to_browser_context = browser_context_; 162 event->restrict_to_browser_context = browser_context_;
149 event->filter_info.SetServiceType(service_type); 163 event->filter_info.SetServiceType(service_type);
150 164
151 VLOG(1) << "Broadcasting OnServiceList event: " << event.get();
152
153 // TODO(justinlin): To avoid having listeners without filters getting all 165 // TODO(justinlin): To avoid having listeners without filters getting all
154 // events, modify API to have this event require filters. 166 // events, modify API to have this event require filters.
167 // TODO(reddaly): If event isn't on whitelist, ensure it does not get
168 // broadcast to extensions.
155 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); 169 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
156 } 170 }
157 171
158 } // namespace extensions 172 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698