app_result.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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 "content/public/browser/user_metrics.h" 19#include "extensions/browser/extension_system.h" 20#include "extensions/browser/extension_system_provider.h" 21#include "extensions/browser/extensions_browser_client.h" 22#include "extensions/common/extension.h" 23#include "extensions/common/extension_icon_set.h" 24#include "extensions/common/manifest_handlers/icons_handler.h" 25#include "ui/gfx/color_utils.h" 26#include "ui/gfx/image/image_skia_operations.h" 27 28namespace app_list { 29 30AppResult::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 57AppResult::~AppResult() { 58 StopObservingInstall(); 59} 60 61void 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 75void 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 97void AppResult::InvokeAction(int action_index, int event_flags) {} 98 99scoped_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 108ChromeSearchResultType AppResult::GetType() { 109 return APP_SEARCH_RESULT; 110} 111 112ui::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 123void AppResult::StartObservingInstall() { 124 DCHECK(!install_tracker_); 125 126 install_tracker_ = extensions::InstallTrackerFactory::GetForProfile(profile_); 127 install_tracker_->AddObserver(this); 128} 129 130void AppResult::StopObservingInstall() { 131 if (install_tracker_) 132 install_tracker_->RemoveObserver(this); 133 134 install_tracker_ = NULL; 135} 136 137bool 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 152void 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 163void AppResult::OnExtensionIconImageChanged(extensions::IconImage* image) { 164 DCHECK_EQ(icon_.get(), image); 165 UpdateIcon(); 166} 167 168void AppResult::ExecuteLaunchCommand(int event_flags) { 169 Open(event_flags); 170} 171 172void AppResult::ExtensionEnableFlowFinished() { 173 extension_enable_flow_.reset(); 174 controller_->OnCloseExtensionPrompt(); 175 176 // Automatically open app after enabling. 177 Open(ui::EF_NONE); 178} 179 180void AppResult::ExtensionEnableFlowAborted(bool user_initiated) { 181 extension_enable_flow_.reset(); 182 controller_->OnCloseExtensionPrompt(); 183} 184 185void AppResult::OnExtensionLoaded(const extensions::Extension* extension) { 186 UpdateIcon(); 187} 188 189void AppResult::OnExtensionUninstalled(const extensions::Extension* extension) { 190 if (extension->id() != app_id_) 191 return; 192 193 NotifyItemUninstalled(); 194} 195 196void AppResult::OnShutdown() { StopObservingInstall(); } 197 198} // namespace app_list 199