12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/frame/system_menu_model_builder.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/toolbar/wrench_menu_model.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/accelerators/accelerator.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/models/simple_menu_model.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_CHROMEOS)
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/session_state_delegate.h"
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ash/shell.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/user_manager/user_info.h"
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SystemMenuModelBuilder::SystemMenuModelBuilder(
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::AcceleratorProvider* provider,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Browser* browser)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : menu_delegate_(provider, browser) {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SystemMenuModelBuilder::~SystemMenuModelBuilder() {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::Init() {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::SimpleMenuModel* model = new ui::SimpleMenuModel(&menu_delegate_);
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  menu_model_.reset(model);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BuildMenu(model);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On Windows with HOST_DESKTOP_TYPE_NATIVE we put the menu items in the
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // system menu (not at the end). Doing this necessitates adding a trailing
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // separator.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (browser()->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model->AddSeparator(ui::NORMAL_SEPARATOR);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::BuildMenu(ui::SimpleMenuModel* model) {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We add the menu items in reverse order so that insertion_index never needs
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to change.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (browser()->is_type_tabbed())
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BuildSystemMenuForBrowserWindow(model);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BuildSystemMenuForAppOrPopupWindow(model);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddFrameToggleItems(model);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::BuildSystemMenuForBrowserWindow(
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::SimpleMenuModel* model) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (chrome::CanOpenTaskManager()) {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model->AddSeparator(ui::NORMAL_SEPARATOR);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  model->AddSeparator(ui::NORMAL_SEPARATOR);
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  model->AddCheckItemWithStringId(IDC_USE_SYSTEM_TITLE_BAR,
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  IDS_SHOW_WINDOW_DECORATIONS_MENU);
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AppendTeleportMenu(model);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If it's a regular browser window with tabs, we don't add any more items,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // since it already has menus (Page, Chrome).
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::BuildSystemMenuForAppOrPopupWindow(
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::SimpleMenuModel* model) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddSeparator(ui::NORMAL_SEPARATOR);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (browser()->is_app())
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model->AddItemWithStringId(IDC_NEW_TAB, IDS_APP_MENU_NEW_WEB_PAGE);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model->AddItemWithStringId(IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddSeparator(ui::NORMAL_SEPARATOR);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_CUT, IDS_CUT);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_COPY, IDS_COPY);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_PASTE, IDS_PASTE);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddSeparator(ui::NORMAL_SEPARATOR);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_FIND, IDS_FIND);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddItemWithStringId(IDC_PRINT, IDS_PRINT);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  zoom_menu_contents_.reset(new ZoomMenuModel(&menu_delegate_));
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                zoom_menu_contents_.get());
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  encoding_menu_contents_.reset(new EncodingMenuModel(browser()));
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  model->AddSubMenuWithStringId(IDC_ENCODING_MENU,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                IDS_ENCODING_MENU,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                encoding_menu_contents_.get());
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (browser()->is_app() && chrome::CanOpenTaskManager()) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model->AddSeparator(ui::NORMAL_SEPARATOR);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  model->AddSeparator(ui::NORMAL_SEPARATOR);
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  model->AddItemWithStringId(IDC_CLOSE_WINDOW, IDS_CLOSE);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AppendTeleportMenu(model);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::AddFrameToggleItems(ui::SimpleMenuModel* model) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          switches::kDebugEnableFrameToggle)) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model->AddSeparator(ui::NORMAL_SEPARATOR);
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    model->AddItem(IDC_DEBUG_FRAME_TOGGLE,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::ASCIIToUTF16("Toggle Frame Type"));
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SystemMenuModelBuilder::AppendTeleportMenu(ui::SimpleMenuModel* model) {
1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_CHROMEOS)
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(browser()->window());
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // If there is no manager, we are not in the proper multi user mode.
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Don't show the menu for incognito windows.
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (browser()->profile()->IsOffTheRecord())
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // To show the menu we need at least two logged in users.
1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ash::SessionStateDelegate* delegate =
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ash::Shell::GetInstance()->session_state_delegate();
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int logged_in_users = delegate->NumberOfLoggedInUsers();
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (logged_in_users <= 1)
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // If this does not belong to a profile or there is no window, or the window
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // is not owned by anyone, we don't show the menu addition.
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chrome::MultiUserWindowManager* manager =
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      chrome::MultiUserWindowManager::GetInstance();
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const std::string user_id =
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      multi_user_util::GetUserIDFromProfile(browser()->profile());
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  aura::Window* window = browser()->window()->GetNativeWindow();
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (user_id.empty() || !window || manager->GetWindowOwner(window).empty())
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  model->AddSeparator(ui::NORMAL_SEPARATOR);
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(logged_in_users <= 3);
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (int user_index = 1; user_index < logged_in_users; ++user_index) {
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const user_manager::UserInfo* user_info = delegate->GetUserInfo(user_index);
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    model->AddItem(
1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        user_index == 1 ? IDC_VISIT_DESKTOP_OF_LRU_USER_2
1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                        : IDC_VISIT_DESKTOP_OF_LRU_USER_3,
1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        l10n_util::GetStringFUTF16(IDS_VISIT_DESKTOP_OF_LRU_USER,
1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   user_info->GetDisplayName(),
1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   base::ASCIIToUTF16(user_info->GetEmail())));
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
165