OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/webapk/webapk_installer.h" | 5 #include "chrome/browser/android/webapk/webapk_installer.h" |
6 | 6 |
7 #include "base/android/build_info.h" | 7 #include "base/android/build_info.h" |
8 #include "base/android/jni_android.h" | 8 #include "base/android/jni_android.h" |
9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
10 #include "base/android/path_utils.h" | 10 #include "base/android/path_utils.h" |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 shortcut_icon_(shortcut_icon), | 136 shortcut_icon_(shortcut_icon), |
137 webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs), | 137 webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs), |
138 download_timeout_ms_(kDownloadTimeoutMs), | 138 download_timeout_ms_(kDownloadTimeoutMs), |
139 task_type_(UNDEFINED), | 139 task_type_(UNDEFINED), |
140 weak_ptr_factory_(this) { | 140 weak_ptr_factory_(this) { |
141 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 141 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
142 server_url_ = | 142 server_url_ = |
143 GURL(command_line->HasSwitch(switches::kWebApkServerUrl) | 143 GURL(command_line->HasSwitch(switches::kWebApkServerUrl) |
144 ? command_line->GetSwitchValueASCII(switches::kWebApkServerUrl) | 144 ? command_line->GetSwitchValueASCII(switches::kWebApkServerUrl) |
145 : kDefaultWebApkServerUrl); | 145 : kDefaultWebApkServerUrl); |
| 146 CreateJavaRef(); |
146 } | 147 } |
147 | 148 |
148 WebApkInstaller::~WebApkInstaller() {} | 149 void WebApkInstaller::CreateJavaRef() { |
| 150 JNIEnv* env = base::android::AttachCurrentThread(); |
| 151 java_ref_.Reset(Java_WebApkInstaller_create( |
| 152 env, reinterpret_cast<intptr_t>(this))); |
| 153 } |
| 154 |
| 155 WebApkInstaller::~WebApkInstaller() { |
| 156 JNIEnv* env = base::android::AttachCurrentThread(); |
| 157 Java_WebApkInstaller_destroy(env, java_ref_); |
| 158 java_ref_.Reset(); |
| 159 } |
149 | 160 |
150 void WebApkInstaller::InstallAsync(content::BrowserContext* browser_context, | 161 void WebApkInstaller::InstallAsync(content::BrowserContext* browser_context, |
151 const FinishCallback& finish_callback) { | 162 const FinishCallback& finish_callback) { |
152 InstallAsyncWithURLRequestContextGetter( | 163 InstallAsyncWithURLRequestContextGetter( |
153 Profile::FromBrowserContext(browser_context)->GetRequestContext(), | 164 Profile::FromBrowserContext(browser_context)->GetRequestContext(), |
154 finish_callback); | 165 finish_callback); |
155 } | 166 } |
156 | 167 |
157 void WebApkInstaller::InstallAsyncWithURLRequestContextGetter( | 168 void WebApkInstaller::InstallAsyncWithURLRequestContextGetter( |
158 net::URLRequestContextGetter* request_context_getter, | 169 net::URLRequestContextGetter* request_context_getter, |
159 const FinishCallback& finish_callback) { | 170 const FinishCallback& finish_callback) { |
160 request_context_getter_ = request_context_getter; | 171 request_context_getter_ = request_context_getter; |
161 finish_callback_ = finish_callback; | 172 finish_callback_ = finish_callback; |
162 task_type_ = INSTALL; | 173 task_type_ = INSTALL; |
163 | 174 |
164 // We need to take the hash of the bitmap at the icon URL prior to any | 175 // We need to take the hash of the bitmap at the icon URL prior to any |
165 // transformations being applied to the bitmap (such as encoding/decoding | 176 // transformations being applied to the bitmap (such as encoding/decoding |
166 // the bitmap). The icon hash is used to determine whether the icon that | 177 // the bitmap). The icon hash is used to determine whether the icon that |
167 // the user sees matches the icon of a WebAPK that the WebAPK server | 178 // the user sees matches the icon of a WebAPK that the WebAPK server |
168 // generated for another user. (The icon can be dynamically generated.) | 179 // generated for another user. (The icon can be dynamically generated.) |
169 // | 180 // |
170 // We redownload the icon in order to take the Murmur2 hash. The redownload | 181 // We redownload the icon in order to take the Murmur2 hash. The redownload |
171 // should be fast because the icon should be in the HTTP cache. | 182 // should be fast because the icon should be in the HTTP cache. |
172 DownloadAppIconAndComputeMurmur2Hash(); | 183 DownloadAppIconAndComputeMurmur2Hash(); |
173 } | 184 } |
174 | 185 |
175 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { | |
176 webapk_download_url_timeout_ms_ = timeout_ms; | |
177 download_timeout_ms_ = timeout_ms; | |
178 } | |
179 | |
180 void WebApkInstaller::UpdateAsync(content::BrowserContext* browser_context, | 186 void WebApkInstaller::UpdateAsync(content::BrowserContext* browser_context, |
181 const FinishCallback& finish_callback, | 187 const FinishCallback& finish_callback, |
182 const std::string& icon_murmur2_hash, | 188 const std::string& icon_murmur2_hash, |
183 const std::string& webapk_package, | 189 const std::string& webapk_package, |
184 int webapk_version) { | 190 int webapk_version) { |
185 UpdateAsyncWithURLRequestContextGetter( | 191 UpdateAsyncWithURLRequestContextGetter( |
186 Profile::FromBrowserContext(browser_context)->GetRequestContext(), | 192 Profile::FromBrowserContext(browser_context)->GetRequestContext(), |
187 finish_callback, icon_murmur2_hash, webapk_package, webapk_version); | 193 finish_callback, icon_murmur2_hash, webapk_package, webapk_version); |
188 } | 194 } |
189 | 195 |
(...skipping 11 matching lines...) Expand all Loading... |
201 task_type_ = UPDATE; | 207 task_type_ = UPDATE; |
202 | 208 |
203 base::PostTaskAndReplyWithResult( | 209 base::PostTaskAndReplyWithResult( |
204 GetBackgroundTaskRunner().get(), FROM_HERE, | 210 GetBackgroundTaskRunner().get(), FROM_HERE, |
205 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, | 211 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, |
206 shortcut_icon_, shortcut_icon_murmur2_hash_), | 212 shortcut_icon_, shortcut_icon_murmur2_hash_), |
207 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest, | 213 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest, |
208 weak_ptr_factory_.GetWeakPtr())); | 214 weak_ptr_factory_.GetWeakPtr())); |
209 } | 215 } |
210 | 216 |
| 217 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { |
| 218 webapk_download_url_timeout_ms_ = timeout_ms; |
| 219 download_timeout_ms_ = timeout_ms; |
| 220 } |
| 221 |
| 222 void WebApkInstaller::OnInstallFinished( |
| 223 JNIEnv* env, |
| 224 const base::android::JavaParamRef<jobject>& obj, |
| 225 jboolean success) { |
| 226 if (success) |
| 227 OnSuccess(); |
| 228 else |
| 229 OnFailure(); |
| 230 } |
| 231 |
| 232 // static |
| 233 bool WebApkInstaller::Register(JNIEnv* env) { |
| 234 return RegisterNativesImpl(env); |
| 235 } |
| 236 |
211 bool WebApkInstaller::StartInstallingDownloadedWebApk( | 237 bool WebApkInstaller::StartInstallingDownloadedWebApk( |
212 JNIEnv* env, | 238 JNIEnv* env, |
213 const base::android::ScopedJavaLocalRef<jstring>& java_file_path, | 239 const base::android::ScopedJavaLocalRef<jstring>& java_file_path, |
214 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) { | 240 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) { |
215 return Java_WebApkInstaller_installAsyncFromNative(env, java_file_path, | 241 return Java_WebApkInstaller_installAsyncFromNative( |
216 java_package_name); | 242 env, java_ref_, java_file_path, java_package_name); |
217 } | 243 } |
218 | 244 |
219 bool WebApkInstaller::StartUpdateUsingDownloadedWebApk( | 245 bool WebApkInstaller::StartUpdateUsingDownloadedWebApk( |
220 JNIEnv* env, | 246 JNIEnv* env, |
221 const base::android::ScopedJavaLocalRef<jstring>& java_file_path, | 247 const base::android::ScopedJavaLocalRef<jstring>& java_file_path, |
222 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) { | 248 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) { |
223 return Java_WebApkInstaller_updateAsyncFromNative(env, java_file_path, | 249 return Java_WebApkInstaller_updateAsyncFromNative( |
224 java_package_name); | 250 env, java_ref_, java_file_path, java_package_name); |
225 } | 251 } |
226 | 252 |
227 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { | 253 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { |
228 timer_.Stop(); | 254 timer_.Stop(); |
229 | 255 |
230 if (!source->GetStatus().is_success() || | 256 if (!source->GetStatus().is_success() || |
231 source->GetResponseCode() != net::HTTP_OK) { | 257 source->GetResponseCode() != net::HTTP_OK) { |
232 OnFailure(); | 258 OnFailure(); |
233 return; | 259 return; |
234 } | 260 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 if (icon_murmur2_hash.empty()) { | 306 if (icon_murmur2_hash.empty()) { |
281 OnFailure(); | 307 OnFailure(); |
282 return; | 308 return; |
283 } | 309 } |
284 | 310 |
285 base::PostTaskAndReplyWithResult( | 311 base::PostTaskAndReplyWithResult( |
286 GetBackgroundTaskRunner().get(), FROM_HERE, | 312 GetBackgroundTaskRunner().get(), FROM_HERE, |
287 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, | 313 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, |
288 shortcut_icon_, shortcut_icon_murmur2_hash_), | 314 shortcut_icon_, shortcut_icon_murmur2_hash_), |
289 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, | 315 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, |
290 weak_ptr_factory_.GetWeakPtr())); | 316 weak_ptr_factory_.GetWeakPtr())); |
291 } | 317 } |
292 | 318 |
293 void WebApkInstaller::SendCreateWebApkRequest( | 319 void WebApkInstaller::SendCreateWebApkRequest( |
294 std::unique_ptr<webapk::WebApk> webapk) { | 320 std::unique_ptr<webapk::WebApk> webapk) { |
295 GURL server_url(server_url_.spec() + kDefaultWebApkServerUrlResponseType); | 321 GURL server_url(server_url_.spec() + kDefaultWebApkServerUrlResponseType); |
296 SendRequest(std::move(webapk), net::URLFetcher::POST, server_url); | 322 SendRequest(std::move(webapk), net::URLFetcher::POST, server_url); |
297 } | 323 } |
298 | 324 |
299 void WebApkInstaller::SendUpdateWebApkRequest( | 325 void WebApkInstaller::SendUpdateWebApkRequest( |
300 std::unique_ptr<webapk::WebApk> webapk) { | 326 std::unique_ptr<webapk::WebApk> webapk) { |
(...skipping 17 matching lines...) Expand all Loading... |
318 std::string serialized_request; | 344 std::string serialized_request; |
319 request_proto->SerializeToString(&serialized_request); | 345 request_proto->SerializeToString(&serialized_request); |
320 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); | 346 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); |
321 url_fetcher_->Start(); | 347 url_fetcher_->Start(); |
322 } | 348 } |
323 | 349 |
324 void WebApkInstaller::OnGotWebApkDownloadUrl(const GURL& download_url, | 350 void WebApkInstaller::OnGotWebApkDownloadUrl(const GURL& download_url, |
325 const std::string& package_name) { | 351 const std::string& package_name) { |
326 base::FilePath output_dir; | 352 base::FilePath output_dir; |
327 base::android::GetCacheDirectory(&output_dir); | 353 base::android::GetCacheDirectory(&output_dir); |
| 354 webapk_package_ = package_name; |
328 // TODO(pkotwicz): Download WebAPKs into WebAPK-specific subdirectory | 355 // TODO(pkotwicz): Download WebAPKs into WebAPK-specific subdirectory |
329 // directory. | 356 // directory. |
330 // TODO(pkotwicz): Figure out when downloaded WebAPK should be deleted. | 357 // TODO(pkotwicz): Figure out when downloaded WebAPK should be deleted. |
331 | 358 |
332 timer_.Start( | 359 timer_.Start( |
333 FROM_HERE, base::TimeDelta::FromMilliseconds(download_timeout_ms_), | 360 FROM_HERE, base::TimeDelta::FromMilliseconds(download_timeout_ms_), |
334 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); | 361 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); |
335 | 362 |
336 base::FilePath output_path = output_dir.AppendASCII(package_name); | 363 base::FilePath output_path = output_dir.AppendASCII(webapk_package_); |
337 downloader_.reset(new FileDownloader( | 364 downloader_.reset(new FileDownloader( |
338 download_url, output_path, true, request_context_getter_, | 365 download_url, output_path, true, request_context_getter_, |
339 base::Bind(&WebApkInstaller::OnWebApkDownloaded, | 366 base::Bind(&WebApkInstaller::OnWebApkDownloaded, |
340 weak_ptr_factory_.GetWeakPtr(), output_path, package_name))); | 367 weak_ptr_factory_.GetWeakPtr(), output_path))); |
341 } | 368 } |
342 | 369 |
343 void WebApkInstaller::OnWebApkDownloaded(const base::FilePath& file_path, | 370 void WebApkInstaller::OnWebApkDownloaded(const base::FilePath& file_path, |
344 const std::string& package_name, | |
345 FileDownloader::Result result) { | 371 FileDownloader::Result result) { |
346 timer_.Stop(); | 372 timer_.Stop(); |
347 | 373 |
348 if (result != FileDownloader::DOWNLOADED) { | 374 if (result != FileDownloader::DOWNLOADED) { |
349 OnFailure(); | 375 OnFailure(); |
350 return; | 376 return; |
351 } | 377 } |
352 | 378 |
353 int posix_permissions = base::FILE_PERMISSION_READ_BY_USER | | 379 int posix_permissions = base::FILE_PERMISSION_READ_BY_USER | |
354 base::FILE_PERMISSION_WRITE_BY_USER | | 380 base::FILE_PERMISSION_WRITE_BY_USER | |
355 base::FILE_PERMISSION_READ_BY_GROUP | | 381 base::FILE_PERMISSION_READ_BY_GROUP | |
356 base::FILE_PERMISSION_READ_BY_OTHERS; | 382 base::FILE_PERMISSION_READ_BY_OTHERS; |
357 base::PostTaskAndReplyWithResult( | 383 base::PostTaskAndReplyWithResult( |
358 GetBackgroundTaskRunner().get(), FROM_HERE, | 384 GetBackgroundTaskRunner().get(), FROM_HERE, |
359 base::Bind(&base::SetPosixFilePermissions, file_path, posix_permissions), | 385 base::Bind(&base::SetPosixFilePermissions, file_path, posix_permissions), |
360 base::Bind(&WebApkInstaller::OnWebApkMadeWorldReadable, | 386 base::Bind(&WebApkInstaller::OnWebApkMadeWorldReadable, |
361 weak_ptr_factory_.GetWeakPtr(), file_path, package_name)); | 387 weak_ptr_factory_.GetWeakPtr(), file_path)); |
362 } | 388 } |
363 | 389 |
364 void WebApkInstaller::OnWebApkMadeWorldReadable( | 390 void WebApkInstaller::OnWebApkMadeWorldReadable( |
365 const base::FilePath& file_path, | 391 const base::FilePath& file_path, |
366 const std::string& package_name, | |
367 bool change_permission_success) { | 392 bool change_permission_success) { |
368 if (!change_permission_success) { | 393 if (!change_permission_success) { |
369 OnFailure(); | 394 OnFailure(); |
370 return; | 395 return; |
371 } | 396 } |
372 | 397 |
373 JNIEnv* env = base::android::AttachCurrentThread(); | 398 JNIEnv* env = base::android::AttachCurrentThread(); |
374 base::android::ScopedJavaLocalRef<jstring> java_file_path = | 399 base::android::ScopedJavaLocalRef<jstring> java_file_path = |
375 base::android::ConvertUTF8ToJavaString(env, file_path.value()); | 400 base::android::ConvertUTF8ToJavaString(env, file_path.value()); |
376 base::android::ScopedJavaLocalRef<jstring> java_package_name = | 401 base::android::ScopedJavaLocalRef<jstring> java_package_name = |
377 base::android::ConvertUTF8ToJavaString(env, package_name); | 402 base::android::ConvertUTF8ToJavaString(env, webapk_package_); |
378 bool success = false; | 403 bool success = false; |
379 if (task_type_ == INSTALL) { | 404 if (task_type_ == INSTALL) { |
380 success = StartInstallingDownloadedWebApk(env, java_file_path, | 405 success = StartInstallingDownloadedWebApk(env, java_file_path, |
381 java_package_name); | 406 java_package_name); |
382 } else if (task_type_ == UPDATE) { | 407 } else if (task_type_ == UPDATE) { |
383 success = StartUpdateUsingDownloadedWebApk(env, java_file_path, | 408 success = StartUpdateUsingDownloadedWebApk(env, java_file_path, |
384 java_package_name); | 409 java_package_name); |
385 } | 410 } |
386 if (success) | 411 if (!success) |
387 OnSuccess(); | |
388 else | |
389 OnFailure(); | 412 OnFailure(); |
390 } | 413 } |
391 | 414 |
392 void WebApkInstaller::OnTimeout() { | 415 void WebApkInstaller::OnTimeout() { |
393 OnFailure(); | 416 OnFailure(); |
394 } | 417 } |
395 | 418 |
396 void WebApkInstaller::OnSuccess() { | 419 void WebApkInstaller::OnSuccess() { |
397 FinishCallback callback = finish_callback_; | 420 FinishCallback callback = finish_callback_; |
398 delete this; | 421 delete this; |
399 callback.Run(true); | 422 callback.Run(true, webapk_package_); |
400 } | 423 } |
401 | 424 |
402 void WebApkInstaller::OnFailure() { | 425 void WebApkInstaller::OnFailure() { |
403 FinishCallback callback = finish_callback_; | 426 FinishCallback callback = finish_callback_; |
404 delete this; | 427 delete this; |
405 callback.Run(false); | 428 callback.Run(false, ""); |
406 } | 429 } |
OLD | NEW |