Chromium Code Reviews| Index: chrome/browser/ui/cocoa/user_manager_mac.mm |
| diff --git a/chrome/browser/ui/cocoa/user_manager_mac.mm b/chrome/browser/ui/cocoa/user_manager_mac.mm |
| index 07818f33ff8d69615ef679d3fb33e91002e72208..8b7c4e3e39630d0e1e528ad2084eda223751812c 100644 |
| --- a/chrome/browser/ui/cocoa/user_manager_mac.mm |
| +++ b/chrome/browser/ui/cocoa/user_manager_mac.mm |
| @@ -2,20 +2,188 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#import <Cocoa/Cocoa.h> |
| +#include "chrome/browser/ui/cocoa/user_manager_mac.h" |
| +#include "base/strings/string_number_conversions.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/ui/browser_dialogs.h" |
| +#include "chrome/common/url_constants.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "content/public/browser/web_contents_view.h" |
| +#include "grit/generated_resources.h" |
| +#include "ui/base/l10n/l10n_util_mac.h" |
| + |
| +namespace { |
| + |
| +// Default window size. Taken from the views implementation in |
| +// chrome/browser/ui/views/user_manager_view.cc. |
| +const int kWindowWidth = 900; |
|
groby-ooo-7-16
2013/12/10 00:41:06
I'd leave at least a TODO to adjust to smaller scr
noms (inactive)
2013/12/10 15:41:35
Done.
|
| +const int kWindowHeight = 700; |
| + |
| +} // namespace |
| namespace chrome { |
| // Declared in browser_dialogs.h so others don't have to depend on this header. |
| -// TODO(noms): Add implementation when the User Manager dialog is implemented. |
| void ShowUserManager(const base::FilePath& profile_path_to_focus) { |
| - NOTIMPLEMENTED(); |
| + UserManagerMac::Show(profile_path_to_focus); |
| } |
| void HideUserManager() { |
| - NOTIMPLEMENTED(); |
| + UserManagerMac::Hide(); |
| } |
| } // namespace chrome |
| + |
| +@interface UserManagerWindowController (Private) |
| +- (void)windowWillClose:(NSNotification*)notification; |
| +- (void)dealloc; |
| +@end |
| + |
| +@implementation UserManagerWindowController |
| + |
| +- (id)initWithProfile:(Profile*)profile |
| + withObserver:(UserManagerMac*)userManagerObserver { |
| + |
| + // Center the window on the primary screen. |
|
groby-ooo-7-16
2013/12/10 00:41:06
What do you mean by "primary" screen? The one with
noms (inactive)
2013/12/10 15:41:35
The reference says primary means the one that cont
|
| + CGFloat screenHeight = |
| + [[[NSScreen screens] objectAtIndex:0] frame].size.height; |
| + CGFloat screenWidth = |
| + [[[NSScreen screens] objectAtIndex:0] frame].size.width; |
| + |
| + NSRect contentRect = NSMakeRect((screenWidth - kWindowWidth) / 2, |
| + (screenHeight - kWindowHeight) / 2, |
| + kWindowWidth, kWindowHeight); |
| + |
| + userManagerObserver_ = userManagerObserver; |
| + NSWindow* window = [[NSWindow alloc] |
| + initWithContentRect:contentRect |
| + styleMask:NSTitledWindowMask | |
| + NSClosableWindowMask | |
| + NSResizableWindowMask |
| + backing:NSBackingStoreBuffered |
| + defer:NO]; |
| + [window setTitle:l10n_util::GetNSString(IDS_USER_MANAGER_SCREEN_TITLE)]; |
| + |
| + // Initialize the web view. |
| + webContents_.reset(content::WebContents::Create( |
| + content::WebContents::CreateParams(profile))); |
| + window.contentView = webContents_->GetView()->GetNativeView(); |
| + DCHECK(window.contentView); |
| + |
| + // Initialize, but don't show the window until the web contents have loaded. |
| + self = [super initWithWindow:window]; |
| + |
| + [[NSNotificationCenter defaultCenter] addObserver:self |
| + selector:@selector(windowWillClose:) |
| + name:NSWindowWillCloseNotification |
| + object:self.window]; |
| + return self; |
| +} |
| + |
| +- (void)dealloc { |
| + [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| + [super dealloc]; |
| +} |
| + |
| +- (void)showURL:(GURL)url { |
| + webContents_->GetController().LoadURL(url, content::Referrer(), |
| + content::PAGE_TRANSITION_AUTO_TOPLEVEL, |
| + std::string()); |
| + [self show]; |
| +} |
| + |
| +- (void)show { |
| + [[self window] makeKeyAndOrderFront:self]; |
| +} |
| + |
| +- (void)close { |
| + [[self window] close]; |
| +} |
| + |
| +-(BOOL)isVisible { |
| + return [[self window] isVisible]; |
| +} |
| + |
| +- (void)windowWillClose:(NSNotification*)notification { |
| + [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| + |
| + // Reset the web contents so that the guest profile doesn't have any |
| + // renderer hosts, so that the profile can be destroyed cleanly in case the |
| + // process is force-killed. |
|
groby-ooo-7-16
2013/12/10 00:41:06
I still don't understand the reference to force-ki
noms (inactive)
2013/12/10 15:41:35
I meant when you Ctrl-C the process in a terminal.
|
| + webContents_.reset(); |
|
groby-ooo-7-16
2013/12/10 00:41:06
Do you still need the reset? Doesn't the observer
noms (inactive)
2013/12/10 15:41:35
Done.
|
| + |
| + if (userManagerObserver_) { |
|
groby-ooo-7-16
2013/12/10 00:41:06
Just DCHECK the observer - should never be NULL.
noms (inactive)
2013/12/10 15:41:35
Done.
|
| + userManagerObserver_->WindowWasClosed(); |
| + userManagerObserver_ = nil; |
|
groby-ooo-7-16
2013/12/10 00:41:06
There's a tiny potential for conflict here - Windo
noms (inactive)
2013/12/10 15:41:35
Done.
|
| + } |
| +} |
| + |
| +@end |
| + |
| +// static |
| +UserManagerMac* UserManagerMac::instance_ = NULL; |
| + |
| +UserManagerMac::UserManagerMac(Profile* profile) { |
| + window_controller_.reset([[UserManagerWindowController alloc] |
| + initWithProfile:profile withObserver:this]); |
| +} |
| + |
| +UserManagerMac::~UserManagerMac() { |
| +} |
| + |
| +// static |
| +void UserManagerMac::Show(const base::FilePath& profile_path_to_focus) { |
| + if (instance_) { |
| + [instance_->window_controller_ show]; |
| + return; |
| + } |
| + |
| + // Create the guest profile, if necessary, and open the User Manager |
| + // from the guest profile. |
| + ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| + profile_manager->CreateProfileAsync( |
| + ProfileManager::GetGuestProfilePath(), |
| + base::Bind(&UserManagerMac::OnGuestProfileCreated, |
| + profile_path_to_focus), |
| + string16(), |
| + string16(), |
| + std::string()); |
| +} |
| + |
| +// static |
| +void UserManagerMac::Hide() { |
| + if (instance_) |
| + [instance_->window_controller_ close]; |
| +} |
| + |
| +void UserManagerMac::WindowWasClosed() { |
| + delete this; |
| + instance_ = NULL; |
|
groby-ooo-7-16
2013/12/10 00:41:06
instance_ is technically already freed memory - do
noms (inactive)
2013/12/10 15:41:35
Hmm, instance is static. Freeing the 'this' object
|
| +} |
| + |
| +void UserManagerMac::OnGuestProfileCreated( |
| + const base::FilePath& profile_path_to_focus, |
| + Profile* guest_profile, |
| + Profile::CreateStatus status) { |
| + if (status != Profile::CREATE_STATUS_INITIALIZED) |
| + return; |
| + |
| + instance_ = new UserManagerMac(guest_profile); |
| + |
| + // Tell the webui which user pod should be focused. |
| + std::string page = chrome::kChromeUIUserManagerURL; |
| + |
| + if (!profile_path_to_focus.empty()) { |
| + ProfileInfoCache& cache = |
| + g_browser_process->profile_manager()->GetProfileInfoCache(); |
| + size_t index = cache.GetIndexOfProfileWithPath(profile_path_to_focus); |
| + if (index != std::string::npos) { |
| + page += "#"; |
| + page += base::IntToString(index); |
| + } |
| + } |
| + [instance_->window_controller_ showURL:GURL(page)]; |
| +} |
| + |