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