Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ui / app_list / search / app_result.cc
blob89dbe9c24c6e51c74f5b3f143530730538d0ea53
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.
5 #include "chrome/browser/ui/app_list/search/app_result.h"
7 #include "base/time/time.h"
8 #include "chrome/browser/extensions/extension_util.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/app_list/app_context_menu.h"
11 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
12 #include "chrome/browser/ui/app_list/search/search_util.h"
13 #include "chrome/browser/ui/extensions/extension_enable_flow.h"
14 #include "chrome/common/extensions/extension_metrics.h"
15 #include "content/public/browser/user_metrics.h"
16 #include "extensions/browser/extension_registry.h"
17 #include "extensions/browser/extension_system_provider.h"
18 #include "extensions/browser/extensions_browser_client.h"
19 #include "extensions/common/constants.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_icon_set.h"
22 #include "extensions/common/manifest_handlers/icons_handler.h"
23 #include "ui/app_list/app_list_switches.h"
24 #include "ui/gfx/color_utils.h"
25 #include "ui/gfx/image/image_skia_operations.h"
27 namespace app_list {
29 AppResult::AppResult(Profile* profile,
30 const std::string& app_id,
31 AppListControllerDelegate* controller,
32 bool is_recommendation)
33 : profile_(profile),
34 app_id_(app_id),
35 controller_(controller),
36 extension_registry_(NULL) {
37 set_id(extensions::Extension::GetBaseURLFromExtensionId(app_id_).spec());
38 if (app_list::switches::IsExperimentalAppListEnabled())
39 set_display_type(is_recommendation ? DISPLAY_RECOMMENDATION : DISPLAY_TILE);
41 const extensions::Extension* extension =
42 extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension(
43 app_id_);
44 DCHECK(extension);
46 is_platform_app_ = extension->is_platform_app();
48 icon_.reset(
49 new extensions::IconImage(profile_,
50 extension,
51 extensions::IconsInfo::GetIcons(extension),
52 GetPreferredIconDimension(),
53 extensions::util::GetDefaultAppIcon(),
54 this));
55 UpdateIcon();
57 StartObservingExtensionRegistry();
60 AppResult::~AppResult() {
61 StopObservingExtensionRegistry();
64 void AppResult::UpdateFromLastLaunched(const base::Time& current_time,
65 const base::Time& last_launched) {
66 base::TimeDelta delta = current_time - last_launched;
67 // |current_time| can be before |last_launched| in weird cases such as users
68 // playing with their clocks. Handle this gracefully.
69 if (current_time < last_launched) {
70 set_relevance(1.0);
71 return;
74 const int kSecondsInWeek = 60 * 60 * 24 * 7;
76 // Set the relevance to a value between 0 and 1. This function decays as the
77 // time delta increases and reaches a value of 0.5 at 1 week.
78 set_relevance(1 / (1 + delta.InSecondsF() / kSecondsInWeek));
81 void AppResult::Open(int event_flags) {
82 RecordHistogram(APP_SEARCH_RESULT);
83 const extensions::Extension* extension =
84 extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension(
85 app_id_);
86 if (!extension)
87 return;
89 // Don't auto-enable apps that cannot be launched.
90 if (!extensions::util::IsAppLaunchable(app_id_, profile_))
91 return;
93 // Check if enable flow is already running or should be started
94 if (RunExtensionEnableFlow())
95 return;
97 if (display_type() != DISPLAY_RECOMMENDATION) {
98 extensions::RecordAppListSearchLaunch(extension);
99 content::RecordAction(
100 base::UserMetricsAction("AppList_ClickOnAppFromSearch"));
103 controller_->ActivateApp(
104 profile_,
105 extension,
106 AppListControllerDelegate::LAUNCH_FROM_APP_LIST_SEARCH,
107 event_flags);
110 scoped_ptr<SearchResult> AppResult::Duplicate() const {
111 scoped_ptr<SearchResult> copy(
112 new AppResult(profile_, app_id_, controller_,
113 display_type() == DISPLAY_RECOMMENDATION));
114 copy->set_title(title());
115 copy->set_title_tags(title_tags());
116 copy->set_relevance(relevance());
118 return copy.Pass();
121 ui::MenuModel* AppResult::GetContextMenuModel() {
122 if (!context_menu_) {
123 context_menu_.reset(new AppContextMenu(
124 this, profile_, app_id_, controller_));
125 context_menu_->set_is_platform_app(is_platform_app_);
126 context_menu_->set_is_search_result(true);
129 return context_menu_->GetMenuModel();
132 void AppResult::StartObservingExtensionRegistry() {
133 DCHECK(!extension_registry_);
135 extension_registry_ = extensions::ExtensionRegistry::Get(profile_);
136 extension_registry_->AddObserver(this);
139 void AppResult::StopObservingExtensionRegistry() {
140 if (extension_registry_)
141 extension_registry_->RemoveObserver(this);
142 extension_registry_ = NULL;
145 bool AppResult::RunExtensionEnableFlow() {
146 if (extensions::util::IsAppLaunchableWithoutEnabling(app_id_, profile_))
147 return false;
149 if (!extension_enable_flow_) {
150 controller_->OnShowChildDialog();
152 extension_enable_flow_.reset(new ExtensionEnableFlow(
153 profile_, app_id_, this));
154 extension_enable_flow_->StartForNativeWindow(
155 controller_->GetAppListWindow());
157 return true;
160 void AppResult::UpdateIcon() {
161 gfx::ImageSkia icon = icon_->image_skia();
163 if (!extensions::util::IsAppLaunchable(app_id_, profile_)) {
164 const color_utils::HSL shift = {-1, 0, 0.6};
165 icon = gfx::ImageSkiaOperations::CreateHSLShiftedImage(icon, shift);
168 SetIcon(icon);
171 void AppResult::OnExtensionIconImageChanged(extensions::IconImage* image) {
172 DCHECK_EQ(icon_.get(), image);
173 UpdateIcon();
176 void AppResult::ExecuteLaunchCommand(int event_flags) {
177 Open(event_flags);
180 void AppResult::ExtensionEnableFlowFinished() {
181 extension_enable_flow_.reset();
182 controller_->OnCloseChildDialog();
184 // Automatically open app after enabling.
185 Open(ui::EF_NONE);
188 void AppResult::ExtensionEnableFlowAborted(bool user_initiated) {
189 extension_enable_flow_.reset();
190 controller_->OnCloseChildDialog();
193 void AppResult::OnExtensionLoaded(content::BrowserContext* browser_context,
194 const extensions::Extension* extension) {
195 UpdateIcon();
198 void AppResult::OnShutdown(extensions::ExtensionRegistry* registry) {
199 DCHECK_EQ(extension_registry_, registry);
200 StopObservingExtensionRegistry();
203 } // namespace app_list