root/chrome/browser/notifications/balloon_host.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. extension_function_dispatcher_
  2. Shutdown
  3. GetExtensionWindowController
  4. GetAssociatedWebContents
  5. GetSource
  6. CloseContents
  7. HandleMouseDown
  8. ResizeDueToAutoResize
  9. AddNewContents
  10. RenderViewCreated
  11. RenderViewReady
  12. RenderProcessGone
  13. OnMessageReceived
  14. OnRequest
  15. Init
  16. EnableWebUI
  17. NotifyDisconnect
  18. IsRenderViewReady

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/notifications/balloon_host.h"

#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/notifications/balloon.h"
#include "chrome/browser/notifications/balloon_collection_impl.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_preferences_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/renderer_preferences.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/extension_messages.h"
#include "ipc/ipc_message.h"

using content::SiteInstance;
using content::WebContents;

BalloonHost::BalloonHost(Balloon* balloon)
    : balloon_(balloon),
      initialized_(false),
      should_notify_on_disconnect_(false),
      enable_web_ui_(false),
      extension_function_dispatcher_(balloon_->profile(), this) {
  site_instance_ = SiteInstance::CreateForURL(
      balloon_->profile(), balloon_->notification().content_url());
}

void BalloonHost::Shutdown() {
  NotifyDisconnect();
  web_contents_.reset();
  site_instance_ = NULL;
  balloon_ = NULL;  // No longer safe to access |balloon_|
}

extensions::WindowController*
BalloonHost::GetExtensionWindowController() const {
  // Notifications don't have a window controller.
  return NULL;
}

content::WebContents* BalloonHost::GetAssociatedWebContents() const {
  return NULL;
}

const base::string16& BalloonHost::GetSource() const {
  return balloon_->notification().display_source();
}

void BalloonHost::CloseContents(WebContents* source) {
  if (!balloon_)
    return;
  balloon_->CloseByScript();
  NotifyDisconnect();
}

void BalloonHost::HandleMouseDown() {
  if (balloon_)
    balloon_->OnClick();
}

void BalloonHost::ResizeDueToAutoResize(WebContents* source,
                                        const gfx::Size& pref_size) {
  if (balloon_)
    balloon_->ResizeDueToAutoResize(pref_size);
}

void BalloonHost::AddNewContents(WebContents* source,
                                 WebContents* new_contents,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture,
                                 bool* was_blocked) {
  Browser* browser = chrome::FindLastActiveWithProfile(
      Profile::FromBrowserContext(new_contents->GetBrowserContext()),
      chrome::GetActiveDesktop());
  if (browser) {
    chrome::AddWebContents(browser, NULL, new_contents, disposition,
                           initial_pos, user_gesture, was_blocked);
  }
}

void BalloonHost::RenderViewCreated(content::RenderViewHost* render_view_host) {
  gfx::Size min_size(BalloonCollectionImpl::min_balloon_width(),
                     BalloonCollectionImpl::min_balloon_height());
  gfx::Size max_size(BalloonCollectionImpl::max_balloon_width(),
                     BalloonCollectionImpl::max_balloon_height());
  render_view_host->EnableAutoResize(min_size, max_size);

  if (enable_web_ui_)
    render_view_host->AllowBindings(content::BINDINGS_POLICY_WEB_UI);
}

void BalloonHost::RenderViewReady() {
  should_notify_on_disconnect_ = true;
  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED,
      content::Source<BalloonHost>(this),
      content::NotificationService::NoDetails());
}

void BalloonHost::RenderProcessGone(base::TerminationStatus status) {
  CloseContents(web_contents_.get());
}

bool BalloonHost::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(BalloonHost, message)
    IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void BalloonHost::OnRequest(const ExtensionHostMsg_Request_Params& params) {
  extension_function_dispatcher_.Dispatch(params,
                                          web_contents_->GetRenderViewHost());
}

void BalloonHost::Init() {
  DCHECK(!web_contents_.get()) << "BalloonViewHost already initialized.";
  web_contents_.reset(WebContents::Create(
      WebContents::CreateParams(balloon_->profile(), site_instance_.get())));
  extensions::SetViewType(
      web_contents_.get(), extensions::VIEW_TYPE_NOTIFICATION);
  web_contents_->SetDelegate(this);
  extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
      web_contents_.get());
  Observe(web_contents_.get());
  renderer_preferences_util::UpdateFromSystemSettings(
      web_contents_->GetMutableRendererPrefs(), balloon_->profile());
  web_contents_->GetRenderViewHost()->SyncRendererPrefs();

  web_contents_->GetController().LoadURL(
      balloon_->notification().content_url(), content::Referrer(),
      content::PAGE_TRANSITION_LINK, std::string());

  initialized_ = true;
}

void BalloonHost::EnableWebUI() {
  DCHECK(!web_contents_.get()) <<
      "EnableWebUI has to be called before a renderer is created.";
  enable_web_ui_ = true;
}

BalloonHost::~BalloonHost() {
}

void BalloonHost::NotifyDisconnect() {
  if (!should_notify_on_disconnect_)
    return;

  should_notify_on_disconnect_ = false;
  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
      content::Source<BalloonHost>(this),
      content::NotificationService::NoDetails());
}

bool BalloonHost::IsRenderViewReady() const {
  return should_notify_on_disconnect_;
}

/* [<][>][^][v][top][bottom][index][help] */