OLD | NEW |
| (Empty) |
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/content_view_client.h" | |
6 | |
7 #include <android/keycodes.h> | |
8 | |
9 #include "base/android/jni_android.h" | |
10 #include "base/android/jni_string.h" | |
11 #include "content/browser/android/content_view_core_impl.h" | |
12 #include "content/browser/android/download_controller.h" | |
13 #include "content/browser/renderer_host/render_view_host_impl.h" | |
14 #include "content/public/browser/render_widget_host_view.h" | |
15 #include "content/public/browser/download_item.h" | |
16 #include "content/public/browser/invalidate_type.h" | |
17 #include "content/public/browser/page_navigator.h" | |
18 #include "content/public/browser/navigation_controller.h" | |
19 #include "content/public/browser/navigation_entry.h" | |
20 #include "content/public/browser/web_contents.h" | |
21 #include "content/public/common/page_transition_types.h" | |
22 #include "content/public/common/referrer.h" | |
23 #include "jni/ContentViewClient_jni.h" | |
24 #include "net/http/http_request_headers.h" | |
25 | |
26 using base::android::AttachCurrentThread; | |
27 using base::android::CheckException; | |
28 using base::android::ConvertUTF8ToJavaString; | |
29 using base::android::ConvertUTF16ToJavaString; | |
30 using base::android::GetClass; | |
31 using base::android::GetMethodID; | |
32 using base::android::HasClass; | |
33 using base::android::ScopedJavaLocalRef; | |
34 | |
35 namespace content { | |
36 | |
37 ContentViewClient::ContentViewClient(JNIEnv* env, jobject obj) | |
38 : weak_java_client_(env, obj) { | |
39 } | |
40 | |
41 ContentViewClient::~ContentViewClient() { | |
42 } | |
43 | |
44 // static | |
45 ContentViewClient* ContentViewClient::CreateNativeContentViewClient( | |
46 JNIEnv* env, jobject obj) { | |
47 DCHECK(obj); | |
48 return new ContentViewClient(env, obj); | |
49 } | |
50 | |
51 void ContentViewClient::OnPageStarted(const GURL& url) { | |
52 JNIEnv* env = AttachCurrentThread(); | |
53 ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); | |
54 if (obj.is_null()) | |
55 return; | |
56 ScopedJavaLocalRef<jstring> jstring_url = | |
57 ConvertUTF8ToJavaString(env, url.spec()); | |
58 Java_ContentViewClient_onPageStarted(env, obj.obj(), jstring_url.obj()); | |
59 } | |
60 | |
61 void ContentViewClient::OnPageFinished(const GURL& url) { | |
62 JNIEnv* env = AttachCurrentThread(); | |
63 ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); | |
64 if (obj.is_null()) | |
65 return; | |
66 ScopedJavaLocalRef<jstring> jstring_url = | |
67 ConvertUTF8ToJavaString(env, url.spec()); | |
68 | |
69 Java_ContentViewClient_onPageFinished(env, obj.obj(), jstring_url.obj()); | |
70 CheckException(env); | |
71 } | |
72 | |
73 void ContentViewClient::OnReceivedError(int error_code, | |
74 const string16& description, | |
75 const GURL& url) { | |
76 JNIEnv* env = AttachCurrentThread(); | |
77 ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); | |
78 if (obj.is_null()) | |
79 return; | |
80 ScopedJavaLocalRef<jstring> jstring_error_description = | |
81 ConvertUTF8ToJavaString(env, url.spec()); | |
82 ScopedJavaLocalRef<jstring> jstring_url = | |
83 ConvertUTF8ToJavaString(env, url.spec()); | |
84 | |
85 Java_ContentViewClient_onReceivedError( | |
86 env, obj.obj(), | |
87 ToContentViewClientError(error_code), | |
88 jstring_error_description.obj(), jstring_url.obj()); | |
89 } | |
90 | |
91 void ContentViewClient::OnDidCommitMainFrame(const GURL& url, | |
92 const GURL& base_url) { | |
93 JNIEnv* env = AttachCurrentThread(); | |
94 ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); | |
95 if (obj.is_null()) | |
96 return; | |
97 ScopedJavaLocalRef<jstring> jstring_url = | |
98 ConvertUTF8ToJavaString(env, url.spec()); | |
99 ScopedJavaLocalRef<jstring> jstring_base_url = | |
100 ConvertUTF8ToJavaString(env, base_url.spec()); | |
101 | |
102 Java_ContentViewClient_onMainFrameCommitted( | |
103 env, obj.obj(), | |
104 jstring_url.obj(), jstring_base_url.obj()); | |
105 } | |
106 | |
107 void ContentViewClient::OnInterstitialShown() { | |
108 JNIEnv* env = AttachCurrentThread(); | |
109 ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); | |
110 if (obj.is_null()) | |
111 return; | |
112 Java_ContentViewClient_onInterstitialShown(env, obj.obj()); | |
113 } | |
114 | |
115 void ContentViewClient::OnInterstitialHidden() { | |
116 JNIEnv* env = AttachCurrentThread(); | |
117 ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); | |
118 if (obj.is_null()) | |
119 return; | |
120 Java_ContentViewClient_onInterstitialHidden(env, obj.obj()); | |
121 } | |
122 | |
123 bool ContentViewClient::OnJSModalDialog(JavaScriptMessageType type, | |
124 bool is_before_unload_dialog, | |
125 const GURL& url, | |
126 const string16& message, | |
127 const string16& default_value) { | |
128 JNIEnv* env = AttachCurrentThread(); | |
129 ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); | |
130 if (obj.is_null()) | |
131 return false; | |
132 ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(env, url.spec())); | |
133 ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message)); | |
134 | |
135 // Special case for beforeunload dialogs, as that isn't encoded in the | |
136 // |type| of the dialog. | |
137 if (is_before_unload_dialog) { | |
138 return Java_ContentViewClient_onJsBeforeUnload( | |
139 env, obj.obj(), | |
140 jurl.obj(), | |
141 jmessage.obj()); | |
142 } | |
143 | |
144 switch (type) { | |
145 case JAVASCRIPT_MESSAGE_TYPE_ALERT: | |
146 return Java_ContentViewClient_onJsAlert(env, obj.obj(), | |
147 jurl.obj(), | |
148 jmessage.obj()); | |
149 | |
150 case JAVASCRIPT_MESSAGE_TYPE_CONFIRM: | |
151 return Java_ContentViewClient_onJsConfirm(env, obj.obj(), | |
152 jurl.obj(), | |
153 jmessage.obj()); | |
154 | |
155 case JAVASCRIPT_MESSAGE_TYPE_PROMPT: { | |
156 ScopedJavaLocalRef<jstring> jdefault_value( | |
157 ConvertUTF16ToJavaString(env, default_value)); | |
158 return Java_ContentViewClient_onJsPrompt(env, obj.obj(), | |
159 jurl.obj(), | |
160 jmessage.obj(), | |
161 jdefault_value.obj()); | |
162 } | |
163 | |
164 default: | |
165 NOTREACHED(); | |
166 return false; | |
167 } | |
168 } | |
169 | |
170 ContentViewClientError ContentViewClient::ToContentViewClientError( | |
171 int net_error) { | |
172 // Note: many net::Error constants don't have an obvious mapping. | |
173 // These will be handled by the default case, ERROR_UNKNOWN. | |
174 switch(net_error) { | |
175 case net::ERR_UNSUPPORTED_AUTH_SCHEME: | |
176 return CONTENT_VIEW_CLIENT_ERROR_UNSUPPORTED_AUTH_SCHEME; | |
177 | |
178 case net::ERR_INVALID_AUTH_CREDENTIALS: | |
179 case net::ERR_MISSING_AUTH_CREDENTIALS: | |
180 case net::ERR_MISCONFIGURED_AUTH_ENVIRONMENT: | |
181 return CONTENT_VIEW_CLIENT_ERROR_AUTHENTICATION; | |
182 | |
183 case net::ERR_TOO_MANY_REDIRECTS: | |
184 return CONTENT_VIEW_CLIENT_ERROR_REDIRECT_LOOP; | |
185 | |
186 case net::ERR_UPLOAD_FILE_CHANGED: | |
187 return CONTENT_VIEW_CLIENT_ERROR_FILE_NOT_FOUND; | |
188 | |
189 case net::ERR_INVALID_URL: | |
190 return CONTENT_VIEW_CLIENT_ERROR_BAD_URL; | |
191 | |
192 case net::ERR_DISALLOWED_URL_SCHEME: | |
193 case net::ERR_UNKNOWN_URL_SCHEME: | |
194 return CONTENT_VIEW_CLIENT_ERROR_UNSUPPORTED_SCHEME; | |
195 | |
196 case net::ERR_IO_PENDING: | |
197 case net::ERR_NETWORK_IO_SUSPENDED: | |
198 return CONTENT_VIEW_CLIENT_ERROR_IO; | |
199 | |
200 case net::ERR_CONNECTION_TIMED_OUT: | |
201 case net::ERR_TIMED_OUT: | |
202 return CONTENT_VIEW_CLIENT_ERROR_TIMEOUT; | |
203 | |
204 case net::ERR_FILE_TOO_BIG: | |
205 return CONTENT_VIEW_CLIENT_ERROR_FILE; | |
206 | |
207 case net::ERR_HOST_RESOLVER_QUEUE_TOO_LARGE: | |
208 case net::ERR_INSUFFICIENT_RESOURCES: | |
209 case net::ERR_OUT_OF_MEMORY: | |
210 return CONTENT_VIEW_CLIENT_ERROR_TOO_MANY_REQUESTS; | |
211 | |
212 case net::ERR_CONNECTION_CLOSED: | |
213 case net::ERR_CONNECTION_RESET: | |
214 case net::ERR_CONNECTION_REFUSED: | |
215 case net::ERR_CONNECTION_ABORTED: | |
216 case net::ERR_CONNECTION_FAILED: | |
217 case net::ERR_SOCKET_NOT_CONNECTED: | |
218 return CONTENT_VIEW_CLIENT_ERROR_CONNECT; | |
219 | |
220 case net::ERR_INTERNET_DISCONNECTED: | |
221 case net::ERR_ADDRESS_INVALID: | |
222 case net::ERR_ADDRESS_UNREACHABLE: | |
223 case net::ERR_NAME_NOT_RESOLVED: | |
224 case net::ERR_NAME_RESOLUTION_FAILED: | |
225 return CONTENT_VIEW_CLIENT_ERROR_HOST_LOOKUP; | |
226 | |
227 case net::ERR_SSL_PROTOCOL_ERROR: | |
228 case net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED: | |
229 case net::ERR_TUNNEL_CONNECTION_FAILED: | |
230 case net::ERR_NO_SSL_VERSIONS_ENABLED: | |
231 case net::ERR_SSL_VERSION_OR_CIPHER_MISMATCH: | |
232 case net::ERR_SSL_RENEGOTIATION_REQUESTED: | |
233 case net::ERR_CERT_ERROR_IN_SSL_RENEGOTIATION: | |
234 case net::ERR_BAD_SSL_CLIENT_AUTH_CERT: | |
235 case net::ERR_SSL_NO_RENEGOTIATION: | |
236 case net::ERR_SSL_DECOMPRESSION_FAILURE_ALERT: | |
237 case net::ERR_SSL_BAD_RECORD_MAC_ALERT: | |
238 case net::ERR_SSL_UNSAFE_NEGOTIATION: | |
239 case net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY: | |
240 case net::ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: | |
241 case net::ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: | |
242 return CONTENT_VIEW_CLIENT_ERROR_FAILED_SSL_HANDSHAKE; | |
243 | |
244 case net::ERR_PROXY_AUTH_UNSUPPORTED: | |
245 case net::ERR_PROXY_AUTH_REQUESTED: | |
246 case net::ERR_PROXY_CONNECTION_FAILED: | |
247 case net::ERR_UNEXPECTED_PROXY_AUTH: | |
248 return CONTENT_VIEW_CLIENT_ERROR_PROXY_AUTHENTICATION; | |
249 | |
250 /* The certificate errors are handled by onReceivedSslError | |
251 * and don't need to be reported here. | |
252 */ | |
253 case net::ERR_CERT_COMMON_NAME_INVALID: | |
254 case net::ERR_CERT_DATE_INVALID: | |
255 case net::ERR_CERT_AUTHORITY_INVALID: | |
256 case net::ERR_CERT_CONTAINS_ERRORS: | |
257 case net::ERR_CERT_NO_REVOCATION_MECHANISM: | |
258 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION: | |
259 case net::ERR_CERT_REVOKED: | |
260 case net::ERR_CERT_INVALID: | |
261 case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM: | |
262 case net::ERR_CERT_NON_UNIQUE_NAME: | |
263 return CONTENT_VIEW_CLIENT_ERROR_OK; | |
264 | |
265 default: | |
266 VLOG(1) << "ContentViewClient::ToContentViewClientError: Unknown " | |
267 << "chromium error: " | |
268 << net_error; | |
269 return CONTENT_VIEW_CLIENT_ERROR_UNKNOWN; | |
270 } | |
271 } | |
272 | |
273 // ---------------------------------------------------------------------------- | |
274 // Native JNI methods | |
275 // ---------------------------------------------------------------------------- | |
276 | |
277 // Register native methods | |
278 | |
279 bool RegisterContentViewClient(JNIEnv* env) { | |
280 if (!HasClass(env, kContentViewClientClassPath)) { | |
281 DLOG(ERROR) << "Unable to find class ContentViewClient!"; | |
282 return false; | |
283 } | |
284 return RegisterNativesImpl(env); | |
285 } | |
286 | |
287 } // namespace content | |
OLD | NEW |