// Copyright 2013 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/extension_process_resource_provider.h"

#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/task_manager/resource_provider.h"
#include "chrome/browser/task_manager/task_manager.h"
#include "chrome/browser/task_manager/task_manager_util.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.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 "extensions/browser/process_manager.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/extension.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"

using content::WebContents;
using extensions::Extension;

namespace task_manager {

class ExtensionProcessResource : public Resource {
 public:
  explicit ExtensionProcessResource(
      content::RenderViewHost* render_view_host);
  virtual ~ExtensionProcessResource();

  // Resource methods:
  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;
  virtual const extensions::Extension* GetExtension() const OVERRIDE;

  // Returns the pid of the extension process.
  int process_id() const { return pid_; }

  // Returns true if the associated extension has a background page.
  virtual bool IsBackground() const OVERRIDE;

 private:
  // The icon painted for the extension process.
  static gfx::ImageSkia* default_icon_;

  content::RenderViewHost* render_view_host_;

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

  DISALLOW_COPY_AND_ASSIGN(ExtensionProcessResource);
};

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

ExtensionProcessResource::ExtensionProcessResource(
    content::RenderViewHost* render_view_host)
    : render_view_host_(render_view_host) {
  if (!default_icon_) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    default_icon_ = rb.GetImageSkiaNamed(IDR_PLUGINS_FAVICON);
  }
  process_handle_ = render_view_host_->GetProcess()->GetHandle();
  unique_process_id_ = render_view_host->GetProcess()->GetID();
  pid_ = base::GetProcId(process_handle_);
  base::string16 extension_name = UTF8ToUTF16(GetExtension()->name());
  DCHECK(!extension_name.empty());

  Profile* profile = Profile::FromBrowserContext(
      render_view_host->GetProcess()->GetBrowserContext());
  int message_id = util::GetMessagePrefixID(
      GetExtension()->is_app(),
      true,  // is_extension
      profile->IsOffTheRecord(),
      false,  // is_prerender
      false,  // is_instant_overlay
      IsBackground());
  title_ = l10n_util::GetStringFUTF16(message_id, extension_name);
}

ExtensionProcessResource::~ExtensionProcessResource() {
}

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

base::string16 ExtensionProcessResource::GetProfileName() const {
  return util::GetProfileNameFromInfoCache(
      Profile::FromBrowserContext(
          render_view_host_->GetProcess()->GetBrowserContext()));
}

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

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

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

Resource::Type ExtensionProcessResource::GetType() const {
  return EXTENSION;
}

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

void ExtensionProcessResource::Inspect() const {
  DevToolsWindow::OpenDevToolsWindow(render_view_host_);
}

bool ExtensionProcessResource::SupportNetworkUsage() const {
  return true;
}

void ExtensionProcessResource::SetSupportNetworkUsage() {
  NOTREACHED();
}

const Extension* ExtensionProcessResource::GetExtension() const {
  Profile* profile = Profile::FromBrowserContext(
      render_view_host_->GetProcess()->GetBrowserContext());
  extensions::ProcessManager* process_manager =
      extensions::ExtensionSystem::Get(profile)->process_manager();
  return process_manager->GetExtensionForRenderViewHost(render_view_host_);
}

bool ExtensionProcessResource::IsBackground() const {
  WebContents* web_contents =
      WebContents::FromRenderViewHost(render_view_host_);
  extensions::ViewType view_type = extensions::GetViewType(web_contents);
  return view_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE;
}

////////////////////////////////////////////////////////////////////////////////
// ExtensionProcessResourceProvider class
////////////////////////////////////////////////////////////////////////////////

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

ExtensionProcessResourceProvider::~ExtensionProcessResourceProvider() {
}

Resource* ExtensionProcessResourceProvider::GetResource(
    int origin_pid,
    int render_process_host_id,
    int routing_id) {
  // If an origin PID was specified, the request is from a plugin, not the
  // render view host process
  if (origin_pid)
    return NULL;

  for (ExtensionRenderViewHostMap::iterator i = resources_.begin();
       i != resources_.end(); i++) {
    if (i->first->GetSiteInstance()->GetProcess()->GetID() ==
            render_process_host_id &&
        i->first->GetRoutingID() == routing_id)
      return i->second;
  }

  // Can happen if the page went away while a network request was being
  // performed.
  return NULL;
}

void ExtensionProcessResourceProvider::StartUpdating() {
  DCHECK(!updating_);
  updating_ = true;

  // Add all the existing extension views from all Profiles, including those
  // from incognito split mode.
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles());
  size_t num_default_profiles = profiles.size();
  for (size_t i = 0; i < num_default_profiles; ++i) {
    if (profiles[i]->HasOffTheRecordProfile()) {
      profiles.push_back(profiles[i]->GetOffTheRecordProfile());
    }
  }

  for (size_t i = 0; i < profiles.size(); ++i) {
    extensions::ProcessManager* process_manager =
        extensions::ExtensionSystem::Get(profiles[i])->process_manager();
    if (process_manager) {
      const extensions::ProcessManager::ViewSet all_views =
          process_manager->GetAllViews();
      extensions::ProcessManager::ViewSet::const_iterator jt =
          all_views.begin();
      for (; jt != all_views.end(); ++jt) {
        content::RenderViewHost* rvh = *jt;
        // Don't add dead extension processes.
        if (!rvh->IsRenderViewLive())
          continue;

        AddToTaskManager(rvh);
      }
    }
  }

  // Register for notifications about extension process changes.
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED,
                 content::NotificationService::AllBrowserContextsAndSources());
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
                 content::NotificationService::AllBrowserContextsAndSources());
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED,
                 content::NotificationService::AllBrowserContextsAndSources());
}

void ExtensionProcessResourceProvider::StopUpdating() {
  DCHECK(updating_);
  updating_ = false;

  // Unregister for notifications about extension process changes.
  registrar_.Remove(
      this, chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED,
      content::NotificationService::AllBrowserContextsAndSources());
  registrar_.Remove(
      this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
      content::NotificationService::AllBrowserContextsAndSources());
  registrar_.Remove(
      this, chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED,
      content::NotificationService::AllBrowserContextsAndSources());

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

  resources_.clear();
}

void ExtensionProcessResourceProvider::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED:
      AddToTaskManager(
          content::Details<content::RenderViewHost>(details).ptr());
      break;
    case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED:
      RemoveFromTaskManager(
          content::Details<extensions::ExtensionHost>(details).ptr()->
          render_view_host());
      break;
    case chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED:
      RemoveFromTaskManager(
          content::Details<content::RenderViewHost>(details).ptr());
      break;
    default:
      NOTREACHED() << "Unexpected notification.";
      return;
  }
}

bool ExtensionProcessResourceProvider::
    IsHandledByThisProvider(content::RenderViewHost* render_view_host) {
  WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host);
  // Don't add WebContents that belong to a guest (those are handled by
  // GuestResourceProvider). Otherwise they will be added twice, and
  // in this case they will have the app's name as a title (due to the
  // ExtensionProcessResource constructor).
  if (web_contents->GetRenderProcessHost()->IsGuest())
    return false;
  extensions::ViewType view_type = extensions::GetViewType(web_contents);
  // Don't add WebContents (those are handled by
  // TabContentsResourceProvider) or background contents (handled
  // by BackgroundResourceProvider).
#if defined(USE_ASH)
  return (view_type != extensions::VIEW_TYPE_TAB_CONTENTS &&
          view_type != extensions::VIEW_TYPE_BACKGROUND_CONTENTS);
#else
  return (view_type != extensions::VIEW_TYPE_TAB_CONTENTS &&
          view_type != extensions::VIEW_TYPE_BACKGROUND_CONTENTS &&
          view_type != extensions::VIEW_TYPE_PANEL);
#endif  // USE_ASH
}

void ExtensionProcessResourceProvider::AddToTaskManager(
    content::RenderViewHost* render_view_host) {
  if (!IsHandledByThisProvider(render_view_host))
    return;

  ExtensionProcessResource* resource =
      new ExtensionProcessResource(render_view_host);
  if (resources_.find(render_view_host) != resources_.end())
    return;
  resources_[render_view_host] = resource;
  task_manager_->AddResource(resource);
}

void ExtensionProcessResourceProvider::RemoveFromTaskManager(
    content::RenderViewHost* render_view_host) {
  if (!updating_)
    return;
  std::map<content::RenderViewHost*, ExtensionProcessResource*>
      ::iterator iter = resources_.find(render_view_host);
  if (iter == resources_.end())
    return;

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

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

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

}  // namespace task_manager
