| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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/views/aura/panel_view_aura.h" | |
| 6 | |
| 7 #include "ash/wm/panel_frame_view.h" | |
| 8 #include "base/utf_string_conversions.h" | |
| 9 #include "chrome/browser/extensions/extension_function_dispatcher.h" | |
| 10 #include "chrome/browser/extensions/extension_tab_util.h" | |
| 11 #include "chrome/browser/extensions/extension_tabs_module_constants.h" | |
| 12 #include "chrome/browser/extensions/extension_window_controller.h" | |
| 13 #include "chrome/browser/extensions/extension_window_list.h" | |
| 14 #include "chrome/browser/profiles/profile.h" | |
| 15 #include "chrome/browser/ui/browser.h" | |
| 16 #include "chrome/browser/ui/browser_list.h" | |
| 17 #include "chrome/common/chrome_view_type.h" | |
| 18 #include "chrome/common/extensions/extension_messages.h" | |
| 19 #include "content/public/browser/site_instance.h" | |
| 20 #include "content/public/browser/web_contents.h" | |
| 21 #include "content/public/browser/web_contents_delegate.h" | |
| 22 #include "content/public/browser/web_contents_observer.h" | |
| 23 #include "googleurl/src/gurl.h" | |
| 24 #include "ipc/ipc_message.h" | |
| 25 #include "ipc/ipc_message_macros.h" | |
| 26 #include "ui/aura/window.h" | |
| 27 #include "ui/views/widget/widget.h" | |
| 28 | |
| 29 namespace { | |
| 30 const int kMinWidth = 100; | |
| 31 const int kMinHeight = 100; | |
| 32 const int kDefaultWidth = 200; | |
| 33 const int kDefaultHeight = 300; | |
| 34 } | |
| 35 | |
| 36 namespace internal { | |
| 37 | |
| 38 //////////////////////////////////////////////////////////////////////////////// | |
| 39 // PanelHost | |
| 40 | |
| 41 class PanelHost : public content::WebContentsDelegate, | |
| 42 public content::WebContentsObserver, | |
| 43 public ExtensionFunctionDispatcher::Delegate { | |
| 44 public: | |
| 45 PanelHost(PanelViewAura* panel_view, Profile* profile); | |
| 46 virtual ~PanelHost(); | |
| 47 | |
| 48 void Init(const GURL& url); | |
| 49 | |
| 50 content::WebContents* web_contents() const { return web_contents_.get(); } | |
| 51 Profile* profile() const { return profile_; } | |
| 52 | |
| 53 // ExtensionFunctionDispatcher::Delegate overrides. | |
| 54 virtual Browser* GetBrowser() OVERRIDE; | |
| 55 virtual content::WebContents* GetAssociatedWebContents() const OVERRIDE; | |
| 56 | |
| 57 // content::WebContentsDelegate implementation: | |
| 58 virtual void CloseContents(content::WebContents* source) OVERRIDE; | |
| 59 virtual void HandleMouseDown() OVERRIDE; | |
| 60 virtual void UpdatePreferredSize(content::WebContents* source, | |
| 61 const gfx::Size& pref_size) OVERRIDE; | |
| 62 virtual void AddNewContents(content::WebContents* source, | |
| 63 content::WebContents* new_contents, | |
| 64 WindowOpenDisposition disposition, | |
| 65 const gfx::Rect& initial_pos, | |
| 66 bool user_gesture) OVERRIDE; | |
| 67 | |
| 68 // content::WebContentsObserver implementation: | |
| 69 virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; | |
| 70 virtual void RenderViewReady() OVERRIDE; | |
| 71 virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; | |
| 72 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; | |
| 73 | |
| 74 protected: | |
| 75 // Message handlers | |
| 76 void OnRequest(const ExtensionHostMsg_Request_Params& params); | |
| 77 | |
| 78 private: | |
| 79 PanelViewAura* panel_view_; | |
| 80 Profile* profile_; | |
| 81 ExtensionFunctionDispatcher extension_function_dispatcher_; | |
| 82 scoped_ptr<content::WebContents> web_contents_; | |
| 83 // Site instance to be used for opening new links. | |
| 84 scoped_refptr<content::SiteInstance> site_instance_; | |
| 85 }; | |
| 86 | |
| 87 PanelHost::PanelHost(PanelViewAura* panel_view, Profile* profile) | |
| 88 : panel_view_(panel_view), | |
| 89 profile_(profile), | |
| 90 ALLOW_THIS_IN_INITIALIZER_LIST( | |
| 91 extension_function_dispatcher_(profile, this)) { | |
| 92 } | |
| 93 | |
| 94 PanelHost::~PanelHost() { | |
| 95 } | |
| 96 | |
| 97 void PanelHost::Init(const GURL& url) { | |
| 98 site_instance_ = content::SiteInstance::CreateForURL(profile_, url); | |
| 99 | |
| 100 web_contents_.reset(content::WebContents::Create( | |
| 101 profile_, site_instance_.get(), MSG_ROUTING_NONE, NULL, NULL)); | |
| 102 web_contents_->SetViewType(chrome::VIEW_TYPE_PANEL); | |
| 103 web_contents_->SetDelegate(this); | |
| 104 Observe(web_contents_.get()); | |
| 105 | |
| 106 web_contents_->GetController().LoadURL( | |
| 107 url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); | |
| 108 } | |
| 109 | |
| 110 Browser* PanelHost::GetBrowser() { | |
| 111 return NULL; | |
| 112 } | |
| 113 | |
| 114 content::WebContents* PanelHost::GetAssociatedWebContents() const { | |
| 115 return web_contents_.get(); | |
| 116 } | |
| 117 | |
| 118 void PanelHost::CloseContents(content::WebContents* source) { | |
| 119 panel_view_->CloseView(); | |
| 120 } | |
| 121 | |
| 122 void PanelHost::HandleMouseDown() { | |
| 123 } | |
| 124 | |
| 125 void PanelHost::UpdatePreferredSize(content::WebContents* source, | |
| 126 const gfx::Size& pref_size) { | |
| 127 panel_view_->SetContentPreferredSize(pref_size); | |
| 128 } | |
| 129 | |
| 130 // This handles launching a new page from within the panel. | |
| 131 // TODO(stevenjb): Determine whether or not this is the desired/expected | |
| 132 // behavior for panels. | |
| 133 void PanelHost::AddNewContents(content::WebContents* source, | |
| 134 content::WebContents* new_contents, | |
| 135 WindowOpenDisposition disposition, | |
| 136 const gfx::Rect& initial_pos, | |
| 137 bool user_gesture) { | |
| 138 Browser* browser = BrowserList::GetLastActiveWithProfile( | |
| 139 Profile::FromBrowserContext(new_contents->GetBrowserContext())); | |
| 140 if (!browser) | |
| 141 return; | |
| 142 browser->AddWebContents(new_contents, disposition, initial_pos, user_gesture); | |
| 143 } | |
| 144 | |
| 145 void PanelHost::RenderViewCreated(RenderViewHost* render_view_host) { | |
| 146 } | |
| 147 | |
| 148 void PanelHost::RenderViewReady() { | |
| 149 } | |
| 150 | |
| 151 void PanelHost::RenderViewGone(base::TerminationStatus status) { | |
| 152 CloseContents(web_contents_.get()); | |
| 153 } | |
| 154 | |
| 155 bool PanelHost::OnMessageReceived(const IPC::Message& message) { | |
| 156 bool handled = true; | |
| 157 IPC_BEGIN_MESSAGE_MAP(PanelHost, message) | |
| 158 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) | |
| 159 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 160 IPC_END_MESSAGE_MAP() | |
| 161 return handled; | |
| 162 } | |
| 163 | |
| 164 void PanelHost::OnRequest(const ExtensionHostMsg_Request_Params& params) { | |
| 165 extension_function_dispatcher_.Dispatch(params, | |
| 166 web_contents_->GetRenderViewHost()); | |
| 167 } | |
| 168 | |
| 169 //////////////////////////////////////////////////////////////////////////////// | |
| 170 // PanelExtensionWindowController | |
| 171 | |
| 172 class PanelExtensionWindowController : public ExtensionWindowController { | |
| 173 public: | |
| 174 PanelExtensionWindowController(PanelViewAura* panel_view, | |
| 175 PanelHost* panel_host); | |
| 176 | |
| 177 // Overriden from ExtensionWindowController: | |
| 178 virtual const SessionID& GetSessionId() const OVERRIDE; | |
| 179 virtual base::DictionaryValue* CreateWindowValue() const OVERRIDE; | |
| 180 virtual base::DictionaryValue* CreateWindowValueWithTabs() const OVERRIDE; | |
| 181 virtual bool CanClose( | |
| 182 ExtensionWindowController::Reason* reason) const OVERRIDE; | |
| 183 virtual void SetFullscreenMode(bool is_fullscreen, | |
| 184 const GURL& extension_url) const OVERRIDE; | |
| 185 | |
| 186 private: | |
| 187 PanelViewAura* panel_view_; | |
| 188 PanelHost* panel_host_; | |
| 189 | |
| 190 DISALLOW_COPY_AND_ASSIGN(PanelExtensionWindowController); | |
| 191 }; | |
| 192 | |
| 193 PanelExtensionWindowController::PanelExtensionWindowController( | |
| 194 PanelViewAura* panel_view, | |
| 195 PanelHost* panel_host) | |
| 196 : ExtensionWindowController(panel_view, panel_host->profile()), | |
| 197 panel_view_(panel_view), | |
| 198 panel_host_(panel_host) { | |
| 199 } | |
| 200 | |
| 201 const SessionID& PanelExtensionWindowController::GetSessionId() const { | |
| 202 return panel_view_->session_id(); | |
| 203 } | |
| 204 | |
| 205 namespace keys = extension_tabs_module_constants; | |
| 206 | |
| 207 base::DictionaryValue* | |
| 208 PanelExtensionWindowController::CreateWindowValue() const { | |
| 209 DictionaryValue* result = ExtensionWindowController::CreateWindowValue(); | |
| 210 | |
| 211 result->SetString(keys::kWindowTypeKey, keys::kWindowTypeValuePanel); | |
| 212 std::string window_state = window()->IsMinimized() ? | |
| 213 keys::kShowStateValueMinimized : keys::kShowStateValueNormal; | |
| 214 result->SetString(keys::kShowStateKey, window_state); | |
| 215 | |
| 216 return result; | |
| 217 } | |
| 218 | |
| 219 base::DictionaryValue* | |
| 220 PanelExtensionWindowController::CreateWindowValueWithTabs() const { | |
| 221 DictionaryValue* result = CreateWindowValue(); | |
| 222 | |
| 223 // TODO(stevenjb): Implement tab interface for Aura panels. | |
| 224 // Currently there is no mechanism to get a tab id without an associated | |
| 225 // TabContentsWrapper. We will need to either add a TabContentsWrapper for | |
| 226 // panels, or add another mechanism for tracking tabs. crbug.com/115532. | |
| 227 | |
| 228 return result; | |
| 229 } | |
| 230 | |
| 231 bool PanelExtensionWindowController::CanClose( | |
| 232 ExtensionWindowController::Reason* reason) const { | |
| 233 return true; | |
| 234 } | |
| 235 | |
| 236 void PanelExtensionWindowController::SetFullscreenMode( | |
| 237 bool is_fullscreen, const GURL& extension_url) const { | |
| 238 } | |
| 239 | |
| 240 } // namespace internal | |
| 241 | |
| 242 //////////////////////////////////////////////////////////////////////////////// | |
| 243 // PanelViewAura | |
| 244 | |
| 245 PanelViewAura::PanelViewAura(const std::string& title) | |
| 246 : title_(title), | |
| 247 preferred_size_(kMinWidth, kMinHeight), | |
| 248 widget_(NULL) { | |
| 249 } | |
| 250 | |
| 251 PanelViewAura::~PanelViewAura() { | |
| 252 } | |
| 253 | |
| 254 views::Widget* PanelViewAura::Init(Profile* profile, | |
| 255 const GURL& url, | |
| 256 const gfx::Rect& bounds) { | |
| 257 widget_ = new views::Widget; | |
| 258 views::Widget::InitParams params(views::Widget::InitParams::TYPE_PANEL); | |
| 259 params.delegate = this; | |
| 260 | |
| 261 params.bounds = bounds; | |
| 262 if (params.bounds.width() == 0) | |
| 263 params.bounds.set_width(kDefaultWidth); | |
| 264 else if (params.bounds.width() < kMinWidth) | |
| 265 params.bounds.set_width(kMinWidth); | |
| 266 | |
| 267 if (params.bounds.height() == 0) | |
| 268 params.bounds.set_height(kDefaultHeight); | |
| 269 else if (params.bounds.height() < kMinHeight) | |
| 270 params.bounds.set_height(kMinHeight); | |
| 271 | |
| 272 widget_->Init(params); | |
| 273 widget_->GetNativeView()->SetName(title_); | |
| 274 | |
| 275 host_.reset(new internal::PanelHost(this, profile)); | |
| 276 host_->Init(url); | |
| 277 | |
| 278 Attach(host_->web_contents()->GetNativeView()); | |
| 279 | |
| 280 // Add the browser to the list of windows available to the extension API. | |
| 281 extension_window_controller_.reset( | |
| 282 new internal::PanelExtensionWindowController(this, host_.get())); | |
| 283 | |
| 284 // Show the window, but don't activate it by default. | |
| 285 widget_->ShowInactive(); | |
| 286 | |
| 287 return widget_; | |
| 288 } | |
| 289 | |
| 290 content::WebContents* PanelViewAura::WebContents() { | |
| 291 return host_->web_contents(); | |
| 292 } | |
| 293 | |
| 294 void PanelViewAura::CloseView() { | |
| 295 widget_->CloseNow(); | |
| 296 } | |
| 297 | |
| 298 void PanelViewAura::SetContentPreferredSize(const gfx::Size& size) { | |
| 299 if (size.width() > kMinWidth) | |
| 300 preferred_size_.set_width(size.width()); | |
| 301 if (size.height() > kMinHeight) | |
| 302 preferred_size_.set_height(size.height()); | |
| 303 } | |
| 304 | |
| 305 // views::View implementation: | |
| 306 | |
| 307 gfx::Size PanelViewAura::GetPreferredSize() { | |
| 308 return preferred_size_; | |
| 309 } | |
| 310 | |
| 311 // views::WidgetDelegate implementation: | |
| 312 | |
| 313 bool PanelViewAura::CanResize() const { | |
| 314 // TODO(stevenjb): Can/should panels be able to prevent resizing? | |
| 315 return true; | |
| 316 } | |
| 317 | |
| 318 string16 PanelViewAura::GetWindowTitle() const { | |
| 319 return UTF8ToUTF16(title_); | |
| 320 } | |
| 321 | |
| 322 views::View* PanelViewAura::GetContentsView() { | |
| 323 return this; | |
| 324 } | |
| 325 | |
| 326 views::View* PanelViewAura::GetInitiallyFocusedView() { | |
| 327 return this; | |
| 328 } | |
| 329 | |
| 330 bool PanelViewAura::ShouldShowWindowTitle() const { | |
| 331 return true; | |
| 332 } | |
| 333 | |
| 334 views::Widget* PanelViewAura::GetWidget() { | |
| 335 return View::GetWidget(); | |
| 336 } | |
| 337 | |
| 338 const views::Widget* PanelViewAura::GetWidget() const { | |
| 339 return View::GetWidget(); | |
| 340 } | |
| 341 | |
| 342 views::NonClientFrameView* PanelViewAura::CreateNonClientFrameView() { | |
| 343 return new ash::PanelFrameView(); | |
| 344 } | |
| 345 | |
| 346 // BaseWindow implementation: | |
| 347 | |
| 348 bool PanelViewAura::IsActive() const { | |
| 349 return GetWidget()->IsActive(); | |
| 350 } | |
| 351 | |
| 352 bool PanelViewAura::IsMaximized() const { | |
| 353 return GetWidget()->IsMaximized(); | |
| 354 } | |
| 355 | |
| 356 bool PanelViewAura::IsMinimized() const { | |
| 357 return GetWidget()->IsMinimized(); | |
| 358 } | |
| 359 | |
| 360 gfx::Rect PanelViewAura::GetRestoredBounds() const { | |
| 361 return GetWidget()->GetRestoredBounds(); | |
| 362 } | |
| 363 | |
| 364 gfx::Rect PanelViewAura::GetBounds() const { | |
| 365 return GetWidget()->GetWindowScreenBounds(); | |
| 366 } | |
| 367 | |
| 368 void PanelViewAura::Show() { | |
| 369 GetWidget()->Show(); | |
| 370 } | |
| 371 | |
| 372 void PanelViewAura::ShowInactive() { | |
| 373 GetWidget()->ShowInactive(); | |
| 374 } | |
| 375 | |
| 376 void PanelViewAura::Close() { | |
| 377 GetWidget()->Close(); | |
| 378 } | |
| 379 | |
| 380 void PanelViewAura::Activate() { | |
| 381 GetWidget()->Activate(); | |
| 382 } | |
| 383 | |
| 384 void PanelViewAura::Deactivate() { | |
| 385 GetWidget()->Deactivate(); | |
| 386 } | |
| 387 | |
| 388 void PanelViewAura::Maximize() { | |
| 389 // Maximize is not implemented for panels. | |
| 390 } | |
| 391 | |
| 392 void PanelViewAura::Minimize() { | |
| 393 // TODO(stevenjb): Implement this properly. | |
| 394 GetWidget()->Minimize(); | |
| 395 NOTIMPLEMENTED(); | |
| 396 } | |
| 397 | |
| 398 void PanelViewAura::Restore() { | |
| 399 // TODO(stevenjb): Implement this properly. | |
| 400 GetWidget()->Restore(); | |
| 401 NOTIMPLEMENTED(); | |
| 402 } | |
| 403 | |
| 404 void PanelViewAura::SetBounds(const gfx::Rect& bounds) { | |
| 405 GetWidget()->SetBounds(bounds); | |
| 406 } | |
| 407 | |
| 408 void PanelViewAura::FlashFrame(bool flash) { | |
| 409 // TODO(stevenjb): Implement | |
| 410 NOTIMPLEMENTED(); | |
| 411 } | |
| OLD | NEW |