1 // Copyright 2014 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.
5 #include "chromecast/browser/android/cast_window_android.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "chromecast/browser/android/cast_window_manager.h"
9 #include "chromecast/browser/cast_content_window.h"
10 #include "content/public/browser/devtools_agent_host.h"
11 #include "content/public/browser/navigation_controller.h"
12 #include "content/public/browser/navigation_entry.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/render_widget_host_view.h"
16 #include "content/public/common/renderer_preferences.h"
17 #include "jni/CastWindowAndroid_jni.h"
18 #include "ui/gfx/skia_util.h"
20 namespace chromecast
{
25 // The time (in milliseconds) we wait for after a page is closed (i.e.
26 // after an app is stopped) before we delete the corresponding WebContents.
27 const int kWebContentsDestructionDelayInMs
= 50;
32 bool CastWindowAndroid::RegisterJni(JNIEnv
* env
) {
33 return RegisterNativesImpl(env
);
37 CastWindowAndroid
* CastWindowAndroid::CreateNewWindow(
38 content::BrowserContext
* browser_context
,
40 CastWindowAndroid
* window_android
= new CastWindowAndroid(browser_context
);
41 window_android
->Initialize();
44 window_android
->LoadURL(url
);
46 content::RenderWidgetHostView
* rwhv
=
47 window_android
->web_contents_
->GetRenderWidgetHostView();
49 rwhv
->SetBackgroundColor(SK_ColorBLACK
);
52 return window_android
;
55 CastWindowAndroid::CastWindowAndroid(content::BrowserContext
* browser_context
)
56 : browser_context_(browser_context
),
57 content_window_(new CastContentWindow
),
61 void CastWindowAndroid::Initialize() {
63 content_window_
->CreateWebContents(gfx::Size(), browser_context_
);
64 web_contents_
->SetDelegate(this);
65 content::WebContentsObserver::Observe(web_contents_
.get());
67 JNIEnv
* env
= base::android::AttachCurrentThread();
68 window_java_
.Reset(CreateCastWindowView(this));
70 Java_CastWindowAndroid_initFromNativeWebContents(
71 env
, window_java_
.obj(), web_contents_
->GetJavaWebContents().obj(),
72 web_contents_
->GetRenderProcessHost()->GetID());
74 // Enabling hole-punching also requires runtime renderer preference
75 content::RendererPreferences
* prefs
=
76 web_contents_
->GetMutableRendererPrefs();
77 prefs
->use_video_overlay_for_embedded_encrypted_video
= true;
78 prefs
->use_view_overlay_for_all_video
= true;
79 web_contents_
->GetRenderViewHost()->SyncRendererPrefs();
82 CastWindowAndroid::~CastWindowAndroid() {
85 void CastWindowAndroid::Close() {
86 // Close page first, which fires the window.unload event. The WebContents
87 // itself will be destroyed after browser-process has received renderer
88 // notification that the page is closed.
89 web_contents_
->GetRenderViewHost()->ClosePage();
92 void CastWindowAndroid::Destroy() {
93 // Note: if multiple windows becomes supported, this may close other devtools
95 content::DevToolsAgentHost::DetachAllClients();
96 CloseCastWindowView(window_java_
.obj());
100 void CastWindowAndroid::LoadURL(const GURL
& url
) {
101 content::NavigationController::LoadURLParams
params(url
);
102 params
.transition_type
= ui::PageTransitionFromInt(
103 ui::PAGE_TRANSITION_TYPED
|
104 ui::PAGE_TRANSITION_FROM_ADDRESS_BAR
);
105 web_contents_
->GetController().LoadURLWithParams(params
);
106 web_contents_
->Focus();
109 void CastWindowAndroid::AddNewContents(content::WebContents
* source
,
110 content::WebContents
* new_contents
,
111 WindowOpenDisposition disposition
,
112 const gfx::Rect
& initial_rect
,
121 void CastWindowAndroid::CloseContents(content::WebContents
* source
) {
122 DCHECK_EQ(source
, web_contents_
.get());
124 // We need to delay the deletion of web_contents_ (currently for 50ms) to
125 // give (and guarantee) the renderer enough time to finish 'onunload'
126 // handler (but we don't want to wait any longer than that to delay the
127 // starting of next app).
128 base::MessageLoopProxy::current()->PostDelayedTask(
130 base::Bind(&CastWindowAndroid::Destroy
, weak_factory_
.GetWeakPtr()),
131 base::TimeDelta::FromMilliseconds(kWebContentsDestructionDelayInMs
));
134 bool CastWindowAndroid::CanOverscrollContent() const {
138 bool CastWindowAndroid::AddMessageToConsole(content::WebContents
* source
,
140 const base::string16
& message
,
142 const base::string16
& source_id
) {
146 void CastWindowAndroid::ActivateContents(content::WebContents
* contents
) {
147 DCHECK_EQ(contents
, web_contents_
.get());
148 contents
->GetRenderViewHost()->Focus();
151 void CastWindowAndroid::DeactivateContents(content::WebContents
* contents
) {
152 DCHECK_EQ(contents
, web_contents_
.get());
153 contents
->GetRenderViewHost()->Blur();
156 void CastWindowAndroid::RenderProcessGone(base::TerminationStatus status
) {
157 LOG(ERROR
) << "Render process gone: status=" << status
;
162 } // namespace chromecast