app_search_provider.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/app_list/search/app_search_provider.h"
6
7#include <string>
8
9#include "base/strings/utf_string_conversions.h"
10#include "chrome/browser/chrome_notification_types.h"
11#include "chrome/browser/extensions/extension_service.h"
12#include "chrome/browser/extensions/extension_system_factory.h"
13#include "chrome/browser/extensions/extension_util.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/ui/app_list/search/app_result.h"
16#include "chrome/browser/ui/app_list/search/tokenized_string.h"
17#include "chrome/browser/ui/app_list/search/tokenized_string_match.h"
18#include "content/public/browser/notification_details.h"
19#include "content/public/browser/notification_source.h"
20
21namespace app_list {
22
23class AppSearchProvider::App {
24 public:
25  explicit App(const extensions::Extension* extension)
26      : app_id_(extension->id()),
27        indexed_name_(UTF8ToUTF16(extension->name())) {
28  }
29  ~App() {}
30
31  const std::string& app_id() const { return app_id_; }
32  const TokenizedString& indexed_name() const { return indexed_name_; }
33
34 private:
35  const std::string app_id_;
36  TokenizedString indexed_name_;
37
38  DISALLOW_COPY_AND_ASSIGN(App);
39};
40
41AppSearchProvider::AppSearchProvider(
42    Profile* profile,
43    AppListControllerDelegate* list_controller)
44    : profile_(profile),
45      list_controller_(list_controller) {
46  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
47                 content::Source<Profile>(profile_->GetOriginalProfile()));
48  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
49                 content::Source<Profile>(profile_->GetOriginalProfile()));
50  RefreshApps();
51}
52
53AppSearchProvider::~AppSearchProvider() {}
54
55void AppSearchProvider::Start(const string16& query) {
56  const TokenizedString query_terms(query);
57
58  ClearResults();
59
60  TokenizedStringMatch match;
61  for (Apps::const_iterator app_it = apps_.begin();
62       app_it != apps_.end();
63       ++app_it) {
64    if (!match.Calculate(query_terms, (*app_it)->indexed_name()))
65      continue;
66
67    scoped_ptr<AppResult> result(
68        new AppResult(profile_, (*app_it)->app_id(), list_controller_));
69    result->UpdateFromMatch((*app_it)->indexed_name(), match);
70    Add(result.PassAs<ChromeSearchResult>());
71  }
72}
73
74void AppSearchProvider::Stop() {}
75
76void AppSearchProvider::AddApps(const ExtensionSet* extensions,
77                                ExtensionService* service) {
78  for (ExtensionSet::const_iterator iter = extensions->begin();
79       iter != extensions->end(); ++iter) {
80    const extensions::Extension* app = iter->get();
81
82    if (!app->ShouldDisplayInAppLauncher())
83      continue;
84
85    if (profile_->IsOffTheRecord() &&
86        !extension_util::CanLoadInIncognito(app, service))
87      continue;
88    apps_.push_back(new App(app));
89  }
90}
91
92void AppSearchProvider::RefreshApps() {
93  ExtensionService* extension_service =
94      extensions::ExtensionSystemFactory::GetForProfile(profile_)->
95      extension_service();
96  if (!extension_service)
97    return;  // During testing, there is no extension service.
98
99  apps_.clear();
100
101  AddApps(extension_service->extensions(), extension_service);
102  AddApps(extension_service->disabled_extensions(), extension_service);
103  AddApps(extension_service->terminated_extensions(), extension_service);
104}
105
106void AppSearchProvider::Observe(int type,
107                                const content::NotificationSource& source,
108                                const content::NotificationDetails& detaila) {
109  RefreshApps();
110}
111
112}  // namespace app_list
113