普通文本  |  164行  |  5.46 KB

// Copyright (c) 2011 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/extensions/extension_tab_helper.h"

#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h"
#include "chrome/common/extensions/extension_action.h"
#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/extension_resource.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/navigation_controller.h"
#include "content/common/notification_service.h"

ExtensionTabHelper::ExtensionTabHelper(TabContentsWrapper* wrapper)
    : TabContentsObserver(wrapper->tab_contents()),
      extension_app_(NULL),
      wrapper_(wrapper) {
}

ExtensionTabHelper::~ExtensionTabHelper() {
}

void ExtensionTabHelper::CopyStateFrom(const ExtensionTabHelper& source) {
  SetExtensionApp(source.extension_app());
  extension_app_icon_ = source.extension_app_icon_;
}

void ExtensionTabHelper::PageActionStateChanged() {
  tab_contents()->NotifyNavigationStateChanged(
      TabContents::INVALIDATE_PAGE_ACTIONS);
}

void ExtensionTabHelper::GetApplicationInfo(int32 page_id) {
  Send(new ExtensionMsg_GetApplicationInfo(routing_id(), page_id));
}

void ExtensionTabHelper::SetExtensionApp(const Extension* extension) {
  DCHECK(!extension || extension->GetFullLaunchURL().is_valid());
  extension_app_ = extension;

  UpdateExtensionAppIcon(extension_app_);

  NotificationService::current()->Notify(
      NotificationType::TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED,
      Source<ExtensionTabHelper>(this),
      NotificationService::NoDetails());
}

void ExtensionTabHelper::SetExtensionAppById(
    const std::string& extension_app_id) {
  if (extension_app_id.empty())
    return;

  ExtensionService* extension_service =
      tab_contents()->profile()->GetExtensionService();
  if (!extension_service || !extension_service->is_ready())
    return;

  const Extension* extension =
      extension_service->GetExtensionById(extension_app_id, false);
  if (extension)
    SetExtensionApp(extension);
}

SkBitmap* ExtensionTabHelper::GetExtensionAppIcon() {
  if (extension_app_icon_.empty())
    return NULL;

  return &extension_app_icon_;
}

void ExtensionTabHelper::DidNavigateMainFramePostCommit(
    const NavigationController::LoadCommittedDetails& details,
    const ViewHostMsg_FrameNavigate_Params& params) {
  if (details.is_in_page)
    return;

  ExtensionService* service = tab_contents()->profile()->GetExtensionService();
  if (!service)
    return;

  for (size_t i = 0; i < service->extensions()->size(); ++i) {
    ExtensionAction* browser_action =
        service->extensions()->at(i)->browser_action();
    if (browser_action) {
      browser_action->ClearAllValuesForTab(
          tab_contents()->controller().session_id().id());
      NotificationService::current()->Notify(
          NotificationType::EXTENSION_BROWSER_ACTION_UPDATED,
          Source<ExtensionAction>(browser_action),
          NotificationService::NoDetails());
    }

    ExtensionAction* page_action =
        service->extensions()->at(i)->page_action();
    if (page_action) {
      page_action->ClearAllValuesForTab(
          tab_contents()->controller().session_id().id());
      PageActionStateChanged();
    }
  }
}

bool ExtensionTabHelper::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ExtensionTabHelper, message)
    IPC_MESSAGE_HANDLER(ExtensionHostMsg_DidGetApplicationInfo,
                        OnDidGetApplicationInfo)
    IPC_MESSAGE_HANDLER(ExtensionHostMsg_InstallApplication,
                        OnInstallApplication)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void ExtensionTabHelper::OnDidGetApplicationInfo(
    int32 page_id, const WebApplicationInfo& info) {
  web_app_info_ = info;

  if (wrapper_->delegate())
    wrapper_->delegate()->OnDidGetApplicationInfo(wrapper_, page_id);
}

void ExtensionTabHelper::OnInstallApplication(const WebApplicationInfo& info) {
  if (wrapper_->delegate())
    wrapper_->delegate()->OnInstallApplication(wrapper_, info);
}

void ExtensionTabHelper::UpdateExtensionAppIcon(const Extension* extension) {
  extension_app_icon_.reset();

  if (extension) {
    extension_app_image_loader_.reset(new ImageLoadingTracker(this));
    extension_app_image_loader_->LoadImage(
        extension,
        extension->GetIconResource(Extension::EXTENSION_ICON_SMALLISH,
                                   ExtensionIconSet::MATCH_EXACTLY),
        gfx::Size(Extension::EXTENSION_ICON_SMALLISH,
                  Extension::EXTENSION_ICON_SMALLISH),
        ImageLoadingTracker::CACHE);
  } else {
    extension_app_image_loader_.reset(NULL);
  }
}

void ExtensionTabHelper::SetAppIcon(const SkBitmap& app_icon) {
  extension_app_icon_ = app_icon;
  tab_contents()->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE);
}

void ExtensionTabHelper::OnImageLoaded(SkBitmap* image,
                                       const ExtensionResource& resource,
                                       int index) {
  if (image) {
    extension_app_icon_ = *image;
    tab_contents()->NotifyNavigationStateChanged(TabContents::INVALIDATE_TAB);
  }
}