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

Side by Side Diff: content/browser/android/download_controller.cc

Issue 10449017: Add android download controller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Few comments added. Created 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
jochen (gone - plz use gerrit) 2012/05/25 21:29:37 2012
nilesh 2012/05/25 23:10:22 Done.
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/download_controller.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "content/browser/renderer_host/render_view_host_delegate.h"
13 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/download_item.h"
16 #include "content/public/browser/global_request_id.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "jni/download_controller_jni.h"
21 #include "net/cookies/cookie_options.h"
22 #include "net/cookies/cookie_store.h"
23 #include "net/http/http_request_headers.h"
24 #include "net/url_request/url_request.h"
25 #include "net/url_request/url_request_context.h"
26
27 using base::android::AttachCurrentThread;
28 using base::android::CheckException;
29 using base::android::ConvertUTF8ToJavaString;
30 using base::android::GetClass;
31 using base::android::ScopedJavaLocalRef;
32 using content::BrowserThread;
33 using content::DownloadItem;
34 using content::RenderViewHost;
35 using content::WebContents;
36
37 // JNI methods
38 static void Init(JNIEnv* env, jobject obj) {
jochen (gone - plz use gerrit) 2012/05/25 21:29:37 where is this invoked from? Can it be in the anony
nilesh 2012/05/25 23:10:22 Its called via JNI from DownloadController.java (c
39 DownloadController::GetInstance()->Init(env, obj);
40 }
41
42 namespace {
43
44 static const char* kDownloadControllerClassPathName =
jochen (gone - plz use gerrit) 2012/05/25 21:29:37 no static required
nilesh 2012/05/25 23:10:22 Done.
45 "org/chromium/content/browser/DownloadController";
46
47 } // namespace
48
49 bool RegisterDownloadController(JNIEnv* env) {
50 return RegisterNativesImpl(env);
51 }
52
53 // DownloadController implementation
54
55 struct DownloadController::JavaObject {
56 jweak obj;
jochen (gone - plz use gerrit) 2012/05/25 21:29:37 variables after methods
nilesh 2012/05/25 23:10:22 Done.
57 ScopedJavaLocalRef<jobject> Controller(JNIEnv* env) {
58 return GetRealObject(env, obj);
59 }
60 };
61
62 // static
63 DownloadController* DownloadController::GetInstance() {
64 return Singleton<DownloadController>::get();
65 }
66
67 DownloadController::DownloadController()
68 : java_object_(NULL) {
69 }
70
71 DownloadController::~DownloadController() {
72 if (java_object_) {
73 JNIEnv* env = AttachCurrentThread();
74 env->DeleteWeakGlobalRef(java_object_->obj);
75 delete java_object_;
76 CheckException(env);
77 }
78 }
79
80 // Initialize references to Java object.
81 void DownloadController::Init(JNIEnv* env, jobject obj) {
82 java_object_ = new JavaObject;
83 java_object_->obj = env->NewWeakGlobalRef(obj);
84 }
85
86 void DownloadController::NewGetDownload(
87 content::RenderViewHost* render_view_host,
88 int request_id) {
89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
90 int render_process_id = render_view_host->GetProcess()->GetID();
91 content::GlobalRequestID global_id(
92 render_process_id, request_id);
jochen (gone - plz use gerrit) 2012/05/25 21:29:37 should fit on previous line?
nilesh 2012/05/25 23:10:22 Done.
93
94 // We are yielding the UI thread and render_view_host may go away by
95 // the time we come back. Pass along render_process_id and render_view_id
96 // to retrieve it later (if it still exists).
97 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
98 base::Bind(&DownloadController::PrepareDownloadInfo,
99 base::Unretained(this), global_id,
100 render_process_id,
101 render_view_host->GetRoutingID()));
102 }
103
104 void DownloadController::PrepareDownloadInfo(
105 const content::GlobalRequestID& global_id,
106 int render_process_id, int render_view_id) {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
108
109 net::URLRequest* request =
110 content::ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
111 DCHECK(request) << "Request to download not found.";
112
113 DownloadInfoAndroid info_android(request);
114 net::CookieOptions options;
115 options.set_include_httponly();
116
117 request->context()->cookie_store()->GetCookiesWithOptionsAsync(
jochen (gone - plz use gerrit) 2012/05/25 21:29:37 please ask the request context' network delegate w
nilesh 2012/05/25 23:10:22 NetworkDelegate::CanGetCookies needs a CookieList.
118 info_android.url, options,
119 base::Bind(&DownloadController::OnCookieResponse,
120 base::Unretained(this), info_android, render_process_id,
121 render_view_id));
122 }
123
124 void DownloadController::OnCookieResponse(DownloadInfoAndroid download_info,
125 int render_process_id,
126 int render_view_id,
127 const std::string& cookie) {
128 download_info.cookie = cookie;
129
130 // We have everything we need, start Android download on the UI thread.
131 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
132 base::Bind(&DownloadController::StartAndroidDownload,
133 base::Unretained(this), download_info, render_process_id,
134 render_view_id));
135 }
136
137 void DownloadController::StartAndroidDownload(
138 const DownloadInfoAndroid& info,
139 int render_process_id,
140 int render_view_id) {
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
142 JNIEnv* env = AttachCurrentThread();
143
144 // Call newHttpGetDownload
145 jobject view = GetContentView(render_process_id, render_view_id);
146 if (!view) {
147 // The view went away. Can't proceed.
148 LOG(ERROR) << "Download failed on URL:" << info.url.spec();
149 return;
150 }
151
152 ScopedJavaLocalRef<jstring> jurl =
153 ConvertUTF8ToJavaString(env, info.url.spec());
154 ScopedJavaLocalRef<jstring> juser_agent =
155 ConvertUTF8ToJavaString(env, info.user_agent);
156 ScopedJavaLocalRef<jstring> jcontent_disposition =
157 ConvertUTF8ToJavaString(env, info.content_disposition);
158 ScopedJavaLocalRef<jstring> jmime_type =
159 ConvertUTF8ToJavaString(env, info.original_mime_type);
160 ScopedJavaLocalRef<jstring> jcookie =
161 ConvertUTF8ToJavaString(env, info.cookie);
162
163 Java_DownloadController_newHttpGetDownload(env,
jochen (gone - plz use gerrit) 2012/05/25 21:29:37 env should go on the next line
nilesh 2012/05/25 23:10:22 Done.
164 java_object()->Controller(env).obj(), view, jurl.obj(), juser_agent.obj(),
165 jcontent_disposition.obj(), jmime_type.obj(), jcookie.obj(),
166 info.total_bytes);
167 }
168
169 void DownloadController::OnPostDownloadStarted(
170 WebContents* web_contents,
171 DownloadItem* download_item) {
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
173 JNIEnv* env = AttachCurrentThread();
174
175 // Register for updates to the DownloadItem.
176 download_item->AddObserver(this);
177
178 jobject view = GetContentViewFromWebContents(web_contents);
179 if(!view) {
180 // The view went away. Can't proceed.
181 return;
182 }
183
184 Java_DownloadController_onHttpPostDownloadStarted(
185 env, java_object()->Controller(env).obj(), view);
186 }
187
188 void DownloadController::OnDownloadUpdated(DownloadItem* item) {
189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
190
191 if (item->GetState() != DownloadItem::COMPLETE)
192 return;
193
194 // Call onHttpPostDownloadCompleted
195 JNIEnv* env = AttachCurrentThread();
196 ScopedJavaLocalRef<jstring> jurl =
197 ConvertUTF8ToJavaString(env, item->GetURL().spec());
198 ScopedJavaLocalRef<jstring> jcontent_disposition =
199 ConvertUTF8ToJavaString(env, item->GetContentDisposition());
200 ScopedJavaLocalRef<jstring> jmime_type =
201 ConvertUTF8ToJavaString(env, item->GetMimeType());
202 ScopedJavaLocalRef<jstring> jpath =
203 ConvertUTF8ToJavaString(env, item->GetFullPath().value());
204
205 jobject view = GetContentViewFromWebContents(item->GetWebContents());
206 if(!view) {
207 // We can get NULL WebContents from the DownloadItem.
208 return;
209 }
210
211 Java_DownloadController_onHttpPostDownloadCompleted(env,
212 java_object()->Controller(env).obj(), view, jurl.obj(),
213 jcontent_disposition.obj(), jmime_type.obj(), jpath.obj(),
214 item->GetReceivedBytes(), true);
215 }
216
217 jobject DownloadController::GetContentView(int render_process_id,
218 int render_view_id) {
219 RenderViewHost* render_view_host =
220 RenderViewHost::FromID(render_process_id, render_view_id);
221
222 if (!render_view_host)
223 return NULL;
224
225 WebContents* web_contents =
226 render_view_host->GetDelegate()->GetAsWebContents();
227
228 if (!web_contents)
229 return NULL;
230
231 return GetContentViewFromWebContents(web_contents);
232 }
233
234 jobject DownloadController::GetContentViewFromWebContents(
235 WebContents* web_contents) {
236 NOTIMPLEMENTED();
237 return NULL;
238 }
239
240 DownloadController::JavaObject* DownloadController::java_object() {
241 if (!java_object_) {
242 // Initialize Java DownloadController by calling
243 // DownloadController.getInstance(), which will call Init()
244 // if Java DownloadController is not instantiated already.
245 JNIEnv* env = AttachCurrentThread();
246 ScopedJavaLocalRef<jclass> clazz =
247 GetClass(env, kDownloadControllerClassPathName);
248 jmethodID get_instance = GetStaticMethodID(env, clazz, "getInstance",
249 "()Lorg/chromium/content/browser/DownloadController;");
250 ScopedJavaLocalRef<jobject> jobj(env,
251 env->CallStaticObjectMethod(clazz.obj(), get_instance));
252 CheckException(env);
253 }
254
255 DCHECK(java_object_);
256 return java_object_;
257 }
258
259 DownloadController::DownloadInfoAndroid::DownloadInfoAndroid(
260 net::URLRequest* request) {
261 request->GetResponseHeaderByName("content-disposition", &content_disposition);
262 request->GetResponseHeaderByName("mime-type", &original_mime_type);
263 request->extra_request_headers().GetHeader(
264 net::HttpRequestHeaders::kUserAgent,
265 &user_agent);
266 if (!request->url_chain().empty()) {
267 original_url = request->url_chain().front();
268 url = request->url_chain().back();
269 }
270 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698