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

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: Address comments 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
« no previous file with comments | « content/browser/android/download_controller.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "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/26 10:12:44 if it's invoked within this compilation unit, you
nilesh 2012/05/29 18:21:22 The method is declared in jni/download_controller_
39 content::DownloadController::GetInstance()->Init(env, obj);
40 }
41
42 namespace {
43 const char* kDownloadControllerClassPathName =
44 "org/chromium/content/browser/DownloadController";
45 } // namespace
46
47 namespace content {
48
49 struct DownloadController::JavaObject {
50 ScopedJavaLocalRef<jobject> Controller(JNIEnv* env) {
51 return GetRealObject(env, obj);
52 }
53 jweak obj;
54 };
55
56 // static
57 bool DownloadController::RegisterDownloadController(JNIEnv* env) {
58 return RegisterNativesImpl(env);
59 }
60
61 DownloadController* DownloadController::GetInstance() {
62 return Singleton<DownloadController>::get();
63 }
64
65 DownloadController::DownloadController()
66 : java_object_(NULL) {
67 }
68
69 DownloadController::~DownloadController() {
70 if (java_object_) {
71 JNIEnv* env = AttachCurrentThread();
72 env->DeleteWeakGlobalRef(java_object_->obj);
73 delete java_object_;
74 CheckException(env);
75 }
76 }
77
78 // Initialize references to Java object.
79 void DownloadController::Init(JNIEnv* env, jobject obj) {
80 java_object_ = new JavaObject;
81 java_object_->obj = env->NewWeakGlobalRef(obj);
82 }
83
84 void DownloadController::NewGetDownload(
85 content::RenderViewHost* render_view_host,
86 int request_id) {
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
88 int render_process_id = render_view_host->GetProcess()->GetID();
89 content::GlobalRequestID global_id(render_process_id, request_id);
90
91 // We are yielding the UI thread and render_view_host may go away by
92 // the time we come back. Pass along render_process_id and render_view_id
93 // to retrieve it later (if it still exists).
94 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
95 base::Bind(&DownloadController::PrepareDownloadInfo,
96 base::Unretained(this), global_id,
97 render_process_id,
98 render_view_host->GetRoutingID()));
99 }
100
101 void DownloadController::PrepareDownloadInfo(
102 const content::GlobalRequestID& global_id,
103 int render_process_id, int render_view_id) {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
105
106 net::URLRequest* request =
107 content::ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
108 DCHECK(request) << "Request to download not found.";
109
110 DownloadInfoAndroid info_android(request);
111 net::CookieOptions options;
112 options.set_include_httponly();
113
114 request->context()->cookie_store()->GetCookiesWithOptionsAsync(
jochen (gone - plz use gerrit) 2012/05/26 10:12:44 see http://code.google.com/searchframe#OAMlx_jo-ck
nilesh 2012/05/29 18:21:22 Done. Thanks for the pointer.
115 info_android.url, options,
116 base::Bind(&DownloadController::OnCookieResponse,
117 base::Unretained(this), info_android, render_process_id,
118 render_view_id));
119 }
120
121 void DownloadController::OnCookieResponse(DownloadInfoAndroid download_info,
122 int render_process_id,
123 int render_view_id,
124 const std::string& cookie) {
125 download_info.cookie = cookie;
126
127 // We have everything we need, start Android download on the UI thread.
128 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
129 base::Bind(&DownloadController::StartAndroidDownload,
130 base::Unretained(this), download_info, render_process_id,
131 render_view_id));
132 }
133
134 void DownloadController::StartAndroidDownload(
135 const DownloadInfoAndroid& info,
136 int render_process_id,
137 int render_view_id) {
138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
139 JNIEnv* env = AttachCurrentThread();
140
141 // Call newHttpGetDownload
142 jobject view = GetContentView(render_process_id, render_view_id);
143 if (!view) {
144 // The view went away. Can't proceed.
145 LOG(ERROR) << "Download failed on URL:" << info.url.spec();
146 return;
147 }
148
149 ScopedJavaLocalRef<jstring> jurl =
150 ConvertUTF8ToJavaString(env, info.url.spec());
151 ScopedJavaLocalRef<jstring> juser_agent =
152 ConvertUTF8ToJavaString(env, info.user_agent);
153 ScopedJavaLocalRef<jstring> jcontent_disposition =
154 ConvertUTF8ToJavaString(env, info.content_disposition);
155 ScopedJavaLocalRef<jstring> jmime_type =
156 ConvertUTF8ToJavaString(env, info.original_mime_type);
157 ScopedJavaLocalRef<jstring> jcookie =
158 ConvertUTF8ToJavaString(env, info.cookie);
159
160 Java_DownloadController_newHttpGetDownload(
161 env, java_object()->Controller(env).obj(), view, jurl.obj(),
162 juser_agent.obj(), jcontent_disposition.obj(), jmime_type.obj(),
163 jcookie.obj(), info.total_bytes);
164 }
165
166 void DownloadController::OnPostDownloadStarted(
167 WebContents* web_contents,
168 DownloadItem* download_item) {
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
170 JNIEnv* env = AttachCurrentThread();
171
172 // Register for updates to the DownloadItem.
173 download_item->AddObserver(this);
174
175 jobject view = GetContentViewFromWebContents(web_contents);
176 if(!view) {
177 // The view went away. Can't proceed.
178 return;
179 }
180
181 Java_DownloadController_onHttpPostDownloadStarted(
182 env, java_object()->Controller(env).obj(), view);
183 }
184
185 void DownloadController::OnDownloadUpdated(DownloadItem* item) {
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
187
188 if (item->GetState() != DownloadItem::COMPLETE)
189 return;
190
191 // Call onHttpPostDownloadCompleted
192 JNIEnv* env = AttachCurrentThread();
193 ScopedJavaLocalRef<jstring> jurl =
194 ConvertUTF8ToJavaString(env, item->GetURL().spec());
195 ScopedJavaLocalRef<jstring> jcontent_disposition =
196 ConvertUTF8ToJavaString(env, item->GetContentDisposition());
197 ScopedJavaLocalRef<jstring> jmime_type =
198 ConvertUTF8ToJavaString(env, item->GetMimeType());
199 ScopedJavaLocalRef<jstring> jpath =
200 ConvertUTF8ToJavaString(env, item->GetFullPath().value());
201
202 jobject view = GetContentViewFromWebContents(item->GetWebContents());
203 if(!view) {
204 // We can get NULL WebContents from the DownloadItem.
205 return;
206 }
207
208 Java_DownloadController_onHttpPostDownloadCompleted(env,
209 java_object()->Controller(env).obj(), view, jurl.obj(),
210 jcontent_disposition.obj(), jmime_type.obj(), jpath.obj(),
211 item->GetReceivedBytes(), true);
212 }
213
214 void DownloadController::OnDownloadOpened(DownloadItem* item) {
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 }
271
272 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/android/download_controller.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698