1// Copyright (c) 2012 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 "content/browser/web_contents/web_contents_view_android.h"
6
7#include "base/logging.h"
8#include "content/browser/android/content_view_core_impl.h"
9#include "content/browser/frame_host/interstitial_page_impl.h"
10#include "content/browser/renderer_host/render_widget_host_view_android.h"
11#include "content/browser/renderer_host/render_view_host_factory.h"
12#include "content/browser/renderer_host/render_view_host_impl.h"
13#include "content/browser/web_contents/web_contents_impl.h"
14#include "content/public/browser/web_contents_delegate.h"
15
16namespace content {
17WebContentsView* CreateWebContentsView(
18    WebContentsImpl* web_contents,
19    WebContentsViewDelegate* delegate,
20    RenderViewHostDelegateView** render_view_host_delegate_view) {
21  WebContentsViewAndroid* rv = new WebContentsViewAndroid(
22      web_contents, delegate);
23  *render_view_host_delegate_view = rv;
24  return rv;
25}
26
27WebContentsViewAndroid::WebContentsViewAndroid(
28    WebContentsImpl* web_contents,
29    WebContentsViewDelegate* delegate)
30    : web_contents_(web_contents),
31      content_view_core_(NULL),
32      delegate_(delegate) {
33}
34
35WebContentsViewAndroid::~WebContentsViewAndroid() {
36}
37
38void WebContentsViewAndroid::SetContentViewCore(
39    ContentViewCoreImpl* content_view_core) {
40  content_view_core_ = content_view_core;
41  RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
42      web_contents_->GetRenderWidgetHostView());
43  if (rwhv)
44    rwhv->SetContentViewCore(content_view_core_);
45
46  if (web_contents_->ShowingInterstitialPage()) {
47    rwhv = static_cast<RenderWidgetHostViewAndroid*>(
48        static_cast<InterstitialPageImpl*>(
49            web_contents_->GetInterstitialPage())->
50                GetRenderViewHost()->GetView());
51    if (rwhv)
52      rwhv->SetContentViewCore(content_view_core_);
53  }
54}
55
56gfx::NativeView WebContentsViewAndroid::GetNativeView() const {
57  return content_view_core_ ? content_view_core_->GetViewAndroid() : NULL;
58}
59
60gfx::NativeView WebContentsViewAndroid::GetContentNativeView() const {
61  return content_view_core_ ? content_view_core_->GetViewAndroid() : NULL;
62}
63
64gfx::NativeWindow WebContentsViewAndroid::GetTopLevelNativeWindow() const {
65  return content_view_core_ ? content_view_core_->GetWindowAndroid() : NULL;
66}
67
68void WebContentsViewAndroid::GetContainerBounds(gfx::Rect* out) const {
69  *out = content_view_core_ ? gfx::Rect(content_view_core_->GetViewSize())
70                            : gfx::Rect();
71}
72
73void WebContentsViewAndroid::SetPageTitle(const base::string16& title) {
74  if (content_view_core_)
75    content_view_core_->SetTitle(title);
76}
77
78void WebContentsViewAndroid::SizeContents(const gfx::Size& size) {
79  // TODO(klobag): Do we need to do anything else?
80  RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
81  if (rwhv)
82    rwhv->SetSize(size);
83}
84
85void WebContentsViewAndroid::Focus() {
86  if (web_contents_->ShowingInterstitialPage())
87    web_contents_->GetInterstitialPage()->Focus();
88  else
89    web_contents_->GetRenderWidgetHostView()->Focus();
90}
91
92void WebContentsViewAndroid::SetInitialFocus() {
93  if (web_contents_->FocusLocationBarByDefault())
94    web_contents_->SetFocusToLocationBar(false);
95  else
96    Focus();
97}
98
99void WebContentsViewAndroid::StoreFocus() {
100  NOTIMPLEMENTED();
101}
102
103void WebContentsViewAndroid::RestoreFocus() {
104  NOTIMPLEMENTED();
105}
106
107DropData* WebContentsViewAndroid::GetDropData() const {
108  NOTIMPLEMENTED();
109  return NULL;
110}
111
112gfx::Rect WebContentsViewAndroid::GetViewBounds() const {
113  if (content_view_core_)
114    return gfx::Rect(content_view_core_->GetViewSize());
115
116  return gfx::Rect();
117}
118
119void WebContentsViewAndroid::CreateView(
120    const gfx::Size& initial_size, gfx::NativeView context) {
121}
122
123RenderWidgetHostViewBase* WebContentsViewAndroid::CreateViewForWidget(
124    RenderWidgetHost* render_widget_host) {
125  if (render_widget_host->GetView()) {
126    // During testing, the view will already be set up in most cases to the
127    // test view, so we don't want to clobber it with a real one. To verify that
128    // this actually is happening (and somebody isn't accidentally creating the
129    // view twice), we check for the RVH Factory, which will be set when we're
130    // making special ones (which go along with the special views).
131    DCHECK(RenderViewHostFactory::has_factory());
132    return static_cast<RenderWidgetHostViewBase*>(
133        render_widget_host->GetView());
134  }
135  // Note that while this instructs the render widget host to reference
136  // |native_view_|, this has no effect without also instructing the
137  // native view (i.e. ContentView) how to obtain a reference to this widget in
138  // order to paint it. See ContentView::GetRenderWidgetHostViewAndroid for an
139  // example of how this is achieved for InterstitialPages.
140  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(render_widget_host);
141  return new RenderWidgetHostViewAndroid(rwhi, content_view_core_);
142}
143
144RenderWidgetHostViewBase* WebContentsViewAndroid::CreateViewForPopupWidget(
145    RenderWidgetHost* render_widget_host) {
146  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(render_widget_host);
147  return new RenderWidgetHostViewAndroid(rwhi, NULL);
148}
149
150void WebContentsViewAndroid::RenderViewCreated(RenderViewHost* host) {
151}
152
153void WebContentsViewAndroid::RenderViewSwappedIn(RenderViewHost* host) {
154}
155
156void WebContentsViewAndroid::SetOverscrollControllerEnabled(bool enabled) {
157}
158
159void WebContentsViewAndroid::ShowContextMenu(
160    RenderFrameHost* render_frame_host, const ContextMenuParams& params) {
161  if (delegate_)
162    delegate_->ShowContextMenu(render_frame_host, params);
163}
164
165void WebContentsViewAndroid::ShowPopupMenu(
166    RenderFrameHost* render_frame_host,
167    const gfx::Rect& bounds,
168    int item_height,
169    double item_font_size,
170    int selected_item,
171    const std::vector<MenuItem>& items,
172    bool right_aligned,
173    bool allow_multiple_selection) {
174  if (content_view_core_) {
175    content_view_core_->ShowSelectPopupMenu(render_frame_host,
176                                            bounds,
177                                            items,
178                                            selected_item,
179                                            allow_multiple_selection);
180  }
181}
182
183void WebContentsViewAndroid::HidePopupMenu() {
184  if (content_view_core_)
185    content_view_core_->HideSelectPopupMenu();
186}
187
188void WebContentsViewAndroid::StartDragging(
189    const DropData& drop_data,
190    blink::WebDragOperationsMask allowed_ops,
191    const gfx::ImageSkia& image,
192    const gfx::Vector2d& image_offset,
193    const DragEventSourceInfo& event_info) {
194  NOTIMPLEMENTED();
195}
196
197void WebContentsViewAndroid::UpdateDragCursor(blink::WebDragOperation op) {
198  NOTIMPLEMENTED();
199}
200
201void WebContentsViewAndroid::GotFocus() {
202  // This is only used in the views FocusManager stuff but it bleeds through
203  // all subclasses. http://crbug.com/21875
204}
205
206// This is called when we the renderer asks us to take focus back (i.e., it has
207// iterated past the last focusable element on the page).
208void WebContentsViewAndroid::TakeFocus(bool reverse) {
209  if (web_contents_->GetDelegate() &&
210      web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse))
211    return;
212  web_contents_->GetRenderWidgetHostView()->Focus();
213}
214
215} // namespace content
216