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