| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2016 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/launcher/extension_launcher_context_menu.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "ash/desktop_background/user_wallpaper_delegate.h" |
| 10 #include "ash/metrics/user_metrics_recorder.h" |
| 11 #include "ash/shelf/shelf.h" |
| 12 #include "ash/shelf/shelf_item_delegate.h" |
| 13 #include "ash/shelf/shelf_widget.h" |
| 14 #include "ash/shell.h" |
| 15 #include "base/bind.h" |
| 16 #include "base/memory/scoped_ptr.h" |
| 17 #include "build/build_config.h" |
| 18 #include "chrome/browser/extensions/context_menu_matcher.h" |
| 19 #include "chrome/browser/extensions/extension_util.h" |
| 20 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
| 21 #include "chrome/browser/profiles/profile.h" |
| 22 #include "chrome/browser/ui/ash/chrome_shell_delegate.h" |
| 23 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" |
| 24 #include "chrome/common/extensions/extension_constants.h" |
| 25 #include "chrome/common/pref_names.h" |
| 26 #include "chrome/grit/generated_resources.h" |
| 27 #include "components/prefs/pref_service.h" |
| 28 #include "content/public/common/context_menu_params.h" |
| 29 #include "grit/ash_strings.h" |
| 30 #include "ui/base/l10n/l10n_util.h" |
| 31 |
| 32 namespace { |
| 33 |
| 34 bool MenuItemHasLauncherContext(const extensions::MenuItem* item) { |
| 35 return item->contexts().Contains(extensions::MenuItem::LAUNCHER); |
| 36 } |
| 37 |
| 38 } // name space |
| 39 |
| 40 ExtensionLauncherContextMenu::ExtensionLauncherContextMenu( |
| 41 ChromeLauncherController* controller, |
| 42 const ash::ShelfItem* item, |
| 43 ash::Shelf* shelf) |
| 44 : LauncherContextMenu(controller, item, shelf) { |
| 45 Init(); |
| 46 } |
| 47 |
| 48 ExtensionLauncherContextMenu::~ExtensionLauncherContextMenu() {} |
| 49 |
| 50 void ExtensionLauncherContextMenu::Init() { |
| 51 extension_items_.reset(new extensions::ContextMenuMatcher( |
| 52 controller()->profile(), this, this, |
| 53 base::Bind(MenuItemHasLauncherContext))); |
| 54 if (item().type == ash::TYPE_APP_SHORTCUT || |
| 55 item().type == ash::TYPE_WINDOWED_APP) { |
| 56 // V1 apps can be started from the menu - but V2 apps should not. |
| 57 if (!controller()->IsPlatformApp(item().id)) { |
| 58 AddItem(MENU_OPEN_NEW, base::string16()); |
| 59 AddSeparator(ui::NORMAL_SEPARATOR); |
| 60 } |
| 61 AddPinMenu(); |
| 62 if (controller()->IsOpen(item().id)) { |
| 63 AddItem(MENU_CLOSE, |
| 64 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE)); |
| 65 } |
| 66 if (!controller()->IsPlatformApp(item().id) && |
| 67 item().type != ash::TYPE_WINDOWED_APP) { |
| 68 AddSeparator(ui::NORMAL_SEPARATOR); |
| 69 if (extensions::util::IsNewBookmarkAppsEnabled()) { |
| 70 // With bookmark apps enabled, hosted apps launch in a window by |
| 71 // default. This menu item is re-interpreted as a single, toggle-able |
| 72 // option to launch the hosted app as a tab. |
| 73 AddCheckItemWithStringId(LAUNCH_TYPE_WINDOW, |
| 74 IDS_APP_CONTEXT_MENU_OPEN_WINDOW); |
| 75 } else { |
| 76 AddCheckItemWithStringId(LAUNCH_TYPE_REGULAR_TAB, |
| 77 IDS_APP_CONTEXT_MENU_OPEN_REGULAR); |
| 78 AddCheckItemWithStringId(LAUNCH_TYPE_PINNED_TAB, |
| 79 IDS_APP_CONTEXT_MENU_OPEN_PINNED); |
| 80 AddCheckItemWithStringId(LAUNCH_TYPE_WINDOW, |
| 81 IDS_APP_CONTEXT_MENU_OPEN_WINDOW); |
| 82 // Even though the launch type is Full Screen it is more accurately |
| 83 // described as Maximized in Ash. |
| 84 AddCheckItemWithStringId(LAUNCH_TYPE_FULLSCREEN, |
| 85 IDS_APP_CONTEXT_MENU_OPEN_MAXIMIZED); |
| 86 } |
| 87 } |
| 88 } else if (item().type == ash::TYPE_BROWSER_SHORTCUT) { |
| 89 AddItem(MENU_NEW_WINDOW, |
| 90 l10n_util::GetStringUTF16(IDS_APP_LIST_NEW_WINDOW)); |
| 91 if (!controller()->IsLoggedInAsGuest()) { |
| 92 AddItem(MENU_NEW_INCOGNITO_WINDOW, |
| 93 l10n_util::GetStringUTF16(IDS_APP_LIST_NEW_INCOGNITO_WINDOW)); |
| 94 } |
| 95 } else if (item().type == ash::TYPE_DIALOG) { |
| 96 AddItem(MENU_CLOSE, |
| 97 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE)); |
| 98 } else { |
| 99 if (item().type == ash::TYPE_PLATFORM_APP) { |
| 100 AddItem(MENU_PIN, |
| 101 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_PIN)); |
| 102 } |
| 103 bool show_close_button = controller()->IsOpen(item().id); |
| 104 #if defined(OS_CHROMEOS) |
| 105 if (extension_misc::IsImeMenuExtensionId( |
| 106 controller()->GetAppIDForShelfID(item().id))) { |
| 107 show_close_button = false; |
| 108 } |
| 109 #endif |
| 110 if (show_close_button) { |
| 111 AddItem(MENU_CLOSE, |
| 112 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE)); |
| 113 } |
| 114 } |
| 115 AddSeparator(ui::NORMAL_SEPARATOR); |
| 116 if (item().type == ash::TYPE_APP_SHORTCUT || |
| 117 item().type == ash::TYPE_WINDOWED_APP || |
| 118 item().type == ash::TYPE_PLATFORM_APP) { |
| 119 const extensions::MenuItem::ExtensionKey app_key( |
| 120 controller()->GetAppIDForShelfID(item().id)); |
| 121 if (!app_key.empty()) { |
| 122 int index = 0; |
| 123 extension_items_->AppendExtensionItems(app_key, base::string16(), &index, |
| 124 false); // is_action_menu |
| 125 AddSeparator(ui::NORMAL_SEPARATOR); |
| 126 } |
| 127 } |
| 128 AddAutohideAlignmentWallpaperMenu(); |
| 129 } |
| 130 |
| 131 base::string16 ExtensionLauncherContextMenu::GetLabelForCommandId( |
| 132 int command_id) const { |
| 133 if (command_id == MENU_OPEN_NEW) { |
| 134 if (item().type == ash::TYPE_PLATFORM_APP) { |
| 135 return l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW); |
| 136 } |
| 137 switch (controller()->GetLaunchType(item().id)) { |
| 138 case extensions::LAUNCH_TYPE_PINNED: |
| 139 case extensions::LAUNCH_TYPE_REGULAR: |
| 140 return l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_TAB); |
| 141 case extensions::LAUNCH_TYPE_FULLSCREEN: |
| 142 case extensions::LAUNCH_TYPE_WINDOW: |
| 143 return l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW); |
| 144 default: |
| 145 NOTREACHED(); |
| 146 return base::string16(); |
| 147 } |
| 148 } |
| 149 NOTREACHED(); |
| 150 return base::string16(); |
| 151 } |
| 152 |
| 153 bool ExtensionLauncherContextMenu::IsCommandIdChecked(int command_id) const { |
| 154 switch (command_id) { |
| 155 case LAUNCH_TYPE_PINNED_TAB: |
| 156 return controller()->GetLaunchType(item().id) == |
| 157 extensions::LAUNCH_TYPE_PINNED; |
| 158 case LAUNCH_TYPE_REGULAR_TAB: |
| 159 return controller()->GetLaunchType(item().id) == |
| 160 extensions::LAUNCH_TYPE_REGULAR; |
| 161 case LAUNCH_TYPE_WINDOW: |
| 162 return controller()->GetLaunchType(item().id) == |
| 163 extensions::LAUNCH_TYPE_WINDOW; |
| 164 case LAUNCH_TYPE_FULLSCREEN: |
| 165 return controller()->GetLaunchType(item().id) == |
| 166 extensions::LAUNCH_TYPE_FULLSCREEN; |
| 167 case MENU_AUTO_HIDE: |
| 168 return shelf()->GetAutoHideBehavior() == |
| 169 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; |
| 170 default: |
| 171 if (command_id < MENU_ITEM_COUNT) |
| 172 return false; |
| 173 return (extension_items_ && |
| 174 extension_items_->IsCommandIdChecked(command_id)); |
| 175 } |
| 176 } |
| 177 |
| 178 bool ExtensionLauncherContextMenu::IsCommandIdEnabled(int command_id) const { |
| 179 switch (command_id) { |
| 180 case MENU_PIN: |
| 181 return controller()->IsPinnable(item().id); |
| 182 case MENU_CHANGE_WALLPAPER: |
| 183 return ash::Shell::GetInstance() |
| 184 ->user_wallpaper_delegate() |
| 185 ->CanOpenSetWallpaperPage(); |
| 186 case MENU_NEW_WINDOW: |
| 187 // "Normal" windows are not allowed when incognito is enforced. |
| 188 return IncognitoModePrefs::GetAvailability( |
| 189 controller()->profile()->GetPrefs()) != |
| 190 IncognitoModePrefs::FORCED; |
| 191 case MENU_AUTO_HIDE: |
| 192 return CanUserModifyShelfAutoHideBehavior(); |
| 193 case MENU_NEW_INCOGNITO_WINDOW: |
| 194 // Incognito windows are not allowed when incognito is disabled. |
| 195 return IncognitoModePrefs::GetAvailability( |
| 196 controller()->profile()->GetPrefs()) != |
| 197 IncognitoModePrefs::DISABLED; |
| 198 default: |
| 199 if (command_id < MENU_ITEM_COUNT) |
| 200 return true; |
| 201 return (extension_items_ && |
| 202 extension_items_->IsCommandIdEnabled(command_id)); |
| 203 } |
| 204 } |
| 205 |
| 206 void ExtensionLauncherContextMenu::ExecuteCommand(int command_id, |
| 207 int event_flags) { |
| 208 switch (static_cast<MenuItem>(command_id)) { |
| 209 case MENU_OPEN_NEW: |
| 210 controller()->Launch(item().id, ui::EF_NONE); |
| 211 break; |
| 212 case MENU_CLOSE: |
| 213 if (item().type == ash::TYPE_DIALOG) { |
| 214 ash::ShelfItemDelegate* item_delegate = |
| 215 ash::Shell::GetInstance() |
| 216 ->shelf_item_delegate_manager() |
| 217 ->GetShelfItemDelegate(item().id); |
| 218 DCHECK(item_delegate); |
| 219 item_delegate->Close(); |
| 220 } else { |
| 221 // TODO(simonhong): Use ShelfItemDelegate::Close(). |
| 222 controller()->Close(item().id); |
| 223 } |
| 224 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction( |
| 225 ash::UMA_CLOSE_THROUGH_CONTEXT_MENU); |
| 226 break; |
| 227 case MENU_PIN: |
| 228 controller()->TogglePinned(item().id); |
| 229 break; |
| 230 case LAUNCH_TYPE_PINNED_TAB: |
| 231 controller()->SetLaunchType(item().id, extensions::LAUNCH_TYPE_PINNED); |
| 232 break; |
| 233 case LAUNCH_TYPE_REGULAR_TAB: |
| 234 controller()->SetLaunchType(item().id, extensions::LAUNCH_TYPE_REGULAR); |
| 235 break; |
| 236 case LAUNCH_TYPE_WINDOW: { |
| 237 extensions::LaunchType launch_type = extensions::LAUNCH_TYPE_WINDOW; |
| 238 // With bookmark apps enabled, hosted apps can only toggle between |
| 239 // LAUNCH_WINDOW and LAUNCH_REGULAR. |
| 240 if (extensions::util::IsNewBookmarkAppsEnabled()) { |
| 241 launch_type = controller()->GetLaunchType(item().id) == |
| 242 extensions::LAUNCH_TYPE_WINDOW |
| 243 ? extensions::LAUNCH_TYPE_REGULAR |
| 244 : extensions::LAUNCH_TYPE_WINDOW; |
| 245 } |
| 246 controller()->SetLaunchType(item().id, launch_type); |
| 247 break; |
| 248 } |
| 249 case LAUNCH_TYPE_FULLSCREEN: |
| 250 controller()->SetLaunchType(item().id, |
| 251 extensions::LAUNCH_TYPE_FULLSCREEN); |
| 252 break; |
| 253 case MENU_AUTO_HIDE: |
| 254 shelf()->SetAutoHideBehavior(shelf()->GetAutoHideBehavior() == |
| 255 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS |
| 256 ? ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER |
| 257 : ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); |
| 258 break; |
| 259 case MENU_NEW_WINDOW: |
| 260 controller()->CreateNewWindow(); |
| 261 break; |
| 262 case MENU_NEW_INCOGNITO_WINDOW: |
| 263 controller()->CreateNewIncognitoWindow(); |
| 264 break; |
| 265 case MENU_ALIGNMENT_MENU: |
| 266 break; |
| 267 case MENU_CHANGE_WALLPAPER: |
| 268 ash::Shell::GetInstance() |
| 269 ->user_wallpaper_delegate() |
| 270 ->OpenSetWallpaperPage(); |
| 271 break; |
| 272 default: |
| 273 if (extension_items_) { |
| 274 extension_items_->ExecuteCommand(command_id, nullptr, nullptr, |
| 275 content::ContextMenuParams()); |
| 276 } |
| 277 } |
| 278 } |
| OLD | NEW |