Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / profiles / user_manager_mac.mm
1 // Copyright 2014 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/cocoa/profiles/user_manager_mac.h"
6
7 #include "base/mac/foundation_util.h"
8 #include "chrome/app/chrome_command_ids.h"
9 #import "chrome/browser/app_controller_mac.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "chrome/browser/profiles/profiles_state.h"
13 #include "chrome/browser/ui/browser_dialogs.h"
14 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
15 #include "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
16 #include "chrome/browser/ui/user_manager.h"
17 #include "chrome/grit/chromium_strings.h"
18 #include "content/public/browser/native_web_keyboard_event.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_delegate.h"
21 #include "ui/base/l10n/l10n_util_mac.h"
22 #include "ui/events/keycodes/keyboard_codes.h"
23
24
25 // An open User Manager window. There can only be one open at a time. This
26 // is reset to NULL when the window is closed.
27 UserManagerMac* instance_ = NULL;  // Weak.
28
29 // Custom WebContentsDelegate that allows handling of hotkeys.
30 class UserManagerWebContentsDelegate : public content::WebContentsDelegate {
31  public:
32   UserManagerWebContentsDelegate() {}
33
34   // WebContentsDelegate implementation. Forwards all unhandled keyboard events
35   // to the current window.
36   virtual void HandleKeyboardEvent(
37       content::WebContents* source,
38       const content::NativeWebKeyboardEvent& event) OVERRIDE {
39     if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
40       return;
41
42     // -getCommandId returns -1 if the event isn't a chrome accelerator.
43     int chromeCommandId = [BrowserWindowUtils getCommandId:event];
44
45     // Check for Cmd+A and Cmd+V events that could come from a password field.
46     bool isTextEditingCommand =
47         (event.modifiers & blink::WebInputEvent::MetaKey) &&
48         (event.windowsKeyCode == ui::VKEY_A ||
49          event.windowsKeyCode == ui::VKEY_V);
50
51     // Only handle close window Chrome accelerators and text editing ones.
52     if (chromeCommandId == IDC_CLOSE_WINDOW || chromeCommandId == IDC_EXIT ||
53         isTextEditingCommand) {
54       [[NSApp mainMenu] performKeyEquivalent:event.os_event];
55     }
56   }
57 };
58
59 // Window controller for the User Manager view.
60 @interface UserManagerWindowController : NSWindowController <NSWindowDelegate> {
61  @private
62   scoped_ptr<content::WebContents> webContents_;
63   scoped_ptr<UserManagerWebContentsDelegate> webContentsDelegate_;
64   UserManagerMac* userManagerObserver_;  // Weak.
65 }
66 - (void)windowWillClose:(NSNotification*)notification;
67 - (void)dealloc;
68 - (id)initWithProfile:(Profile*)profile
69          withObserver:(UserManagerMac*)userManagerObserver;
70 - (void)showURL:(const GURL&)url;
71 - (void)show;
72 - (void)close;
73 - (BOOL)isVisible;
74 @end
75
76 @implementation UserManagerWindowController
77
78 - (id)initWithProfile:(Profile*)profile
79          withObserver:(UserManagerMac*)userManagerObserver {
80
81   // Center the window on the screen that currently has focus.
82   NSScreen* mainScreen = [NSScreen mainScreen];
83   CGFloat screenHeight = [mainScreen frame].size.height;
84   CGFloat screenWidth = [mainScreen frame].size.width;
85
86   NSRect contentRect =
87       NSMakeRect((screenWidth - UserManager::kWindowWidth) / 2,
88                  (screenHeight - UserManager::kWindowHeight) / 2,
89                  UserManager::kWindowWidth, UserManager::kWindowHeight);
90   ChromeEventProcessingWindow* window = [[ChromeEventProcessingWindow alloc]
91       initWithContentRect:contentRect
92                 styleMask:NSTitledWindowMask |
93                           NSClosableWindowMask |
94                           NSResizableWindowMask
95                   backing:NSBackingStoreBuffered
96                     defer:NO
97                    screen:mainScreen];
98   [window setTitle:l10n_util::GetNSString(IDS_PRODUCT_NAME)];
99   [window setMinSize:NSMakeSize(UserManager::kWindowWidth,
100                                 UserManager::kWindowHeight)];
101
102   if ((self = [super initWithWindow:window])) {
103     userManagerObserver_ = userManagerObserver;
104
105     // Initialize the web view.
106     webContents_.reset(content::WebContents::Create(
107         content::WebContents::CreateParams(profile)));
108     window.contentView = webContents_->GetNativeView();
109     webContentsDelegate_.reset(new UserManagerWebContentsDelegate());
110     webContents_->SetDelegate(webContentsDelegate_.get());
111     DCHECK(window.contentView);
112
113     [[NSNotificationCenter defaultCenter]
114         addObserver:self
115            selector:@selector(windowWillClose:)
116                name:NSWindowWillCloseNotification
117              object:self.window];
118   }
119   return self;
120 }
121
122 - (void)dealloc {
123   [[NSNotificationCenter defaultCenter] removeObserver:self];
124   [super dealloc];
125 }
126
127 - (void)showURL:(const GURL&)url {
128   webContents_->GetController().LoadURL(url, content::Referrer(),
129                                         ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
130                                         std::string());
131   [self show];
132 }
133
134 - (void)show {
135   // Because the User Manager isn't a BrowserWindowController, activating it
136   // will not trigger a -windowChangedToProfile and update the menu bar.
137   // This is only important if the active profile is Guest, which may have
138   // happened after locking a profile.
139   Profile* guestProfile = profiles::SetActiveProfileToGuestIfLocked();
140   if (guestProfile && guestProfile->IsGuestSession()) {
141     AppController* controller =
142         base::mac::ObjCCast<AppController>([NSApp delegate]);
143     [controller windowChangedToProfile:guestProfile];
144   }
145   [[self window] makeKeyAndOrderFront:self];
146 }
147
148 - (void)close {
149   [[self window] close];
150 }
151
152 -(BOOL)isVisible {
153   return [[self window] isVisible];
154 }
155
156 - (void)windowWillClose:(NSNotification*)notification {
157   [[NSNotificationCenter defaultCenter] removeObserver:self];
158   DCHECK(userManagerObserver_);
159   userManagerObserver_->WindowWasClosed();
160 }
161
162 @end
163
164
165 void UserManager::Show(
166     const base::FilePath& profile_path_to_focus,
167     profiles::UserManagerTutorialMode tutorial_mode,
168     profiles::UserManagerProfileSelected profile_open_action) {
169   ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::OPEN_USER_MANAGER);
170   if (instance_) {
171     // If there's a user manager window open already, just activate it.
172     [instance_->window_controller() show];
173     return;
174   }
175
176   // Create the guest profile, if necessary, and open the User Manager
177   // from the guest profile.
178   profiles::CreateGuestProfileForUserManager(
179       profile_path_to_focus,
180       tutorial_mode,
181       profile_open_action,
182       base::Bind(&UserManagerMac::OnGuestProfileCreated));
183 }
184
185 void UserManager::Hide() {
186   if (instance_)
187     [instance_->window_controller() close];
188 }
189
190 bool UserManager::IsShowing() {
191   return instance_ ? [instance_->window_controller() isVisible]: false;
192 }
193
194 UserManagerMac::UserManagerMac(Profile* profile) {
195   window_controller_.reset([[UserManagerWindowController alloc]
196       initWithProfile:profile withObserver:this]);
197 }
198
199 UserManagerMac::~UserManagerMac() {
200 }
201
202 // static
203 void UserManagerMac::OnGuestProfileCreated(Profile* guest_profile,
204                                            const std::string& url) {
205   DCHECK(!instance_);
206   instance_ = new UserManagerMac(guest_profile);
207   [instance_->window_controller() showURL:GURL(url)];
208 }
209
210 void UserManagerMac::WindowWasClosed() {
211   instance_ = NULL;
212   delete this;
213 }