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.
5 #include "content/browser/android/web_contents_observer_android.h"
11 #include "base/android/jni_android.h"
12 #include "base/android/jni_string.h"
13 #include "base/android/scoped_java_ref.h"
14 #include "content/browser/renderer_host/render_widget_host_impl.h"
15 #include "content/browser/web_contents/web_contents_impl.h"
16 #include "content/public/browser/navigation_details.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "jni/WebContentsObserverAndroid_jni.h"
20 using base::android::AttachCurrentThread
;
21 using base::android::ScopedJavaLocalRef
;
22 using base::android::ConvertUTF8ToJavaString
;
23 using base::android::ConvertUTF16ToJavaString
;
27 WebContentsObserverAndroid::WebContentsObserverAndroid(
30 WebContents
* web_contents
)
31 : WebContentsObserver(web_contents
),
32 weak_java_observer_(env
, obj
){
35 WebContentsObserverAndroid::~WebContentsObserverAndroid() {
38 jlong
Init(JNIEnv
* env
, jobject obj
, jobject java_web_contents
) {
39 content::WebContents
* web_contents
=
40 content::WebContents::FromJavaWebContents(java_web_contents
);
43 WebContentsObserverAndroid
* native_observer
= new WebContentsObserverAndroid(
44 env
, obj
, web_contents
);
45 return reinterpret_cast<intptr_t>(native_observer
);
48 void WebContentsObserverAndroid::Destroy(JNIEnv
* env
, jobject obj
) {
52 void WebContentsObserverAndroid::WebContentsDestroyed() {
53 JNIEnv
* env
= AttachCurrentThread();
54 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
58 // The java side will destroy |this|
59 Java_WebContentsObserverAndroid_detachFromWebContents(env
, obj
.obj());
63 void WebContentsObserverAndroid::RenderProcessGone(
64 base::TerminationStatus termination_status
) {
65 JNIEnv
* env
= AttachCurrentThread();
66 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
69 jboolean was_oom_protected
=
70 termination_status
== base::TERMINATION_STATUS_OOM_PROTECTED
;
71 Java_WebContentsObserverAndroid_renderProcessGone(
72 env
, obj
.obj(), was_oom_protected
);
75 void WebContentsObserverAndroid::DidStartLoading(
76 RenderViewHost
* render_view_host
) {
77 JNIEnv
* env
= AttachCurrentThread();
78 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
81 ScopedJavaLocalRef
<jstring
> jstring_url(ConvertUTF8ToJavaString(
82 env
, web_contents()->GetVisibleURL().spec()));
83 Java_WebContentsObserverAndroid_didStartLoading(
84 env
, obj
.obj(), jstring_url
.obj());
87 void WebContentsObserverAndroid::DidStopLoading(
88 RenderViewHost
* render_view_host
) {
89 JNIEnv
* env
= AttachCurrentThread();
90 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
93 ScopedJavaLocalRef
<jstring
> jstring_url(ConvertUTF8ToJavaString(
94 env
, web_contents()->GetLastCommittedURL().spec()));
95 Java_WebContentsObserverAndroid_didStopLoading(
96 env
, obj
.obj(), jstring_url
.obj());
99 void WebContentsObserverAndroid::DidFailProvisionalLoad(
101 const base::string16
& frame_unique_name
,
103 const GURL
& validated_url
,
105 const base::string16
& error_description
,
106 RenderViewHost
* render_view_host
) {
108 true, is_main_frame
, error_code
, error_description
, validated_url
);
111 void WebContentsObserverAndroid::DidFailLoad(
113 const GURL
& validated_url
,
116 const base::string16
& error_description
,
117 RenderViewHost
* render_view_host
) {
119 false, is_main_frame
, error_code
, error_description
, validated_url
);
122 void WebContentsObserverAndroid::DidNavigateMainFrame(
123 const LoadCommittedDetails
& details
,
124 const FrameNavigateParams
& params
) {
125 JNIEnv
* env
= AttachCurrentThread();
126 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
129 ScopedJavaLocalRef
<jstring
> jstring_url(
130 ConvertUTF8ToJavaString(env
, params
.url
.spec()));
131 ScopedJavaLocalRef
<jstring
> jstring_base_url(
132 ConvertUTF8ToJavaString(env
, params
.base_url
.spec()));
134 // See http://crbug.com/251330 for why it's determined this way.
135 url::Replacements
<char> replacements
;
136 replacements
.ClearRef();
137 bool urls_same_ignoring_fragment
=
138 params
.url
.ReplaceComponents(replacements
) ==
139 details
.previous_url
.ReplaceComponents(replacements
);
141 // is_fragment_navigation is indicative of the intent of this variable.
142 // However, there isn't sufficient information here to determine whether this
143 // is actually a fragment navigation, or a history API navigation to a URL
144 // that would also be valid for a fragment navigation.
145 bool is_fragment_navigation
= urls_same_ignoring_fragment
&&
146 (details
.type
== NAVIGATION_TYPE_IN_PAGE
|| details
.is_in_page
);
147 Java_WebContentsObserverAndroid_didNavigateMainFrame(
148 env
, obj
.obj(), jstring_url
.obj(), jstring_base_url
.obj(),
149 details
.is_navigation_to_different_page(), is_fragment_navigation
);
152 void WebContentsObserverAndroid::DidNavigateAnyFrame(
153 const LoadCommittedDetails
& details
,
154 const FrameNavigateParams
& params
) {
155 JNIEnv
* env
= AttachCurrentThread();
156 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
159 ScopedJavaLocalRef
<jstring
> jstring_url(
160 ConvertUTF8ToJavaString(env
, params
.url
.spec()));
161 ScopedJavaLocalRef
<jstring
> jstring_base_url(
162 ConvertUTF8ToJavaString(env
, params
.base_url
.spec()));
163 jboolean jboolean_is_reload
=
164 PageTransitionCoreTypeIs(params
.transition
, PAGE_TRANSITION_RELOAD
);
166 Java_WebContentsObserverAndroid_didNavigateAnyFrame(
167 env
, obj
.obj(), jstring_url
.obj(), jstring_base_url
.obj(),
171 void WebContentsObserverAndroid::DidStartProvisionalLoadForFrame(
173 int64 parent_frame_id
,
175 const GURL
& validated_url
,
177 bool is_iframe_srcdoc
,
178 RenderViewHost
* render_view_host
) {
179 JNIEnv
* env
= AttachCurrentThread();
180 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
183 ScopedJavaLocalRef
<jstring
> jstring_url(
184 ConvertUTF8ToJavaString(env
, validated_url
.spec()));
185 Java_WebContentsObserverAndroid_didStartProvisionalLoadForFrame(
186 env
, obj
.obj(), frame_id
, parent_frame_id
, is_main_frame
,
187 jstring_url
.obj(), is_error_page
, is_iframe_srcdoc
);
190 void WebContentsObserverAndroid::DidCommitProvisionalLoadForFrame(
192 const base::string16
& frame_unique_name
,
195 PageTransition transition_type
,
196 RenderViewHost
* render_view_host
) {
197 JNIEnv
* env
= AttachCurrentThread();
198 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
201 ScopedJavaLocalRef
<jstring
> jstring_url(
202 ConvertUTF8ToJavaString(env
, url
.spec()));
203 Java_WebContentsObserverAndroid_didCommitProvisionalLoadForFrame(
204 env
, obj
.obj(), frame_id
, is_main_frame
, jstring_url
.obj(),
208 void WebContentsObserverAndroid::DidFinishLoad(
210 const GURL
& validated_url
,
212 RenderViewHost
* render_view_host
) {
213 JNIEnv
* env
= AttachCurrentThread();
214 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
218 std::string url_string
= validated_url
.spec();
219 NavigationEntry
* entry
=
220 web_contents()->GetController().GetLastCommittedEntry();
221 // Note that GetBaseURLForDataURL is only used by the Android WebView.
222 if (entry
&& !entry
->GetBaseURLForDataURL().is_empty())
223 url_string
= entry
->GetBaseURLForDataURL().possibly_invalid_spec();
225 ScopedJavaLocalRef
<jstring
> jstring_url(
226 ConvertUTF8ToJavaString(env
, url_string
));
227 Java_WebContentsObserverAndroid_didFinishLoad(
228 env
, obj
.obj(), frame_id
, jstring_url
.obj(), is_main_frame
);
231 void WebContentsObserverAndroid::DocumentLoadedInFrame(
233 RenderViewHost
* render_view_host
) {
234 JNIEnv
* env
= AttachCurrentThread();
235 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
238 Java_WebContentsObserverAndroid_documentLoadedInFrame(
239 env
, obj
.obj(), frame_id
);
242 void WebContentsObserverAndroid::NavigationEntryCommitted(
243 const LoadCommittedDetails
& load_details
) {
244 JNIEnv
* env
= AttachCurrentThread();
245 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
248 Java_WebContentsObserverAndroid_navigationEntryCommitted(env
, obj
.obj());
251 void WebContentsObserverAndroid::DidAttachInterstitialPage() {
252 JNIEnv
* env
= AttachCurrentThread();
253 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
256 Java_WebContentsObserverAndroid_didAttachInterstitialPage(env
, obj
.obj());
259 void WebContentsObserverAndroid::DidDetachInterstitialPage() {
260 JNIEnv
* env
= AttachCurrentThread();
261 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
264 Java_WebContentsObserverAndroid_didDetachInterstitialPage(env
, obj
.obj());
267 void WebContentsObserverAndroid::DidFailLoadInternal(
268 bool is_provisional_load
,
271 const base::string16
& description
,
273 JNIEnv
* env
= AttachCurrentThread();
274 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
277 ScopedJavaLocalRef
<jstring
> jstring_error_description(
278 ConvertUTF16ToJavaString(env
, description
));
279 ScopedJavaLocalRef
<jstring
> jstring_url(
280 ConvertUTF8ToJavaString(env
, url
.spec()));
282 Java_WebContentsObserverAndroid_didFailLoad(
287 jstring_error_description
.obj(), jstring_url
.obj());
290 void WebContentsObserverAndroid::DidFirstVisuallyNonEmptyPaint() {
291 JNIEnv
* env
= AttachCurrentThread();
292 ScopedJavaLocalRef
<jobject
> obj(weak_java_observer_
.get(env
));
295 Java_WebContentsObserverAndroid_didFirstVisuallyNonEmptyPaint(
299 bool RegisterWebContentsObserverAndroid(JNIEnv
* env
) {
300 return RegisterNativesImpl(env
);
302 } // namespace content