OLD | NEW |
| (Empty) |
1 // Copyright 2015 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. | |
4 | |
5 #include "chrome/browser/chromeos/launcher_search_provider/service.h" | |
6 | |
7 #include "base/memory/scoped_vector.h" | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #include "chrome/browser/chromeos/launcher_search_provider/service_factory.h" | |
10 #include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_prov
ider.h" | |
11 #include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_resu
lt.h" | |
12 #include "extensions/browser/extension_registry.h" | |
13 #include "extensions/common/extension_set.h" | |
14 #include "extensions/common/permissions/permissions_data.h" | |
15 | |
16 namespace api_launcher_search_provider = | |
17 extensions::api::launcher_search_provider; | |
18 using extensions::ExtensionId; | |
19 using extensions::ExtensionSet; | |
20 | |
21 namespace chromeos { | |
22 namespace launcher_search_provider { | |
23 | |
24 Service::Service(Profile* profile, | |
25 extensions::ExtensionRegistry* extension_registry) | |
26 : profile_(profile), | |
27 extension_registry_(extension_registry), | |
28 provider_(nullptr), | |
29 query_id_(0), | |
30 is_query_running_(false) { | |
31 extension_registry_->AddObserver(this); | |
32 } | |
33 | |
34 Service::~Service() { | |
35 extension_registry_->RemoveObserver(this); | |
36 } | |
37 | |
38 // static | |
39 Service* Service::Get(content::BrowserContext* context) { | |
40 return ServiceFactory::Get(context); | |
41 } | |
42 | |
43 void Service::OnQueryStarted(app_list::LauncherSearchProvider* provider, | |
44 const std::string& query, | |
45 const int max_result) { | |
46 DCHECK(!is_query_running_); | |
47 is_query_running_ = true; | |
48 provider_ = provider; | |
49 | |
50 ++query_id_; | |
51 | |
52 extensions::EventRouter* event_router = | |
53 extensions::EventRouter::Get(profile_); | |
54 | |
55 CacheListenerExtensionIds(); | |
56 for (const ExtensionId extension_id : *cached_listener_extension_ids_.get()) { | |
57 // Convert query_id_ to string here since queryId is defined as string in | |
58 // javascript side API while we use uint32 internally to generate it. | |
59 event_router->DispatchEventToExtension( | |
60 extension_id, | |
61 make_scoped_ptr(new extensions::Event( | |
62 api_launcher_search_provider::OnQueryStarted::kEventName, | |
63 api_launcher_search_provider::OnQueryStarted::Create( | |
64 query_id_, query, max_result)))); | |
65 } | |
66 } | |
67 | |
68 void Service::OnQueryEnded() { | |
69 DCHECK(is_query_running_); | |
70 provider_ = nullptr; | |
71 | |
72 extensions::EventRouter* event_router = | |
73 extensions::EventRouter::Get(profile_); | |
74 | |
75 CacheListenerExtensionIds(); | |
76 for (const ExtensionId extension_id : *cached_listener_extension_ids_.get()) { | |
77 event_router->DispatchEventToExtension( | |
78 extension_id, | |
79 make_scoped_ptr(new extensions::Event( | |
80 api_launcher_search_provider::OnQueryEnded::kEventName, | |
81 api_launcher_search_provider::OnQueryEnded::Create(query_id_)))); | |
82 } | |
83 | |
84 is_query_running_ = false; | |
85 } | |
86 | |
87 void Service::OnOpenResult(const ExtensionId& extension_id, | |
88 const std::string& item_id) { | |
89 CacheListenerExtensionIds(); | |
90 CHECK(ContainsValue(*cached_listener_extension_ids_.get(), extension_id)); | |
91 | |
92 extensions::EventRouter* event_router = | |
93 extensions::EventRouter::Get(profile_); | |
94 event_router->DispatchEventToExtension( | |
95 extension_id, | |
96 make_scoped_ptr(new extensions::Event( | |
97 api_launcher_search_provider::OnOpenResult::kEventName, | |
98 api_launcher_search_provider::OnOpenResult::Create(item_id)))); | |
99 } | |
100 | |
101 void Service::SetSearchResults( | |
102 const extensions::Extension* extension, | |
103 scoped_ptr<ErrorReporter> error_reporter, | |
104 const int query_id, | |
105 const std::vector<linked_ptr< | |
106 extensions::api::launcher_search_provider::SearchResult>>& results) { | |
107 // If query is not running or query_id is different from current query id, | |
108 // discard the results. | |
109 if (!is_query_running_ || query_id != query_id_) | |
110 return; | |
111 | |
112 // If |extension| is not in the listener extensions list, ignore it. | |
113 CacheListenerExtensionIds(); | |
114 if (!ContainsValue(*cached_listener_extension_ids_.get(), extension->id())) | |
115 return; | |
116 | |
117 // Set search results to provider. | |
118 DCHECK(provider_); | |
119 ScopedVector<app_list::LauncherSearchResult> search_results; | |
120 for (const auto& result : results) { | |
121 const int relevance = | |
122 std::min(kMaxSearchResultScore, std::max(result->relevance, 0)); | |
123 const GURL icon_url = | |
124 result->icon_url ? GURL(*result->icon_url.get()) : GURL(); | |
125 | |
126 app_list::LauncherSearchResult* search_result = | |
127 new app_list::LauncherSearchResult(result->item_id, icon_url, relevance, | |
128 profile_, extension, | |
129 error_reporter->Duplicate()); | |
130 search_result->set_title(base::UTF8ToUTF16(result->title)); | |
131 search_results.push_back(search_result); | |
132 } | |
133 provider_->SetSearchResults(extension->id(), search_results.Pass()); | |
134 } | |
135 | |
136 bool Service::IsQueryRunning() const { | |
137 return is_query_running_; | |
138 } | |
139 | |
140 void Service::OnExtensionLoaded(content::BrowserContext* browser_context, | |
141 const extensions::Extension* extension) { | |
142 // Invalidate cache. | |
143 cached_listener_extension_ids_.reset(); | |
144 } | |
145 | |
146 void Service::OnExtensionUnloaded( | |
147 content::BrowserContext* browser_context, | |
148 const extensions::Extension* extension, | |
149 extensions::UnloadedExtensionInfo::Reason reason) { | |
150 // Invalidate cache. | |
151 cached_listener_extension_ids_.reset(); | |
152 } | |
153 | |
154 void Service::CacheListenerExtensionIds() { | |
155 // If it's already cached, do nothing. | |
156 if (cached_listener_extension_ids_) | |
157 return; | |
158 | |
159 cached_listener_extension_ids_.reset(new std::set<ExtensionId>()); | |
160 | |
161 const ExtensionSet& extension_set = extension_registry_->enabled_extensions(); | |
162 for (scoped_refptr<const extensions::Extension> extension : extension_set) { | |
163 const extensions::PermissionsData* permission_data = | |
164 extension->permissions_data(); | |
165 const bool has_permission = permission_data->HasAPIPermission( | |
166 extensions::APIPermission::kLauncherSearchProvider); | |
167 if (has_permission) | |
168 cached_listener_extension_ids_->insert(extension->id()); | |
169 } | |
170 } | |
171 | |
172 } // namespace launcher_search_provider | |
173 } // namespace chromeos | |
OLD | NEW |