- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / app_list / search / app_result.cc
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_result.h"
6
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/extensions/extension_system_factory.h"
9 #include "chrome/browser/extensions/install_tracker.h"
10 #include "chrome/browser/extensions/install_tracker_factory.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/app_list/app_context_menu.h"
13 #include "chrome/browser/ui/app_list/app_list_controller_delegate.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 #include "chrome/browser/ui/extensions/extension_enable_flow.h"
17 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
18 #include "chrome/common/extensions/extension.h"
19 #include "chrome/common/extensions/extension_icon_set.h"
20 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
21 #include "content/public/browser/user_metrics.h"
22 #include "ui/gfx/color_utils.h"
23 #include "ui/gfx/image/image_skia_operations.h"
24
25 namespace app_list {
26
27 AppResult::AppResult(Profile* profile,
28                      const std::string& app_id,
29                      AppListControllerDelegate* controller)
30     : profile_(profile),
31       app_id_(app_id),
32       controller_(controller),
33       install_tracker_(NULL) {
34   set_id(extensions::Extension::GetBaseURLFromExtensionId(app_id_).spec());
35
36   const extensions::Extension* extension =
37       extensions::ExtensionSystem::Get(profile_)->extension_service()
38           ->GetInstalledExtension(app_id_);
39   DCHECK(extension);
40
41   is_platform_app_ = extension->is_platform_app();
42
43   icon_.reset(new extensions::IconImage(
44       profile_,
45       extension,
46       extensions::IconsInfo::GetIcons(extension),
47       extension_misc::EXTENSION_ICON_SMALL,
48       extensions::IconsInfo::GetDefaultAppIcon(),
49       this));
50   UpdateIcon();
51   StartObservingInstall();
52 }
53
54 AppResult::~AppResult() {
55   StopObservingInstall();
56 }
57
58 void AppResult::UpdateFromMatch(const TokenizedString& title,
59                                 const TokenizedStringMatch& match) {
60   const TokenizedStringMatch::Hits& hits = match.hits();
61
62   Tags tags;
63   tags.reserve(hits.size());
64   for (size_t i = 0; i < hits.size(); ++i)
65     tags.push_back(Tag(Tag::MATCH, hits[i].start(), hits[i].end()));
66
67   set_title(title.text());
68   set_title_tags(tags);
69   set_relevance(match.relevance());
70 }
71
72 void AppResult::Open(int event_flags) {
73   const extensions::Extension* extension =
74       extensions::ExtensionSystem::Get(profile_)->extension_service()
75           ->GetInstalledExtension(app_id_);
76   if (!extension)
77     return;
78
79   // Check if enable flow is already running or should be started
80   if (RunExtensionEnableFlow())
81     return;
82
83   CoreAppLauncherHandler::RecordAppListSearchLaunch(extension);
84   content::RecordAction(
85       content::UserMetricsAction("AppList_ClickOnAppFromSearch"));
86
87   controller_->ActivateApp(
88       profile_,
89       extension,
90       AppListControllerDelegate::LAUNCH_FROM_APP_LIST_SEARCH,
91       event_flags);
92 }
93
94 void AppResult::InvokeAction(int action_index, int event_flags) {}
95
96 scoped_ptr<ChromeSearchResult> AppResult::Duplicate() {
97   scoped_ptr<ChromeSearchResult> copy(
98       new AppResult(profile_, app_id_, controller_));
99   copy->set_title(title());
100   copy->set_title_tags(title_tags());
101
102   return copy.Pass();
103 }
104
105 ChromeSearchResultType AppResult::GetType() {
106   return APP_SEARCH_RESULT;
107 }
108
109 ui::MenuModel* AppResult::GetContextMenuModel() {
110   if (!context_menu_) {
111     context_menu_.reset(new AppContextMenu(
112         this, profile_, app_id_, controller_, is_platform_app_, true));
113   }
114
115   return context_menu_->GetMenuModel();
116 }
117
118 void AppResult::StartObservingInstall() {
119   DCHECK(!install_tracker_);
120
121   install_tracker_ = extensions::InstallTrackerFactory::GetForProfile(profile_);
122   install_tracker_->AddObserver(this);
123 }
124
125 void AppResult::StopObservingInstall() {
126   if (install_tracker_)
127     install_tracker_->RemoveObserver(this);
128
129   install_tracker_ = NULL;
130 }
131
132 bool AppResult::RunExtensionEnableFlow() {
133   const ExtensionService* service =
134       extensions::ExtensionSystem::Get(profile_)->extension_service();
135   if (service->IsExtensionEnabledForLauncher(app_id_))
136     return false;
137
138   if (!extension_enable_flow_) {
139     controller_->OnShowExtensionPrompt();
140
141     extension_enable_flow_.reset(new ExtensionEnableFlow(
142         profile_, app_id_, this));
143     extension_enable_flow_->StartForNativeWindow(
144         controller_->GetAppListWindow());
145   }
146   return true;
147 }
148
149 void AppResult::UpdateIcon() {
150   gfx::ImageSkia icon = icon_->image_skia();
151
152   const ExtensionService* service =
153       extensions::ExtensionSystem::Get(profile_)->extension_service();
154   const bool enabled = service->IsExtensionEnabledForLauncher(app_id_);
155   if (!enabled) {
156     const color_utils::HSL shift = {-1, 0, 0.6};
157     icon = gfx::ImageSkiaOperations::CreateHSLShiftedImage(icon, shift);
158   }
159
160   SetIcon(icon);
161 }
162
163 void AppResult::OnExtensionIconImageChanged(extensions::IconImage* image) {
164   DCHECK_EQ(icon_.get(), image);
165   UpdateIcon();
166 }
167
168 void AppResult::ExecuteLaunchCommand(int event_flags) {
169   Open(event_flags);
170 }
171
172 void AppResult::ExtensionEnableFlowFinished() {
173   extension_enable_flow_.reset();
174   controller_->OnCloseExtensionPrompt();
175
176   // Automatically open app after enabling.
177   Open(ui::EF_NONE);
178 }
179
180 void AppResult::ExtensionEnableFlowAborted(bool user_initiated) {
181   extension_enable_flow_.reset();
182   controller_->OnCloseExtensionPrompt();
183 }
184
185 void AppResult::OnBeginExtensionInstall(const std::string& extension_id,
186                                         const std::string& extension_name,
187                                         const gfx::ImageSkia& installing_icon,
188                                         bool is_app,
189                                         bool is_platform_app) {}
190
191 void AppResult::OnDownloadProgress(const std::string& extension_id,
192                                    int percent_downloaded) {}
193
194 void AppResult::OnInstallFailure(const std::string& extension_id) {}
195
196 void AppResult::OnExtensionInstalled(const extensions::Extension* extension) {}
197
198 void AppResult::OnExtensionLoaded(const extensions::Extension* extension) {
199   UpdateIcon();
200 }
201
202 void AppResult::OnExtensionUnloaded(const extensions::Extension* extension) {}
203
204 void AppResult::OnExtensionUninstalled(const extensions::Extension* extension) {
205   if (extension->id() != app_id_)
206     return;
207
208   NotifyItemUninstalled();
209 }
210
211 void AppResult::OnAppsReordered() {}
212
213 void AppResult::OnAppInstalledToAppList(const std::string& extension_id) {}
214
215 void AppResult::OnShutdown() { StopObservingInstall(); }
216
217 }  // namespace app_list