Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: android_webview/native/android_protocol_handler.cc

Issue 2863233002: [WebView] Move files from native to browser (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 "android_webview/native/android_protocol_handler.h"
6
7 #include <utility>
8
9 #include "android_webview/browser/net/android_stream_reader_url_request_job.h"
10 #include "android_webview/browser/net/aw_url_request_job_factory.h"
11 #include "android_webview/common/url_constants.h"
12 #include "android_webview/native/input_stream_impl.h"
13 #include "base/android/jni_android.h"
14 #include "base/android/jni_string.h"
15 #include "base/android/jni_weak_ref.h"
16 #include "base/memory/ptr_util.h"
17 #include "content/public/common/url_constants.h"
18 #include "jni/AndroidProtocolHandler_jni.h"
19 #include "net/base/io_buffer.h"
20 #include "net/base/mime_util.h"
21 #include "net/base/net_errors.h"
22 #include "net/http/http_util.h"
23 #include "net/url_request/url_request.h"
24 #include "net/url_request/url_request_interceptor.h"
25 #include "url/gurl.h"
26 #include "url/url_constants.h"
27
28 using android_webview::AndroidStreamReaderURLRequestJob;
29 using android_webview::InputStream;
30 using android_webview::InputStreamImpl;
31 using base::android::AttachCurrentThread;
32 using base::android::ClearException;
33 using base::android::ConvertUTF8ToJavaString;
34 using base::android::JavaParamRef;
35 using base::android::ScopedJavaGlobalRef;
36 using base::android::ScopedJavaLocalRef;
37
38 namespace {
39
40 void* kPreviouslyFailedKey = &kPreviouslyFailedKey;
41
42 void MarkRequestAsFailed(net::URLRequest* request) {
43 request->SetUserData(kPreviouslyFailedKey,
44 base::MakeUnique<base::SupportsUserData::Data>());
45 }
46
47 bool HasRequestPreviouslyFailed(net::URLRequest* request) {
48 return request->GetUserData(kPreviouslyFailedKey) != NULL;
49 }
50
51 class AndroidStreamReaderURLRequestJobDelegateImpl
52 : public AndroidStreamReaderURLRequestJob::Delegate {
53 public:
54 AndroidStreamReaderURLRequestJobDelegateImpl();
55
56 std::unique_ptr<InputStream> OpenInputStream(JNIEnv* env,
57 const GURL& url) override;
58
59 void OnInputStreamOpenFailed(net::URLRequest* request,
60 bool* restart) override;
61
62 bool GetMimeType(JNIEnv* env,
63 net::URLRequest* request,
64 InputStream* stream,
65 std::string* mime_type) override;
66
67 bool GetCharset(JNIEnv* env,
68 net::URLRequest* request,
69 InputStream* stream,
70 std::string* charset) override;
71
72 void AppendResponseHeaders(JNIEnv* env,
73 net::HttpResponseHeaders* headers) override;
74
75 ~AndroidStreamReaderURLRequestJobDelegateImpl() override;
76 };
77
78 class AndroidRequestInterceptorBase : public net::URLRequestInterceptor {
79 public:
80 net::URLRequestJob* MaybeInterceptRequest(
81 net::URLRequest* request,
82 net::NetworkDelegate* network_delegate) const override;
83
84 virtual bool ShouldHandleRequest(const net::URLRequest* request) const = 0;
85 };
86
87 class AssetFileRequestInterceptor : public AndroidRequestInterceptorBase {
88 public:
89 AssetFileRequestInterceptor();
90 bool ShouldHandleRequest(const net::URLRequest* request) const override;
91 };
92
93 // Protocol handler for content:// scheme requests.
94 class ContentSchemeRequestInterceptor : public AndroidRequestInterceptorBase {
95 public:
96 ContentSchemeRequestInterceptor();
97 bool ShouldHandleRequest(const net::URLRequest* request) const override;
98 };
99
100 // AndroidStreamReaderURLRequestJobDelegateImpl -------------------------------
101
102 AndroidStreamReaderURLRequestJobDelegateImpl::
103 AndroidStreamReaderURLRequestJobDelegateImpl() {}
104
105 AndroidStreamReaderURLRequestJobDelegateImpl::
106 ~AndroidStreamReaderURLRequestJobDelegateImpl() {
107 }
108
109 std::unique_ptr<InputStream>
110 AndroidStreamReaderURLRequestJobDelegateImpl::OpenInputStream(JNIEnv* env,
111 const GURL& url) {
112 DCHECK(url.is_valid());
113 DCHECK(env);
114
115 // Open the input stream.
116 ScopedJavaLocalRef<jstring> jurl =
117 ConvertUTF8ToJavaString(env, url.spec());
118 ScopedJavaLocalRef<jobject> stream =
119 android_webview::Java_AndroidProtocolHandler_open(env, jurl);
120
121 if (stream.is_null()) {
122 DLOG(ERROR) << "Unable to open input stream for Android URL";
123 return std::unique_ptr<InputStream>();
124 }
125 return base::MakeUnique<InputStreamImpl>(stream);
126 }
127
128 void AndroidStreamReaderURLRequestJobDelegateImpl::OnInputStreamOpenFailed(
129 net::URLRequest* request,
130 bool* restart) {
131 DCHECK(!HasRequestPreviouslyFailed(request));
132 MarkRequestAsFailed(request);
133 *restart = true;
134 }
135
136 bool AndroidStreamReaderURLRequestJobDelegateImpl::GetMimeType(
137 JNIEnv* env,
138 net::URLRequest* request,
139 android_webview::InputStream* stream,
140 std::string* mime_type) {
141 DCHECK(env);
142 DCHECK(request);
143 DCHECK(mime_type);
144
145 // Query the mime type from the Java side. It is possible for the query to
146 // fail, as the mime type cannot be determined for all supported schemes.
147 ScopedJavaLocalRef<jstring> url =
148 ConvertUTF8ToJavaString(env, request->url().spec());
149 const InputStreamImpl* stream_impl =
150 InputStreamImpl::FromInputStream(stream);
151 ScopedJavaLocalRef<jstring> returned_type =
152 android_webview::Java_AndroidProtocolHandler_getMimeType(
153 env, stream_impl->jobj(), url);
154 if (returned_type.is_null())
155 return false;
156
157 *mime_type = base::android::ConvertJavaStringToUTF8(returned_type);
158 return true;
159 }
160
161 bool AndroidStreamReaderURLRequestJobDelegateImpl::GetCharset(
162 JNIEnv* env,
163 net::URLRequest* request,
164 android_webview::InputStream* stream,
165 std::string* charset) {
166 // TODO: We should probably be getting this from the managed side.
167 return false;
168 }
169
170 void AndroidStreamReaderURLRequestJobDelegateImpl::AppendResponseHeaders(
171 JNIEnv* env,
172 net::HttpResponseHeaders* headers) {
173 // no-op
174 }
175
176 // AndroidRequestInterceptorBase ----------------------------------------------
177
178 net::URLRequestJob* AndroidRequestInterceptorBase::MaybeInterceptRequest(
179 net::URLRequest* request,
180 net::NetworkDelegate* network_delegate) const {
181 if (!ShouldHandleRequest(request))
182 return NULL;
183
184 // For WebViewClassic compatibility this job can only accept URLs that can be
185 // opened. URLs that cannot be opened should be resolved by the next handler.
186 //
187 // If a request is initially handled here but the job fails due to it being
188 // unable to open the InputStream for that request the request is marked as
189 // previously failed and restarted.
190 // Restarting a request involves creating a new job for that request. This
191 // handler will ignore requests know to have previously failed to 1) prevent
192 // an infinite loop, 2) ensure that the next handler in line gets the
193 // opportunity to create a job for the request.
194 if (HasRequestPreviouslyFailed(request))
195 return NULL;
196
197 std::unique_ptr<AndroidStreamReaderURLRequestJobDelegateImpl> reader_delegate(
198 new AndroidStreamReaderURLRequestJobDelegateImpl());
199
200 return new AndroidStreamReaderURLRequestJob(request, network_delegate,
201 std::move(reader_delegate));
202 }
203
204 // AssetFileRequestInterceptor ------------------------------------------------
205
206 AssetFileRequestInterceptor::AssetFileRequestInterceptor() {
207 }
208
209 bool AssetFileRequestInterceptor::ShouldHandleRequest(
210 const net::URLRequest* request) const {
211 return android_webview::IsAndroidSpecialFileUrl(request->url());
212 }
213
214 // ContentSchemeRequestInterceptor --------------------------------------------
215
216 ContentSchemeRequestInterceptor::ContentSchemeRequestInterceptor() {
217 }
218
219 bool ContentSchemeRequestInterceptor::ShouldHandleRequest(
220 const net::URLRequest* request) const {
221 return request->url().SchemeIs(url::kContentScheme);
222 }
223
224 } // namespace
225
226 namespace android_webview {
227
228 bool RegisterAndroidProtocolHandler(JNIEnv* env) {
229 return RegisterNativesImpl(env);
230 }
231
232 // static
233 std::unique_ptr<net::URLRequestInterceptor>
234 CreateContentSchemeRequestInterceptor() {
235 return base::MakeUnique<ContentSchemeRequestInterceptor>();
236 }
237
238 // static
239 std::unique_ptr<net::URLRequestInterceptor>
240 CreateAssetFileRequestInterceptor() {
241 return std::unique_ptr<net::URLRequestInterceptor>(
242 new AssetFileRequestInterceptor());
243 }
244
245 static ScopedJavaLocalRef<jstring> GetAndroidAssetPath(
246 JNIEnv* env,
247 const JavaParamRef<jclass>& /*clazz*/) {
248 return ConvertUTF8ToJavaString(env, android_webview::kAndroidAssetPath);
249 }
250
251 static ScopedJavaLocalRef<jstring> GetAndroidResourcePath(
252 JNIEnv* env,
253 const JavaParamRef<jclass>& /*clazz*/) {
254 return ConvertUTF8ToJavaString(env, android_webview::kAndroidResourcePath);
255 }
256
257 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698