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