Home | History | Annotate | Download | only in android
      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/android/web_contents_observer_android.h"
      6 
      7 #include <string>
      8 
      9 #include <jni.h>
     10 
     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/android/content_view_core_impl.h"
     15 #include "content/browser/renderer_host/render_widget_host_impl.h"
     16 #include "content/browser/web_contents/web_contents_impl.h"
     17 #include "content/public/browser/navigation_details.h"
     18 #include "content/public/browser/navigation_entry.h"
     19 #include "jni/WebContentsObserverAndroid_jni.h"
     20 
     21 using base::android::AttachCurrentThread;
     22 using base::android::ScopedJavaLocalRef;
     23 using base::android::ConvertUTF8ToJavaString;
     24 using base::android::ConvertUTF16ToJavaString;
     25 using base::android::HasClass;
     26 
     27 namespace content {
     28 
     29 WebContentsObserverAndroid::WebContentsObserverAndroid(
     30     JNIEnv* env,
     31     jobject obj,
     32     WebContents* web_contents)
     33     : WebContentsObserver(web_contents),
     34       weak_java_observer_(env, obj){
     35 }
     36 
     37 WebContentsObserverAndroid::~WebContentsObserverAndroid() {
     38 }
     39 
     40 jint Init(JNIEnv* env, jobject obj, jint native_content_view_core) {
     41   ContentViewCore* content_view_core =
     42       reinterpret_cast<ContentViewCore*>(native_content_view_core);
     43   WebContentsObserverAndroid* native_observer = new WebContentsObserverAndroid(
     44       env, obj, content_view_core->GetWebContents());
     45   return reinterpret_cast<jint>(native_observer);
     46 }
     47 
     48 void WebContentsObserverAndroid::Destroy(JNIEnv* env, jobject obj) {
     49   delete this;
     50 }
     51 
     52 void WebContentsObserverAndroid::WebContentsDestroyed(
     53     WebContents* web_contents) {
     54   JNIEnv* env = AttachCurrentThread();
     55   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
     56   if (obj.is_null()) {
     57     delete this;
     58   } else {
     59     // The java side will destroy |this|
     60     Java_WebContentsObserverAndroid_detachFromWebContents(env, obj.obj());
     61   }
     62 }
     63 
     64 void WebContentsObserverAndroid::DidStartLoading(
     65     RenderViewHost* render_view_host) {
     66   JNIEnv* env = AttachCurrentThread();
     67   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
     68   if (obj.is_null())
     69     return;
     70   ScopedJavaLocalRef<jstring> jstring_url(
     71       ConvertUTF8ToJavaString(env, web_contents()->GetURL().spec()));
     72   Java_WebContentsObserverAndroid_didStartLoading(
     73       env, obj.obj(), jstring_url.obj());
     74 }
     75 
     76 void WebContentsObserverAndroid::DidStopLoading(
     77     RenderViewHost* render_view_host) {
     78   JNIEnv* env = AttachCurrentThread();
     79   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
     80   if (obj.is_null())
     81     return;
     82 
     83   std::string url_string;
     84   NavigationEntry* entry =
     85     web_contents()->GetController().GetLastCommittedEntry();
     86   // Not that GetBaseURLForDataURL is only used by the Android WebView
     87   if (entry && !entry->GetBaseURLForDataURL().is_empty()) {
     88     url_string = entry->GetBaseURLForDataURL().possibly_invalid_spec();
     89   } else {
     90     url_string = web_contents()->GetURL().spec();
     91   }
     92 
     93   ScopedJavaLocalRef<jstring> jstring_url(
     94       ConvertUTF8ToJavaString(env, url_string));
     95   Java_WebContentsObserverAndroid_didStopLoading(
     96       env, obj.obj(), jstring_url.obj());
     97 }
     98 
     99 void WebContentsObserverAndroid::DidFailProvisionalLoad(
    100     int64 frame_id,
    101     bool is_main_frame,
    102     const GURL& validated_url,
    103     int error_code,
    104     const string16& error_description,
    105     RenderViewHost* render_view_host) {
    106   DidFailLoadInternal(
    107         true, is_main_frame, error_code, error_description, validated_url);
    108 }
    109 
    110 void WebContentsObserverAndroid::DidFailLoad(
    111     int64 frame_id,
    112     const GURL& validated_url,
    113     bool is_main_frame,
    114     int error_code,
    115     const string16& error_description,
    116     RenderViewHost* render_view_host) {
    117   DidFailLoadInternal(
    118         false, is_main_frame, error_code, error_description, validated_url);
    119 }
    120 
    121 void WebContentsObserverAndroid::DidNavigateMainFrame(
    122     const LoadCommittedDetails& details,
    123     const FrameNavigateParams& params) {
    124   JNIEnv* env = AttachCurrentThread();
    125   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
    126   if (obj.is_null())
    127     return;
    128   ScopedJavaLocalRef<jstring> jstring_url(
    129       ConvertUTF8ToJavaString(env, params.url.spec()));
    130   ScopedJavaLocalRef<jstring> jstring_base_url(
    131       ConvertUTF8ToJavaString(env, params.base_url.spec()));
    132   Java_WebContentsObserverAndroid_didNavigateMainFrame(
    133       env, obj.obj(), jstring_url.obj(), jstring_base_url.obj(),
    134       details.is_navigation_to_different_page());
    135 }
    136 
    137 void WebContentsObserverAndroid::DidNavigateAnyFrame(
    138     const LoadCommittedDetails& details,
    139     const FrameNavigateParams& params) {
    140   JNIEnv* env = AttachCurrentThread();
    141   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
    142   if (obj.is_null())
    143     return;
    144   ScopedJavaLocalRef<jstring> jstring_url(
    145       ConvertUTF8ToJavaString(env, params.url.spec()));
    146   ScopedJavaLocalRef<jstring> jstring_base_url(
    147       ConvertUTF8ToJavaString(env, params.base_url.spec()));
    148   jboolean jboolean_is_reload =
    149       PageTransitionCoreTypeIs(params.transition, PAGE_TRANSITION_RELOAD);
    150 
    151   Java_WebContentsObserverAndroid_didNavigateAnyFrame(
    152       env, obj.obj(), jstring_url.obj(), jstring_base_url.obj(),
    153       jboolean_is_reload);
    154 }
    155 
    156 void WebContentsObserverAndroid::DidStartProvisionalLoadForFrame(
    157       int64 frame_id,
    158       int64 parent_frame_id,
    159       bool is_main_frame,
    160       const GURL& validated_url,
    161       bool is_error_page,
    162       bool is_iframe_srcdoc,
    163       RenderViewHost* render_view_host) {
    164   JNIEnv* env = AttachCurrentThread();
    165   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
    166   if (obj.is_null())
    167     return;
    168   ScopedJavaLocalRef<jstring> jstring_url(
    169       ConvertUTF8ToJavaString(env, validated_url.spec()));
    170   Java_WebContentsObserverAndroid_didStartProvisionalLoadForFrame(
    171       env, obj.obj(), frame_id, parent_frame_id, is_main_frame,
    172       jstring_url.obj(), is_error_page, is_iframe_srcdoc);
    173 }
    174 
    175 void WebContentsObserverAndroid::DidCommitProvisionalLoadForFrame(
    176       int64 frame_id,
    177       bool is_main_frame,
    178       const GURL& url,
    179       PageTransition transition_type,
    180       RenderViewHost* render_view_host) {
    181   JNIEnv* env = AttachCurrentThread();
    182   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
    183   if (obj.is_null())
    184     return;
    185   ScopedJavaLocalRef<jstring> jstring_url(
    186       ConvertUTF8ToJavaString(env, url.spec()));
    187   Java_WebContentsObserverAndroid_didCommitProvisionalLoadForFrame(
    188       env, obj.obj(), frame_id, is_main_frame, jstring_url.obj(),
    189       transition_type);
    190 }
    191 
    192 void WebContentsObserverAndroid::DidFinishLoad(
    193     int64 frame_id,
    194     const GURL& validated_url,
    195     bool is_main_frame,
    196     RenderViewHost* render_view_host) {
    197   JNIEnv* env = AttachCurrentThread();
    198   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
    199   if (obj.is_null())
    200     return;
    201   ScopedJavaLocalRef<jstring> jstring_url(
    202       ConvertUTF8ToJavaString(env, validated_url.spec()));
    203   Java_WebContentsObserverAndroid_didFinishLoad(
    204       env, obj.obj(), frame_id, jstring_url.obj(), is_main_frame);
    205 }
    206 
    207 void WebContentsObserverAndroid::DidChangeVisibleSSLState() {
    208   JNIEnv* env = AttachCurrentThread();
    209   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
    210   if (obj.is_null())
    211     return;
    212   Java_WebContentsObserverAndroid_didChangeVisibleSSLState(env, obj.obj());
    213 }
    214 
    215 void WebContentsObserverAndroid::DidFailLoadInternal(
    216     bool is_provisional_load,
    217     bool is_main_frame,
    218     int error_code,
    219     const string16& description,
    220     const GURL& url) {
    221   JNIEnv* env = AttachCurrentThread();
    222   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
    223   if (obj.is_null())
    224     return;
    225   ScopedJavaLocalRef<jstring> jstring_error_description(
    226       ConvertUTF16ToJavaString(env, description));
    227   ScopedJavaLocalRef<jstring> jstring_url(
    228       ConvertUTF8ToJavaString(env, url.spec()));
    229 
    230   Java_WebContentsObserverAndroid_didFailLoad(
    231       env, obj.obj(),
    232       is_provisional_load,
    233       is_main_frame,
    234       error_code,
    235       jstring_error_description.obj(), jstring_url.obj());
    236 }
    237 
    238 bool RegisterWebContentsObserverAndroid(JNIEnv* env) {
    239   if (!HasClass(env, kWebContentsObserverAndroidClassPath)) {
    240     DLOG(ERROR) << "Unable to find class WebContentsObserverAndroid!";
    241     return false;
    242   }
    243   return RegisterNativesImpl(env);
    244 }
    245 }  // namespace content
    246