root/chrome/browser/task_manager/notification_resource_provider.cc

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

DEFINITIONS

This source file includes following definitions.
  1. SetSupportNetworkUsage
  2. GetTitle
  3. GetProfileName
  4. GetIcon
  5. GetProcess
  6. GetUniqueChildProcessId
  7. GetType
  8. CanInspect
  9. Inspect
  10. SupportNetworkUsage
  11. Create
  12. updating_
  13. GetResource
  14. StartUpdating
  15. StopUpdating
  16. Observe
  17. AddToTaskManager
  18. RemoveFromTaskManager

// 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/task_manager/notification_resource_provider.h"

#include "base/strings/string16.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/notifications/balloon_host.h"
#include "chrome/browser/notifications/balloon_notification_ui_manager.h"
#include "chrome/browser/task_manager/task_manager.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_skia.h"

namespace task_manager {

class NotificationResource : public Resource {
 public:
  explicit NotificationResource(BalloonHost* balloon_host);
  virtual ~NotificationResource();

  // Resource interface
  virtual base::string16 GetTitle() const OVERRIDE;
  virtual base::string16 GetProfileName() const OVERRIDE;
  virtual gfx::ImageSkia GetIcon() const OVERRIDE;
  virtual base::ProcessHandle GetProcess() const OVERRIDE;
  virtual int GetUniqueChildProcessId() const OVERRIDE;
  virtual Type GetType() const OVERRIDE;
  virtual bool CanInspect() const OVERRIDE;
  virtual void Inspect() const OVERRIDE;
  virtual bool SupportNetworkUsage() const OVERRIDE;
  virtual void SetSupportNetworkUsage() OVERRIDE { }

 private:
  // The icon painted for notifications.       .
  static gfx::ImageSkia* default_icon_;

  // Non-owned pointer to the balloon host.
  BalloonHost* balloon_host_;

  // Cached data about the balloon host.
  base::ProcessHandle process_handle_;
  int pid_;
  int unique_process_id_;
  base::string16 title_;

  DISALLOW_COPY_AND_ASSIGN(NotificationResource);
};

gfx::ImageSkia* NotificationResource::default_icon_ = NULL;

NotificationResource::NotificationResource(BalloonHost* balloon_host)
    : balloon_host_(balloon_host) {
  if (!default_icon_) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    default_icon_ = rb.GetImageSkiaNamed(IDR_PLUGINS_FAVICON);
  }
  process_handle_ =
      balloon_host_->web_contents()->GetRenderProcessHost()->GetHandle();
  unique_process_id_ =
      balloon_host_->web_contents()->GetRenderProcessHost()->GetID();
  pid_ = base::GetProcId(process_handle_);
  title_ = l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_NOTIFICATION_PREFIX,
                                      balloon_host_->GetSource());
}

NotificationResource::~NotificationResource() {
}

base::string16 NotificationResource::GetTitle() const {
  return title_;
}

base::string16 NotificationResource::GetProfileName() const {
  return base::string16();
}

gfx::ImageSkia NotificationResource::GetIcon() const {
  return *default_icon_;
}

base::ProcessHandle NotificationResource::GetProcess() const {
  return process_handle_;
}

int NotificationResource::GetUniqueChildProcessId() const {
  return unique_process_id_;
}

Resource::Type NotificationResource::GetType() const {
  return NOTIFICATION;
}

bool NotificationResource::CanInspect() const {
  return true;
}

void NotificationResource::Inspect() const {
  DevToolsWindow::OpenDevToolsWindow(
      balloon_host_->web_contents()->GetRenderViewHost());
}

bool NotificationResource::SupportNetworkUsage() const {
  return false;
}

////////////////////////////////////////////////////////////////////////////////
// NotificationResourceProvider class
////////////////////////////////////////////////////////////////////////////////

// static
NotificationResourceProvider*
NotificationResourceProvider::Create(TaskManager* task_manager) {
  return new NotificationResourceProvider(task_manager);
}

NotificationResourceProvider::
    NotificationResourceProvider(TaskManager* task_manager)
    : task_manager_(task_manager),
      updating_(false) {
}

NotificationResourceProvider::~NotificationResourceProvider() {
}

Resource* NotificationResourceProvider::GetResource(
    int origin_pid,
    int child_id,
    int route_id) {
  // TODO(johnnyg): provide resources by pid if necessary.
  return NULL;
}

void NotificationResourceProvider::StartUpdating() {
  // MessageCenter does not use Balloons.
  if (NotificationUIManager::DelegatesToMessageCenter())
    return;

  DCHECK(!updating_);
  updating_ = true;

  // Add all the existing BalloonHosts.
  BalloonNotificationUIManager* balloon_manager =
      static_cast<BalloonNotificationUIManager*>(
          g_browser_process->notification_ui_manager());
  BalloonCollection* collection = balloon_manager->balloon_collection();
  const BalloonCollection::Balloons& balloons =
      collection->GetActiveBalloons();
  for (BalloonCollection::Balloons::const_iterator it = balloons.begin();
       it != balloons.end(); ++it) {
    BalloonHost* balloon_host = (*it)->balloon_view()->GetHost();
    if (balloon_host)
      AddToTaskManager(balloon_host);
  }
  // Register for notifications about extension process changes.
  registrar_.Add(this, chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED,
                 content::NotificationService::AllSources());
  registrar_.Add(this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
                 content::NotificationService::AllSources());
}

void NotificationResourceProvider::StopUpdating() {
  // MessageCenter does not use Balloons.
  if (NotificationUIManager::DelegatesToMessageCenter())
    return;

  DCHECK(updating_);
  updating_ = false;

  // Unregister for notifications about extension process changes.
  registrar_.Remove(this, chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED,
                    content::NotificationService::AllSources());
  registrar_.Remove(this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
                    content::NotificationService::AllSources());

  // Delete all the resources.
  STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
  resources_.clear();
}

void NotificationResourceProvider::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED:
      AddToTaskManager(content::Source<BalloonHost>(source).ptr());
      break;
    case chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED:
      RemoveFromTaskManager(content::Source<BalloonHost>(source).ptr());
      break;
    default:
      NOTREACHED() << "Unexpected notification.";
      return;
  }
}

void NotificationResourceProvider::AddToTaskManager(
    BalloonHost* balloon_host) {
  // The resource may already be tracked, if the task manager was opened
  // while the BalloonHost was waiting to connect.
  if (resources_.count(balloon_host))
    return;
  NotificationResource* resource = new NotificationResource(balloon_host);
  resources_[balloon_host] = resource;
  task_manager_->AddResource(resource);
}

void NotificationResourceProvider::RemoveFromTaskManager(
    BalloonHost* balloon_host) {
  if (!updating_)
    return;
  std::map<BalloonHost*, NotificationResource*>::iterator iter =
      resources_.find(balloon_host);
  if (iter == resources_.end())
    return;

  // Remove the resource from the Task Manager.
  NotificationResource* resource = iter->second;
  task_manager_->RemoveResource(resource);

  // Remove it from the map.
  resources_.erase(iter);

  // Finally, delete the resource.
  delete resource;
}

}  // namespace task_manager

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