Upstream version 5.34.104.0
[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_util.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_icon_set.h"
19 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
20 #include "content/public/browser/user_metrics.h"
21 #include "extensions/browser/extension_system.h"
22 #include "extensions/browser/extension_system_provider.h"
23 #include "extensions/browser/extensions_browser_client.h"
24 #include "extensions/common/extension.h"
25 #include "ui/gfx/color_utils.h"
26 #include "ui/gfx/image/image_skia_operations.h"
27
28 namespace app_list {
29
30 AppResult::AppResult(Profile* profile,
31                      const std::string& app_id,
32                      AppListControllerDelegate* controller)
33     : profile_(profile),
34       app_id_(app_id),
35       controller_(controller),
36       install_tracker_(NULL) {
37   set_id(extensions::Extension::GetBaseURLFromExtensionId(app_id_).spec());
38
39   const extensions::Extension* extension =
40       extensions::ExtensionSystem::Get(profile_)->extension_service()
41           ->GetInstalledExtension(app_id_);
42   DCHECK(extension);
43
44   is_platform_app_ = extension->is_platform_app();
45
46   icon_.reset(new extensions::IconImage(
47       profile_,
48       extension,
49       extensions::IconsInfo::GetIcons(extension),
50       extension_misc::EXTENSION_ICON_SMALL,
51       extensions::IconsInfo::GetDefaultAppIcon(),
52       this));
53   UpdateIcon();
54   StartObservingInstall();
55 }
56
57 AppResult::~AppResult() {
58   StopObservingInstall();
59 }
60
61 void AppResult::UpdateFromMatch(const TokenizedString& title,
62                                 const TokenizedStringMatch& match) {
63   const TokenizedStringMatch::Hits& hits = match.hits();
64
65   Tags tags;
66   tags.reserve(hits.size());
67   for (size_t i = 0; i < hits.size(); ++i)
68     tags.push_back(Tag(Tag::MATCH, hits[i].start(), hits[i].end()));
69
70   set_title(title.text());
71   set_title_tags(tags);
72   set_relevance(match.relevance());
73 }
74
75 void AppResult::Open(int event_flags) {
76   const extensions::Extension* extension =
77       extensions::ExtensionSystem::Get(profile_)->extension_service()
78           ->GetInstalledExtension(app_id_);
79   if (!extension)
80     return;
81
82   // Check if enable flow is already running or should be started
83   if (RunExtensionEnableFlow())
84     return;
85
86   CoreAppLauncherHandler::RecordAppListSearchLaunch(extension);
87   content::RecordAction(
88       base::UserMetricsAction("AppList_ClickOnAppFromSearch"));
89
90   controller_->ActivateApp(
91       profile_,
92       extension,
93       AppListControllerDelegate::LAUNCH_FROM_APP_LIST_SEARCH,
94       event_flags);
95 }
96
97 void AppResult::InvokeAction(int action_index, int event_flags) {}
98
99 scoped_ptr<ChromeSearchResult> AppResult::Duplicate() {
100   scoped_ptr<ChromeSearchResult> copy(
101       new AppResult(profile_, app_id_, controller_));
102   copy->set_title(title());
103   copy->set_title_tags(title_tags());
104
105   return copy.Pass();
106 }
107
108 ChromeSearchResultType AppResult::GetType() {
109   return APP_SEARCH_RESULT;
110 }
111
112 ui::MenuModel* AppResult::GetContextMenuModel() {
113   if (!context_menu_) {
114     context_menu_.reset(new AppContextMenu(
115         this, profile_, app_id_, controller_));
116     context_menu_->set_is_platform_app(is_platform_app_);
117     context_menu_->set_is_search_result(true);
118   }
119
120   return context_menu_->GetMenuModel();
121 }
122
123 void AppResult::StartObservingInstall() {
124   DCHECK(!install_tracker_);
125
126   install_tracker_ = extensions::InstallTrackerFactory::GetForProfile(profile_);
127   install_tracker_->AddObserver(this);
128 }
129
130 void AppResult::StopObservingInstall() {
131   if (install_tracker_)
132     install_tracker_->RemoveObserver(this);
133
134   install_tracker_ = NULL;
135 }
136
137 bool AppResult::RunExtensionEnableFlow() {
138   if (extensions::util::IsAppLaunchableWithoutEnabling(app_id_, profile_))
139     return false;
140
141   if (!extension_enable_flow_) {
142     controller_->OnShowExtensionPrompt();
143
144     extension_enable_flow_.reset(new ExtensionEnableFlow(
145         profile_, app_id_, this));
146     extension_enable_flow_->StartForNativeWindow(
147         controller_->GetAppListWindow());
148   }
149   return true;
150 }
151
152 void AppResult::UpdateIcon() {
153   gfx::ImageSkia icon = icon_->image_skia();
154
155   if (!extensions::util::IsAppLaunchable(app_id_, profile_)) {
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(
186     const ExtensionInstallParams& params) {}
187
188 void AppResult::OnDownloadProgress(const std::string& extension_id,
189                                    int percent_downloaded) {}
190
191 void AppResult::OnInstallFailure(const std::string& extension_id) {}
192
193 void AppResult::OnExtensionInstalled(const extensions::Extension* extension) {}
194
195 void AppResult::OnExtensionLoaded(const extensions::Extension* extension) {
196   UpdateIcon();
197 }
198
199 void AppResult::OnExtensionUnloaded(const extensions::Extension* extension) {}
200
201 void AppResult::OnExtensionUninstalled(const extensions::Extension* extension) {
202   if (extension->id() != app_id_)
203     return;
204
205   NotifyItemUninstalled();
206 }
207
208 void AppResult::OnAppsReordered() {}
209
210 void AppResult::OnAppInstalledToAppList(const std::string& extension_id) {}
211
212 void AppResult::OnShutdown() { StopObservingInstall(); }
213
214 }  // namespace app_list