OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 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/ash/app_list/extension_app_item.h" |
| 6 |
| 7 #include "base/utf_string_conversions.h" |
| 8 #include "chrome/browser/extensions/extension_prefs.h" |
| 9 #include "chrome/browser/extensions/extension_service.h" |
| 10 #include "chrome/browser/extensions/extension_system.h" |
| 11 #include "chrome/browser/extensions/extension_uninstall_dialog.h" |
| 12 #include "chrome/browser/extensions/management_policy.h" |
| 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/ui/ash/extension_utils.h" |
| 15 #include "chrome/browser/ui/browser.h" |
| 16 #include "chrome/browser/ui/browser_finder.h" |
| 17 #include "chrome/browser/ui/browser_tabstrip.h" |
| 18 #include "chrome/browser/ui/browser_window.h" |
| 19 #include "chrome/browser/ui/views/ash/launcher/chrome_launcher_controller.h" |
| 20 #include "chrome/common/extensions/extension.h" |
| 21 #include "chrome/common/extensions/extension_icon_set.h" |
| 22 #include "grit/chromium_strings.h" |
| 23 #include "grit/generated_resources.h" |
| 24 #include "ui/base/l10n/l10n_util.h" |
| 25 #include "ui/gfx/image/image.h" |
| 26 |
| 27 using extensions::Extension; |
| 28 |
| 29 namespace { |
| 30 |
| 31 enum CommandId { |
| 32 LAUNCH = 100, |
| 33 TOGGLE_PIN, |
| 34 OPTIONS, |
| 35 UNINSTALL, |
| 36 // Order matters in LAUNCHER_TYPE_xxxx and must match LaunchType. |
| 37 LAUNCH_TYPE_START = 200, |
| 38 LAUNCH_TYPE_PINNED_TAB = LAUNCH_TYPE_START, |
| 39 LAUNCH_TYPE_REGULAR_TAB, |
| 40 LAUNCH_TYPE_FULLSCREEN, |
| 41 LAUNCH_TYPE_WINDOW, |
| 42 LAUNCH_TYPE_LAST, |
| 43 }; |
| 44 |
| 45 // ExtensionUninstaller decouples ExtensionAppItem from the extension uninstall |
| 46 // flow. It shows extension uninstall dialog and wait for user to confirm or |
| 47 // cancel the uninstall. |
| 48 class ExtensionUninstaller : public ExtensionUninstallDialog::Delegate { |
| 49 public: |
| 50 ExtensionUninstaller(Profile* profile, |
| 51 const std::string& extension_id) |
| 52 : profile_(profile), |
| 53 extension_id_(extension_id) { |
| 54 } |
| 55 |
| 56 void Run() { |
| 57 const Extension* extension = |
| 58 profile_->GetExtensionService()->GetExtensionById(extension_id_, true); |
| 59 if (!extension) { |
| 60 CleanUp(); |
| 61 return; |
| 62 } |
| 63 |
| 64 ExtensionUninstallDialog* dialog = |
| 65 ExtensionUninstallDialog::Create(NULL, this); |
| 66 dialog->ConfirmUninstall(extension); |
| 67 } |
| 68 |
| 69 private: |
| 70 // Overridden from ExtensionUninstallDialog::Delegate: |
| 71 virtual void ExtensionUninstallAccepted() OVERRIDE { |
| 72 ExtensionService* service = profile_->GetExtensionService(); |
| 73 const Extension* extension = service->GetExtensionById(extension_id_, true); |
| 74 if (extension) { |
| 75 service->UninstallExtension(extension_id_, |
| 76 false, /* external_uninstall*/ |
| 77 NULL); |
| 78 } |
| 79 |
| 80 CleanUp(); |
| 81 } |
| 82 |
| 83 virtual void ExtensionUninstallCanceled() OVERRIDE { |
| 84 CleanUp(); |
| 85 } |
| 86 |
| 87 void CleanUp() { |
| 88 delete this; |
| 89 } |
| 90 |
| 91 Profile* profile_; |
| 92 std::string extension_id_; |
| 93 |
| 94 DISALLOW_COPY_AND_ASSIGN(ExtensionUninstaller); |
| 95 }; |
| 96 |
| 97 extensions::ExtensionPrefs::LaunchType GetExtensionLaunchType( |
| 98 Profile* profile, |
| 99 const std::string& extension_id) { |
| 100 return profile->GetExtensionService()->extension_prefs()->GetLaunchType( |
| 101 extension_id, extensions::ExtensionPrefs::LAUNCH_DEFAULT); |
| 102 } |
| 103 |
| 104 void SetExtensionLaunchType( |
| 105 Profile* profile, |
| 106 const std::string& extension_id, |
| 107 extensions::ExtensionPrefs::LaunchType launch_type) { |
| 108 profile->GetExtensionService()->extension_prefs()->SetLaunchType( |
| 109 extension_id, launch_type); |
| 110 } |
| 111 |
| 112 bool IsExtensionEnabled(Profile* profile, const std::string& extension_id) { |
| 113 ExtensionService* service = profile->GetExtensionService(); |
| 114 return service->IsExtensionEnabled(extension_id) && |
| 115 !service->GetTerminatedExtension(extension_id); |
| 116 } |
| 117 |
| 118 bool IsAppPinned(const std::string& extension_id) { |
| 119 return ChromeLauncherController::instance()->IsAppPinned(extension_id); |
| 120 } |
| 121 |
| 122 void PinApp(const std::string& extension_id) { |
| 123 ChromeLauncherController::instance()->PinAppWithID(extension_id); |
| 124 } |
| 125 |
| 126 void UnpinApp(const std::string& extension_id) { |
| 127 return ChromeLauncherController::instance()->UnpinAppsWithID(extension_id); |
| 128 } |
| 129 |
| 130 bool CanPin() { |
| 131 return ChromeLauncherController::instance()->CanPin(); |
| 132 } |
| 133 |
| 134 } // namespace |
| 135 |
| 136 ExtensionAppItem::ExtensionAppItem(Profile* profile, |
| 137 const Extension* extension) |
| 138 : ChromeAppListItem(TYPE_APP), |
| 139 profile_(profile), |
| 140 extension_id_(extension->id()) { |
| 141 SetTitle(extension->name()); |
| 142 LoadImage(extension); |
| 143 } |
| 144 |
| 145 ExtensionAppItem::~ExtensionAppItem() { |
| 146 } |
| 147 |
| 148 const Extension* ExtensionAppItem::GetExtension() const { |
| 149 const Extension* extension = |
| 150 profile_->GetExtensionService()->GetInstalledExtension(extension_id_); |
| 151 return extension; |
| 152 } |
| 153 |
| 154 void ExtensionAppItem::LoadImage(const Extension* extension) { |
| 155 tracker_.reset(new ImageLoadingTracker(this)); |
| 156 tracker_->LoadImage(extension, |
| 157 extension->GetIconResource( |
| 158 ExtensionIconSet::EXTENSION_ICON_LARGE, |
| 159 ExtensionIconSet::MATCH_BIGGER), |
| 160 gfx::Size(ExtensionIconSet::EXTENSION_ICON_LARGE, |
| 161 ExtensionIconSet::EXTENSION_ICON_LARGE), |
| 162 ImageLoadingTracker::DONT_CACHE); |
| 163 } |
| 164 |
| 165 void ExtensionAppItem::ShowExtensionOptions() { |
| 166 const Extension* extension = GetExtension(); |
| 167 if (!extension) |
| 168 return; |
| 169 |
| 170 // TODO(beng): use Navigate()! |
| 171 Browser* browser = browser::FindLastActiveWithProfile(profile_); |
| 172 if (!browser) { |
| 173 browser = new Browser(Browser::CreateParams(profile_)); |
| 174 browser->window()->Show(); |
| 175 } |
| 176 |
| 177 chrome::AddSelectedTabWithURL(browser, extension->options_url(), |
| 178 content::PAGE_TRANSITION_LINK); |
| 179 browser->window()->Activate(); |
| 180 } |
| 181 |
| 182 void ExtensionAppItem::StartExtensionUninstall() { |
| 183 // ExtensionUninstall deletes itself when done or aborted. |
| 184 ExtensionUninstaller* uninstaller = new ExtensionUninstaller(profile_, |
| 185 extension_id_); |
| 186 uninstaller->Run(); |
| 187 } |
| 188 |
| 189 void ExtensionAppItem::OnImageLoaded(const gfx::Image& image, |
| 190 const std::string& extension_id, |
| 191 int tracker_index) { |
| 192 if (!image.IsEmpty()) |
| 193 SetIcon(*image.ToImageSkia()); |
| 194 else |
| 195 SetIcon(Extension::GetDefaultIcon(true /* is_app */)); |
| 196 } |
| 197 |
| 198 bool ExtensionAppItem::IsItemForCommandIdDynamic(int command_id) const { |
| 199 return command_id == TOGGLE_PIN; |
| 200 } |
| 201 |
| 202 string16 ExtensionAppItem::GetLabelForCommandId(int command_id) const { |
| 203 if (command_id == TOGGLE_PIN) { |
| 204 return IsAppPinned(extension_id_) ? |
| 205 l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_UNPIN) : |
| 206 l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_PIN); |
| 207 } else { |
| 208 NOTREACHED(); |
| 209 return string16(); |
| 210 } |
| 211 } |
| 212 |
| 213 bool ExtensionAppItem::IsCommandIdChecked(int command_id) const { |
| 214 if (command_id >= LAUNCH_TYPE_START && command_id < LAUNCH_TYPE_LAST) { |
| 215 return static_cast<int>(GetExtensionLaunchType(profile_, extension_id_)) + |
| 216 LAUNCH_TYPE_START == command_id; |
| 217 } |
| 218 return false; |
| 219 } |
| 220 |
| 221 bool ExtensionAppItem::IsCommandIdEnabled(int command_id) const { |
| 222 if (command_id == TOGGLE_PIN) { |
| 223 return CanPin(); |
| 224 } else if (command_id == OPTIONS) { |
| 225 const Extension* extension = GetExtension(); |
| 226 return IsExtensionEnabled(profile_, extension_id_) && extension && |
| 227 !extension->options_url().is_empty(); |
| 228 } else if (command_id == UNINSTALL) { |
| 229 const Extension* extension = GetExtension(); |
| 230 const extensions::ManagementPolicy* policy = |
| 231 extensions::ExtensionSystem::Get(profile_)->management_policy(); |
| 232 return extension && |
| 233 policy->UserMayModifySettings(extension, NULL); |
| 234 } |
| 235 return true; |
| 236 } |
| 237 |
| 238 bool ExtensionAppItem::GetAcceleratorForCommandId( |
| 239 int command_id, |
| 240 ui::Accelerator* acclelrator) { |
| 241 return false; |
| 242 } |
| 243 |
| 244 void ExtensionAppItem::ExecuteCommand(int command_id) { |
| 245 if (command_id == LAUNCH) { |
| 246 Activate(0); |
| 247 } else if (command_id == TOGGLE_PIN && CanPin()) { |
| 248 if (IsAppPinned(extension_id_)) |
| 249 UnpinApp(extension_id_); |
| 250 else |
| 251 PinApp(extension_id_); |
| 252 } else if (command_id >= LAUNCH_TYPE_START && |
| 253 command_id < LAUNCH_TYPE_LAST) { |
| 254 SetExtensionLaunchType(profile_, |
| 255 extension_id_, |
| 256 static_cast<extensions::ExtensionPrefs::LaunchType>( |
| 257 command_id - LAUNCH_TYPE_START)); |
| 258 } else if (command_id == OPTIONS) { |
| 259 ShowExtensionOptions(); |
| 260 } else if (command_id == UNINSTALL) { |
| 261 StartExtensionUninstall(); |
| 262 } |
| 263 } |
| 264 |
| 265 void ExtensionAppItem::Activate(int event_flags) { |
| 266 const Extension* extension = GetExtension(); |
| 267 if (!extension) |
| 268 return; |
| 269 |
| 270 ChromeLauncherController::instance()->OpenAppID(extension->id(), event_flags); |
| 271 } |
| 272 |
| 273 ui::MenuModel* ExtensionAppItem::GetContextMenuModel() { |
| 274 // No context menu for Chrome app. |
| 275 if (extension_id_ == extension_misc::kChromeAppId) |
| 276 return NULL; |
| 277 |
| 278 if (!context_menu_model_.get()) { |
| 279 context_menu_model_.reset(new ui::SimpleMenuModel(this)); |
| 280 context_menu_model_->AddItem(LAUNCH, UTF8ToUTF16(title())); |
| 281 context_menu_model_->AddSeparator(); |
| 282 context_menu_model_->AddItemWithStringId( |
| 283 TOGGLE_PIN, |
| 284 IsAppPinned(extension_id_) ? IDS_APP_LIST_CONTEXT_MENU_UNPIN : |
| 285 IDS_APP_LIST_CONTEXT_MENU_PIN); |
| 286 context_menu_model_->AddSeparator(); |
| 287 context_menu_model_->AddCheckItemWithStringId( |
| 288 LAUNCH_TYPE_REGULAR_TAB, |
| 289 IDS_APP_CONTEXT_MENU_OPEN_REGULAR); |
| 290 context_menu_model_->AddCheckItemWithStringId( |
| 291 LAUNCH_TYPE_PINNED_TAB, |
| 292 IDS_APP_CONTEXT_MENU_OPEN_PINNED); |
| 293 context_menu_model_->AddCheckItemWithStringId( |
| 294 LAUNCH_TYPE_WINDOW, |
| 295 IDS_APP_CONTEXT_MENU_OPEN_WINDOW); |
| 296 // Even though the launch type is Full Screen it is more accurately |
| 297 // described as Maximized in Ash. |
| 298 context_menu_model_->AddCheckItemWithStringId( |
| 299 LAUNCH_TYPE_FULLSCREEN, |
| 300 IDS_APP_CONTEXT_MENU_OPEN_MAXIMIZED); |
| 301 context_menu_model_->AddSeparator(); |
| 302 context_menu_model_->AddItemWithStringId(OPTIONS, IDS_NEW_TAB_APP_OPTIONS); |
| 303 context_menu_model_->AddItemWithStringId(UNINSTALL, |
| 304 IDS_EXTENSIONS_UNINSTALL); |
| 305 } |
| 306 |
| 307 return context_menu_model_.get(); |
| 308 } |
OLD | NEW |