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