1// Copyright (c) 2010 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/sidebar/sidebar_container.h"
6
7#include "chrome/browser/extensions/extension_service.h"
8#include "chrome/browser/profiles/profile.h"
9#include "chrome/common/extensions/extension.h"
10#include "chrome/common/extensions/extension_resource.h"
11#include "chrome/common/extensions/extension_sidebar_defaults.h"
12#include "chrome/common/extensions/extension_sidebar_utils.h"
13#include "content/browser/renderer_host/browser_render_process_host.h"
14#include "content/browser/renderer_host/render_view_host.h"
15#include "content/browser/tab_contents/navigation_controller.h"
16#include "content/browser/tab_contents/navigation_entry.h"
17#include "content/browser/tab_contents/tab_contents.h"
18#include "content/browser/tab_contents/tab_contents_view.h"
19#include "content/common/bindings_policy.h"
20#include "googleurl/src/gurl.h"
21#include "third_party/skia/include/core/SkBitmap.h"
22
23SidebarContainer::SidebarContainer(TabContents* tab,
24                                   const std::string& content_id,
25                                   Delegate* delegate)
26    : tab_(tab),
27      content_id_(content_id),
28      delegate_(delegate),
29      icon_(new SkBitmap),
30      navigate_to_default_page_on_expand_(true),
31      use_default_icon_(true) {
32  // Create TabContents for sidebar.
33  sidebar_contents_.reset(
34      new TabContents(tab->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL));
35  sidebar_contents_->render_view_host()->set_is_extension_process(true);
36  const Extension* extension = GetExtension();
37  if (extension && extension->is_app()) {
38    BrowserRenderProcessHost* process = static_cast<BrowserRenderProcessHost*>(
39        sidebar_contents_->render_view_host()->process());
40    process->set_installed_app(extension);
41  }
42  sidebar_contents_->render_view_host()->AllowBindings(
43      BindingsPolicy::EXTENSION);
44  sidebar_contents_->set_delegate(this);
45}
46
47SidebarContainer::~SidebarContainer() {
48}
49
50void SidebarContainer::SidebarClosing() {
51  delegate_->UpdateSidebar(this);
52}
53
54void SidebarContainer::LoadDefaults() {
55  const Extension* extension = GetExtension();
56  if (!extension)
57    return;  // Can be NULL in tests.
58  const ExtensionSidebarDefaults* sidebar_defaults =
59      extension->sidebar_defaults();
60
61  title_ = sidebar_defaults->default_title();
62
63  if (!sidebar_defaults->default_icon_path().empty()) {
64    image_loading_tracker_.reset(new ImageLoadingTracker(this));
65    image_loading_tracker_->LoadImage(
66        extension,
67        extension->GetResource(sidebar_defaults->default_icon_path()),
68        gfx::Size(Extension::kSidebarIconMaxSize,
69                  Extension::kSidebarIconMaxSize),
70        ImageLoadingTracker::CACHE);
71  }
72}
73
74void SidebarContainer::Show() {
75  delegate_->UpdateSidebar(this);
76}
77
78void SidebarContainer::Expand() {
79  if (navigate_to_default_page_on_expand_) {
80    navigate_to_default_page_on_expand_ = false;
81    // Check whether a default page is specified for this sidebar.
82    const Extension* extension = GetExtension();
83    if (extension) {  // Can be NULL in tests.
84      if (extension->sidebar_defaults()->default_page().is_valid())
85        Navigate(extension->sidebar_defaults()->default_page());
86    }
87  }
88
89  delegate_->UpdateSidebar(this);
90  sidebar_contents_->view()->SetInitialFocus();
91}
92
93void SidebarContainer::Collapse() {
94  delegate_->UpdateSidebar(this);
95}
96
97void SidebarContainer::Navigate(const GURL& url) {
98  // TODO(alekseys): add a progress UI.
99  navigate_to_default_page_on_expand_ = false;
100  sidebar_contents_->controller().LoadURL(
101      url, GURL(), PageTransition::START_PAGE);
102}
103
104void SidebarContainer::SetBadgeText(const string16& badge_text) {
105  badge_text_ = badge_text;
106}
107
108void SidebarContainer::SetIcon(const SkBitmap& bitmap) {
109  use_default_icon_ = false;
110  *icon_ = bitmap;
111}
112
113void SidebarContainer::SetTitle(const string16& title) {
114  title_ = title;
115}
116
117bool SidebarContainer::IsPopup(const TabContents* source) const {
118  return false;
119}
120
121void SidebarContainer::OnImageLoaded(SkBitmap* image,
122                                     const ExtensionResource& resource,
123                                     int index) {
124  if (image && use_default_icon_) {
125    *icon_ = *image;
126     delegate_->UpdateSidebar(this);
127  }
128}
129
130const Extension* SidebarContainer::GetExtension() const {
131  ExtensionService* service =
132      sidebar_contents_->profile()->GetExtensionService();
133  if (!service)
134    return NULL;
135  return service->GetExtensionById(
136      extension_sidebar_utils::GetExtensionIdByContentId(content_id_), false);
137}
138