| 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 extensions::events::LAUNCHER_SEARCH_PROVIDER_ON_QUERY_STARTED, | |
| 63 api_launcher_search_provider::OnQueryStarted::kEventName, | |
| 64 api_launcher_search_provider::OnQueryStarted::Create( | |
| 65 query_id_, query, max_result)))); | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 void Service::OnQueryEnded() { | |
| 70 DCHECK(is_query_running_); | |
| 71 provider_ = nullptr; | |
| 72 | |
| 73 extensions::EventRouter* event_router = | |
| 74 extensions::EventRouter::Get(profile_); | |
| 75 | |
| 76 CacheListenerExtensionIds(); | |
| 77 for (const ExtensionId extension_id : *cached_listener_extension_ids_.get()) { | |
| 78 event_router->DispatchEventToExtension( | |
| 79 extension_id, | |
| 80 make_scoped_ptr(new extensions::Event( | |
| 81 extensions::events::LAUNCHER_SEARCH_PROVIDER_ON_QUERY_ENDED, | |
| 82 api_launcher_search_provider::OnQueryEnded::kEventName, | |
| 83 api_launcher_search_provider::OnQueryEnded::Create(query_id_)))); | |
| 84 } | |
| 85 | |
| 86 is_query_running_ = false; | |
| 87 } | |
| 88 | |
| 89 void Service::OnOpenResult(const ExtensionId& extension_id, | |
| 90 const std::string& item_id) { | |
| 91 CacheListenerExtensionIds(); | |
| 92 CHECK(ContainsValue(*cached_listener_extension_ids_.get(), extension_id)); | |
| 93 | |
| 94 extensions::EventRouter* event_router = | |
| 95 extensions::EventRouter::Get(profile_); | |
| 96 event_router->DispatchEventToExtension( | |
| 97 extension_id, | |
| 98 make_scoped_ptr(new extensions::Event( | |
| 99 extensions::events::LAUNCHER_SEARCH_PROVIDER_ON_OPEN_RESULT, | |
| 100 api_launcher_search_provider::OnOpenResult::kEventName, | |
| 101 api_launcher_search_provider::OnOpenResult::Create(item_id)))); | |
| 102 } | |
| 103 | |
| 104 void Service::SetSearchResults( | |
| 105 const extensions::Extension* extension, | |
| 106 scoped_ptr<ErrorReporter> error_reporter, | |
| 107 const int query_id, | |
| 108 const std::vector<linked_ptr< | |
| 109 extensions::api::launcher_search_provider::SearchResult>>& results) { | |
| 110 // If query is not running or query_id is different from current query id, | |
| 111 // discard the results. | |
| 112 if (!is_query_running_ || query_id != query_id_) | |
| 113 return; | |
| 114 | |
| 115 // If |extension| is not in the listener extensions list, ignore it. | |
| 116 CacheListenerExtensionIds(); | |
| 117 if (!ContainsValue(*cached_listener_extension_ids_.get(), extension->id())) | |
| 118 return; | |
| 119 | |
| 120 // Set search results to provider. | |
| 121 DCHECK(provider_); | |
| 122 ScopedVector<app_list::LauncherSearchResult> search_results; | |
| 123 for (const auto& result : results) { | |
| 124 const int relevance = | |
| 125 std::min(kMaxSearchResultScore, std::max(result->relevance, 0)); | |
| 126 const GURL icon_url = | |
| 127 result->icon_url ? GURL(*result->icon_url.get()) : GURL(); | |
| 128 | |
| 129 app_list::LauncherSearchResult* search_result = | |
| 130 new app_list::LauncherSearchResult(result->item_id, icon_url, relevance, | |
| 131 profile_, extension, | |
| 132 error_reporter->Duplicate()); | |
| 133 search_result->set_title(base::UTF8ToUTF16(result->title)); | |
| 134 search_results.push_back(search_result); | |
| 135 } | |
| 136 provider_->SetSearchResults(extension->id(), search_results.Pass()); | |
| 137 } | |
| 138 | |
| 139 bool Service::IsQueryRunning() const { | |
| 140 return is_query_running_; | |
| 141 } | |
| 142 | |
| 143 void Service::OnExtensionLoaded(content::BrowserContext* browser_context, | |
| 144 const extensions::Extension* extension) { | |
| 145 // Invalidate cache. | |
| 146 cached_listener_extension_ids_.reset(); | |
| 147 } | |
| 148 | |
| 149 void Service::OnExtensionUnloaded( | |
| 150 content::BrowserContext* browser_context, | |
| 151 const extensions::Extension* extension, | |
| 152 extensions::UnloadedExtensionInfo::Reason reason) { | |
| 153 // Invalidate cache. | |
| 154 cached_listener_extension_ids_.reset(); | |
| 155 } | |
| 156 | |
| 157 void Service::CacheListenerExtensionIds() { | |
| 158 // If it's already cached, do nothing. | |
| 159 if (cached_listener_extension_ids_) | |
| 160 return; | |
| 161 | |
| 162 cached_listener_extension_ids_.reset(new std::set<ExtensionId>()); | |
| 163 | |
| 164 const ExtensionSet& extension_set = extension_registry_->enabled_extensions(); | |
| 165 for (scoped_refptr<const extensions::Extension> extension : extension_set) { | |
| 166 const extensions::PermissionsData* permission_data = | |
| 167 extension->permissions_data(); | |
| 168 const bool has_permission = permission_data->HasAPIPermission( | |
| 169 extensions::APIPermission::kLauncherSearchProvider); | |
| 170 if (has_permission) | |
| 171 cached_listener_extension_ids_->insert(extension->id()); | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 } // namespace launcher_search_provider | |
| 176 } // namespace chromeos | |
| OLD | NEW |