190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/app_search_provider.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <string> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_ui_util.h" 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/extensions/extension_util.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/app_result.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_prefs.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/app_list/search/tokenized_string.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/app_list/search/tokenized_string_match.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionRegistry; 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace app_list { 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class AppSearchProvider::App { 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) explicit App(const extensions::Extension* extension, 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Time& last_launch_time) 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : app_id_(extension->id()), 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) indexed_name_(base::UTF8ToUTF16(extension->name())), 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_launch_time_(last_launch_time) {} 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ~App() {} 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& app_id() const { return app_id_; } 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const TokenizedString& indexed_name() const { return indexed_name_; } 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Time& last_launch_time() const { return last_launch_time_; } 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string app_id_; 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TokenizedString indexed_name_; 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Time last_launch_time_; 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(App); 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)AppSearchProvider::AppSearchProvider(Profile* profile, 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AppListControllerDelegate* list_controller) 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : profile_(profile), 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) list_controller_(list_controller), 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extension_registry_observer_(this) { 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RefreshApps(); 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)AppSearchProvider::~AppSearchProvider() {} 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AppSearchProvider::Start(const base::string16& query) { 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) StartImpl(base::Time::Now(), query); 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppSearchProvider::Stop() { 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppSearchProvider::StartImpl(const base::Time& current_time, 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::string16& query) { 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const TokenizedString query_terms(query); 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ClearResults(); 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool show_recommendations = query.empty(); 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Refresh list of apps to ensure we have the latest launch time information. 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (show_recommendations) 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RefreshApps(); 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (Apps::const_iterator app_it = apps_.begin(); 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) app_it != apps_.end(); 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++app_it) { 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<AppResult> result( 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new AppResult(profile_, (*app_it)->app_id(), list_controller_)); 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (show_recommendations) { 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result->set_title((*app_it)->indexed_name().text()); 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result->UpdateFromLastLaunched(current_time, 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (*app_it)->last_launch_time()); 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TokenizedStringMatch match; 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!match.Calculate(query_terms, (*app_it)->indexed_name())) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result->UpdateFromMatch((*app_it)->indexed_name(), match); 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Add(result.PassAs<SearchResult>()); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppSearchProvider::AddApps(const extensions::ExtensionSet& extensions) { 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_); 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (extensions::ExtensionSet::const_iterator iter = extensions.begin(); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter != extensions.end(); ++iter) { 1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const extensions::Extension* app = iter->get(); 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!extensions::ui_util::ShouldDisplayInAppLauncher(app, profile_)) 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (profile_->IsOffTheRecord() && 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !extensions::util::CanLoadInIncognito(app, profile_)) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) apps_.push_back(new App(app, prefs->GetLastLaunchTime(app->id()))); 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void AppSearchProvider::RefreshApps() { 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) apps_.clear(); 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddApps(registry->enabled_extensions()); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddApps(registry->disabled_extensions()); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddApps(registry->terminated_extensions()); 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppSearchProvider::OnExtensionLoaded( 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) content::BrowserContext* browser_context, 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const extensions::Extension* extension) { 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) RefreshApps(); 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AppSearchProvider::OnExtensionUninstalled( 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) content::BrowserContext* browser_context, 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const extensions::Extension* extension, 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::UninstallReason reason) { 132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) RefreshApps(); 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace app_list 136