Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / passwords / manage_passwords_bubble_cocoa.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 #import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_cocoa.h"
6
7 #include "base/mac/scoped_block.h"
8 #include "chrome/browser/ui/browser_dialogs.h"
9 #include "chrome/browser/ui/browser_finder.h"
10 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
11 #include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
12 #include "chrome/browser/ui/cocoa/location_bar/manage_passwords_decoration.h"
13 #import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.h"
14 #include "chrome/browser/ui/passwords/manage_passwords_icon.h"
15 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
16 #include "content/public/browser/web_contents.h"
17
18 typedef void (^Callback)(void);
19
20 @interface ManagePasswordsBubbleCocoaNotificationBridge : NSObject {
21   base::mac::ScopedBlock<Callback> callback_;
22 }
23 - (id)initWithCallback:(Callback)callback;
24 - (void)onClose;
25 @end
26
27 @implementation ManagePasswordsBubbleCocoaNotificationBridge
28 - (id)initWithCallback:(Callback)callback {
29   if ((self = [super init])) {
30     callback_.reset(callback, base::scoped_policy::RETAIN);
31   }
32   return self;
33 }
34 - (void)onClose {
35   callback_.get()();
36 }
37 @end
38
39 // static
40 ManagePasswordsBubbleCocoa* ManagePasswordsBubbleCocoa::bubble_ = NULL;
41
42 namespace chrome {
43 void ShowManagePasswordsBubble(content::WebContents* webContents) {
44   ManagePasswordsBubbleCocoa* instance = ManagePasswordsBubbleCocoa::instance();
45   if (instance && (instance->webContents_ != webContents)) {
46     // The bubble is currently shown for some other tab. We should close it now
47     // and open for |webContents|.
48     instance->Close();
49   }
50
51   ManagePasswordsUIController* controller =
52       ManagePasswordsUIController::FromWebContents(webContents);
53   NSWindow* window = webContents->GetTopLevelNativeWindow();
54   if (!window) {
55     // The tab isn't active right now.
56     return;
57   }
58   BrowserWindowController* bwc =
59       [BrowserWindowController browserWindowControllerForWindow:window];
60   ManagePasswordsBubbleCocoa::ShowBubble(
61       webContents,
62       password_manager::ui::IsAutomaticDisplayState(controller->state())
63           ? ManagePasswordsBubble::AUTOMATIC
64           : ManagePasswordsBubble::USER_ACTION,
65       [bwc locationBarBridge]->manage_passwords_decoration()->icon());
66 }
67
68 void CloseManagePasswordsBubble(content::WebContents* web_contents) {
69   // The bubble is closed when it loses the focus.
70 }
71 }  // namespace chrome
72
73 ManagePasswordsBubbleCocoa::ManagePasswordsBubbleCocoa(
74     content::WebContents* webContents,
75     DisplayReason displayReason,
76     ManagePasswordsIcon* icon)
77     : ManagePasswordsBubble(webContents, displayReason),
78       icon_(icon),
79       closing_(false),
80       controller_(nil),
81       webContents_(webContents),
82       bridge_(nil) {
83   DCHECK(icon_);
84   icon_->SetActive(true);
85 }
86
87 ManagePasswordsBubbleCocoa::~ManagePasswordsBubbleCocoa() {
88   [[NSNotificationCenter defaultCenter] removeObserver:bridge_];
89   // Clear the global instance pointer.
90   bubble_ = NULL;
91   if (icon_)
92     icon_->SetActive(false);
93 }
94
95 void ManagePasswordsBubbleCocoa::Show() {
96   // Create and show the bubble.
97   NSView* browserView = webContents_->GetNativeView();
98   DCHECK(browserView);
99   NSWindow* browserWindow = [browserView window];
100   DCHECK(browserWindow);
101   controller_ = [[ManagePasswordsBubbleController alloc]
102       initWithParentWindow:browserWindow
103                      model:model()];
104   [controller_ showWindow:nil];
105
106   // Listen for close notification to perform cleanup: the window isn't
107   // necessarily closed by calling Close(). Use a block instead of directly
108   // calling OnClose from the bridge so that we don't need to expose OnClose
109   // in the public API of ManagePasswordsBubbleCocoa.
110   bridge_.reset([[ManagePasswordsBubbleCocoaNotificationBridge alloc]
111       initWithCallback:^{
112           OnClose();
113       }]);
114   [[NSNotificationCenter defaultCenter]
115       addObserver:bridge_
116          selector:@selector(onClose)
117              name:NSWindowWillCloseNotification
118            object:[controller_ window]];
119 }
120
121 void ManagePasswordsBubbleCocoa::Close() {
122   if (!closing_) {
123     closing_ = true;
124     [controller_ close];
125   }
126 }
127
128 void ManagePasswordsBubbleCocoa::OnClose() {
129   delete this;
130 }
131
132 // static
133 void ManagePasswordsBubbleCocoa::ShowBubble(content::WebContents* webContents,
134                                             DisplayReason displayReason,
135                                             ManagePasswordsIcon* icon) {
136   if (bubble_)
137     return;
138   bubble_ = new ManagePasswordsBubbleCocoa(webContents, displayReason, icon);
139   bubble_->Show();
140 }