1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/multi_profile_uma.h" 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/session_state_delegate.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shell.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/prefs/pref_service.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_warning_dialog.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/pref_names.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user.h" 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window.h" 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/models/simple_menu_model.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chromeos { 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace { 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MultiUserContextMenuChromeos : public ui::SimpleMenuModel, 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public ui::SimpleMenuModel::Delegate { 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) explicit MultiUserContextMenuChromeos(aura::Window* window); 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~MultiUserContextMenuChromeos() {} 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // SimpleMenuModel::Delegate: 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool GetAcceleratorForCommandId( 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int command_id, 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::Accelerator* accelerator) OVERRIDE { 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The window for which this menu is. 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* window_; 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MultiUserContextMenuChromeos); 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MultiUserContextMenuChromeos::MultiUserContextMenuChromeos(aura::Window* window) 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : ui::SimpleMenuModel(this), 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_(window) { 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MultiUserContextMenuChromeos::ExecuteCommand(int command_id, 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int event_flags) { 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExecuteVisitDesktopCommand(command_id, window_); 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace chromeos 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<ui::MenuModel> CreateMultiUserContextMenu(aura::Window* window) { 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ui::MenuModel> model; 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::SessionStateDelegate* delegate = 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::Shell::GetInstance()->session_state_delegate(); 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!delegate) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return model.Pass(); 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int logged_in_users = delegate->NumberOfLoggedInUsers(); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (logged_in_users > 1) { 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If this window is not owned, we don't show the menu addition. 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::MultiUserWindowManager* manager = 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::MultiUserWindowManager::GetInstance(); 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string user_id = manager->GetWindowOwner(window); 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (user_id.empty() || !window) 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return model.Pass(); 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chromeos::MultiUserContextMenuChromeos* menu = 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new chromeos::MultiUserContextMenuChromeos(window); 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model.reset(menu); 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (int user_index = 1; user_index < logged_in_users; ++user_index) { 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const user_manager::UserInfo* user_info = 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delegate->GetUserInfo(user_index); 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu menu->AddItem(user_index == 1 ? IDC_VISIT_DESKTOP_OF_LRU_USER_2 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : IDC_VISIT_DESKTOP_OF_LRU_USER_3, 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu l10n_util::GetStringFUTF16( 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu IDS_VISIT_DESKTOP_OF_LRU_USER, 965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu user_info->GetDisplayName(), 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::ASCIIToUTF16(user_info->GetEmail()))); 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return model.Pass(); 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OnAcceptTeleportWarning( 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string user_id, aura::Window* window_, bool no_show_again) { 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefService* pref = ProfileManager::GetActiveUserProfile()->GetPrefs(); 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref->SetBoolean(prefs::kMultiProfileWarningShowDismissed, no_show_again); 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::MultiProfileUMA::RecordTeleportAction( 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::MultiProfileUMA::TELEPORT_WINDOW_CAPTION_MENU); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(window_, 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_id); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExecuteVisitDesktopCommand(int command_id, aura::Window* window) { 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (command_id) { 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_VISIT_DESKTOP_OF_LRU_USER_2: 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_VISIT_DESKTOP_OF_LRU_USER_3: { 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // When running the multi user mode on Chrome OS, windows can "visit" 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // another user's desktop. 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& user_id = 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ash::Shell::GetInstance() 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ->session_state_delegate() 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ->GetUserInfo(IDC_VISIT_DESKTOP_OF_LRU_USER_2 == command_id ? 1 1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : 2) 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ->GetUserID(); 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Callback<void(bool)> on_accept = 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&OnAcceptTeleportWarning, user_id, window); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Don't show warning dialog if any logged in user in multi-profiles 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // session dismissed it. 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const user_manager::UserList logged_in_users = 1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) user_manager::UserManager::Get()->GetLoggedInUsers(); 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (user_manager::UserList::const_iterator it = logged_in_users.begin(); 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) it != logged_in_users.end(); 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ++it) { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (multi_user_util::GetProfileFromUserID( 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) multi_user_util::GetUserIDFromEmail((*it)->email()))->GetPrefs()-> 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetBoolean(prefs::kMultiProfileWarningShowDismissed)) { 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool active_user_show_option = 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProfileManager::GetActiveUserProfile()-> 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetPrefs()->GetBoolean(prefs::kMultiProfileWarningShowDismissed); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) on_accept.Run(active_user_show_option); 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chromeos::ShowMultiprofilesWarningDialog(on_accept); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 154