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/extensions/extension_context_menu_model.h" 6 7 #include "base/prefs/pref_service.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 10 #include "chrome/browser/extensions/extension_action.h" 11 #include "chrome/browser/extensions/extension_action_manager.h" 12 #include "chrome/browser/extensions/extension_service.h" 13 #include "chrome/browser/extensions/extension_tab_util.h" 14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/chrome_pages.h" 17 #include "chrome/browser/ui/tabs/tab_strip_model.h" 18 #include "chrome/common/extensions/extension_constants.h" 19 #include "chrome/common/extensions/manifest_url_handler.h" 20 #include "chrome/common/pref_names.h" 21 #include "chrome/common/url_constants.h" 22 #include "content/public/browser/web_contents.h" 23 #include "extensions/browser/extension_prefs.h" 24 #include "extensions/browser/extension_system.h" 25 #include "extensions/browser/management_policy.h" 26 #include "extensions/common/extension.h" 27 #include "grit/chromium_strings.h" 28 #include "grit/generated_resources.h" 29 #include "ui/base/l10n/l10n_util.h" 30 31 using content::OpenURLParams; 32 using content::Referrer; 33 using content::WebContents; 34 using extensions::Extension; 35 36 ExtensionContextMenuModel::ExtensionContextMenuModel(const Extension* extension, 37 Browser* browser, 38 PopupDelegate* delegate) 39 : SimpleMenuModel(this), 40 extension_id_(extension->id()), 41 browser_(browser), 42 profile_(browser->profile()), 43 delegate_(delegate) { 44 InitMenu(extension); 45 46 if (profile_->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode) && 47 delegate_) { 48 AddSeparator(ui::NORMAL_SEPARATOR); 49 AddItemWithStringId(INSPECT_POPUP, IDS_EXTENSION_ACTION_INSPECT_POPUP); 50 } 51 } 52 53 ExtensionContextMenuModel::ExtensionContextMenuModel(const Extension* extension, 54 Browser* browser) 55 : SimpleMenuModel(this), 56 extension_id_(extension->id()), 57 browser_(browser), 58 profile_(browser->profile()), 59 delegate_(NULL) { 60 InitMenu(extension); 61 } 62 63 bool ExtensionContextMenuModel::IsCommandIdChecked(int command_id) const { 64 return false; 65 } 66 67 bool ExtensionContextMenuModel::IsCommandIdEnabled(int command_id) const { 68 const Extension* extension = this->GetExtension(); 69 if (!extension) 70 return false; 71 72 if (command_id == CONFIGURE) { 73 return 74 extensions::ManifestURL::GetOptionsPage(extension).spec().length() > 0; 75 } else if (command_id == NAME) { 76 // The NAME links to the Homepage URL. If the extension doesn't have a 77 // homepage, we just disable this menu item. 78 return extensions::ManifestURL::GetHomepageURL(extension).is_valid(); 79 } else if (command_id == INSPECT_POPUP) { 80 WebContents* web_contents = 81 browser_->tab_strip_model()->GetActiveWebContents(); 82 if (!web_contents) 83 return false; 84 85 return extension_action_ && 86 extension_action_->HasPopup(SessionID::IdForTab(web_contents)); 87 } else if (command_id == UNINSTALL) { 88 // Some extension types can not be uninstalled. 89 return extensions::ExtensionSystem::Get( 90 profile_)->management_policy()->UserMayModifySettings(extension, NULL); 91 } 92 return true; 93 } 94 95 bool ExtensionContextMenuModel::GetAcceleratorForCommandId( 96 int command_id, ui::Accelerator* accelerator) { 97 return false; 98 } 99 100 void ExtensionContextMenuModel::ExecuteCommand(int command_id, 101 int event_flags) { 102 const Extension* extension = GetExtension(); 103 if (!extension) 104 return; 105 106 switch (command_id) { 107 case NAME: { 108 OpenURLParams params(extensions::ManifestURL::GetHomepageURL(extension), 109 Referrer(), NEW_FOREGROUND_TAB, 110 content::PAGE_TRANSITION_LINK, false); 111 browser_->OpenURL(params); 112 break; 113 } 114 case CONFIGURE: 115 DCHECK(!extensions::ManifestURL::GetOptionsPage(extension).is_empty()); 116 extensions::ExtensionTabUtil::OpenOptionsPage(extension, browser_); 117 break; 118 case HIDE: { 119 extensions::ExtensionActionAPI::SetBrowserActionVisibility( 120 extensions::ExtensionPrefs::Get(profile_), extension->id(), false); 121 break; 122 } 123 case UNINSTALL: { 124 AddRef(); // Balanced in Accepted() and Canceled() 125 extension_uninstall_dialog_.reset( 126 extensions::ExtensionUninstallDialog::Create( 127 profile_, browser_, this)); 128 extension_uninstall_dialog_->ConfirmUninstall(extension); 129 break; 130 } 131 case MANAGE: { 132 chrome::ShowExtensions(browser_, extension->id()); 133 break; 134 } 135 case INSPECT_POPUP: { 136 delegate_->InspectPopup(extension_action_); 137 break; 138 } 139 default: 140 NOTREACHED() << "Unknown option"; 141 break; 142 } 143 } 144 145 void ExtensionContextMenuModel::ExtensionUninstallAccepted() { 146 if (GetExtension()) { 147 extensions::ExtensionSystem::Get(profile_)->extension_service()-> 148 UninstallExtension(extension_id_, false, NULL); 149 } 150 Release(); 151 } 152 153 void ExtensionContextMenuModel::ExtensionUninstallCanceled() { 154 Release(); 155 } 156 157 ExtensionContextMenuModel::~ExtensionContextMenuModel() {} 158 159 void ExtensionContextMenuModel::InitMenu(const Extension* extension) { 160 DCHECK(extension); 161 162 extensions::ExtensionActionManager* extension_action_manager = 163 extensions::ExtensionActionManager::Get(profile_); 164 extension_action_ = extension_action_manager->GetBrowserAction(*extension); 165 if (!extension_action_) 166 extension_action_ = extension_action_manager->GetPageAction(*extension); 167 168 std::string extension_name = extension->name(); 169 // Ampersands need to be escaped to avoid being treated like 170 // mnemonics in the menu. 171 base::ReplaceChars(extension_name, "&", "&&", &extension_name); 172 AddItem(NAME, base::UTF8ToUTF16(extension_name)); 173 AddSeparator(ui::NORMAL_SEPARATOR); 174 AddItemWithStringId(CONFIGURE, IDS_EXTENSIONS_OPTIONS_MENU_ITEM); 175 AddItem(UNINSTALL, l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL)); 176 if (extension_action_manager->GetBrowserAction(*extension)) 177 AddItemWithStringId(HIDE, IDS_EXTENSIONS_HIDE_BUTTON); 178 AddSeparator(ui::NORMAL_SEPARATOR); 179 AddItemWithStringId(MANAGE, IDS_MANAGE_EXTENSION); 180 } 181 182 const Extension* ExtensionContextMenuModel::GetExtension() const { 183 ExtensionService* extension_service = 184 extensions::ExtensionSystem::Get(profile_)->extension_service(); 185 return extension_service->GetExtensionById(extension_id_, false); 186 } 187