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