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

Side by Side Diff: chrome/browser/android/webapk/webapk_installer.cc

Issue 2184913005: Add calls to the server to request WebAPK updates. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and nits. Created 4 years, 4 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
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 18 matching lines...) Expand all
29 #include "jni/WebApkInstaller_jni.h" 29 #include "jni/WebApkInstaller_jni.h"
30 #include "net/http/http_status_code.h" 30 #include "net/http/http_status_code.h"
31 #include "net/url_request/url_fetcher.h" 31 #include "net/url_request/url_fetcher.h"
32 #include "ui/gfx/codec/png_codec.h" 32 #include "ui/gfx/codec/png_codec.h"
33 #include "url/gurl.h" 33 #include "url/gurl.h"
34 34
35 namespace { 35 namespace {
36 36
37 // The default WebAPK server URL. 37 // The default WebAPK server URL.
38 const char kDefaultWebApkServerUrl[] = 38 const char kDefaultWebApkServerUrl[] =
39 "https://webapk.googleapis.com/v1alpha/webApks?alt=proto"; 39 "https://webapk.googleapis.com/v1alpha/webApks/";
40
41 // The response format type expected from the WebAPK server.
42 const char kDefaultWebApkServerUrlResponseType[] = "?alt=proto";
40 43
41 // The MIME type of the POST data sent to the server. 44 // The MIME type of the POST data sent to the server.
42 const char kProtoMimeType[] = "application/x-protobuf"; 45 const char kProtoMimeType[] = "application/x-protobuf";
43 46
44 // The default number of milliseconds to wait for the WebAPK download URL from 47 // The default number of milliseconds to wait for the WebAPK download URL from
45 // the WebAPK server. 48 // the WebAPK server.
46 const int kWebApkDownloadUrlTimeoutMs = 60000; 49 const int kWebApkDownloadUrlTimeoutMs = 60000;
47 50
48 // The default number of milliseconds to wait for the WebAPK download to 51 // The default number of milliseconds to wait for the WebAPK download to
49 // complete. 52 // complete.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 return webapk; 114 return webapk;
112 } 115 }
113 116
114 // Returns task runner for running background tasks. 117 // Returns task runner for running background tasks.
115 scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() { 118 scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() {
116 return content::BrowserThread::GetBlockingPool() 119 return content::BrowserThread::GetBlockingPool()
117 ->GetTaskRunnerWithShutdownBehavior( 120 ->GetTaskRunnerWithShutdownBehavior(
118 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 121 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
119 } 122 }
120 123
124 GURL GetServerUrlForUpdate(const GURL& server_url,
125 const std::string& webapk_package) {
126 // crbug.com/636552. Simplify the server URL.
127 return GURL(server_url.spec() + webapk_package + "/" +
128 kDefaultWebApkServerUrlResponseType);
129 }
130
121 } // anonymous namespace 131 } // anonymous namespace
122 132
123 WebApkInstaller::WebApkInstaller(const ShortcutInfo& shortcut_info, 133 WebApkInstaller::WebApkInstaller(const ShortcutInfo& shortcut_info,
124 const SkBitmap& shortcut_icon) 134 const SkBitmap& shortcut_icon)
125 : shortcut_info_(shortcut_info), 135 : shortcut_info_(shortcut_info),
126 shortcut_icon_(shortcut_icon), 136 shortcut_icon_(shortcut_icon),
127 webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs), 137 webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs),
128 download_timeout_ms_(kDownloadTimeoutMs), 138 download_timeout_ms_(kDownloadTimeoutMs),
139 task_type_(UNDEFINED),
129 weak_ptr_factory_(this) { 140 weak_ptr_factory_(this) {
130 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 141 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
131 server_url_ = 142 server_url_ =
132 GURL(command_line->HasSwitch(switches::kWebApkServerUrl) 143 GURL(command_line->HasSwitch(switches::kWebApkServerUrl)
133 ? command_line->GetSwitchValueASCII(switches::kWebApkServerUrl) 144 ? command_line->GetSwitchValueASCII(switches::kWebApkServerUrl)
134 : kDefaultWebApkServerUrl); 145 : kDefaultWebApkServerUrl);
135 } 146 }
136 147
137 WebApkInstaller::~WebApkInstaller() {} 148 WebApkInstaller::~WebApkInstaller() {}
138 149
139 void WebApkInstaller::InstallAsync(content::BrowserContext* browser_context, 150 void WebApkInstaller::InstallAsync(content::BrowserContext* browser_context,
140 const FinishCallback& finish_callback) { 151 const FinishCallback& finish_callback) {
141 InstallAsyncWithURLRequestContextGetter( 152 InstallAsyncWithURLRequestContextGetter(
142 Profile::FromBrowserContext(browser_context)->GetRequestContext(), 153 Profile::FromBrowserContext(browser_context)->GetRequestContext(),
143 finish_callback); 154 finish_callback);
144 } 155 }
145 156
146 void WebApkInstaller::InstallAsyncWithURLRequestContextGetter( 157 void WebApkInstaller::InstallAsyncWithURLRequestContextGetter(
147 net::URLRequestContextGetter* request_context_getter, 158 net::URLRequestContextGetter* request_context_getter,
148 const FinishCallback& finish_callback) { 159 const FinishCallback& finish_callback) {
149 request_context_getter_ = request_context_getter; 160 request_context_getter_ = request_context_getter;
150 finish_callback_ = finish_callback; 161 finish_callback_ = finish_callback;
162 task_type_ = INSTALL;
151 163
152 if (!shortcut_info_.icon_url.is_valid()) { 164 if (!shortcut_info_.icon_url.is_valid()) {
153 OnFailure(); 165 OnFailure();
154 return; 166 return;
155 } 167 }
156 168
157 // We need to take the hash of the bitmap at the icon URL prior to any 169 // We need to take the hash of the bitmap at the icon URL prior to any
158 // transformations being applied to the bitmap (such as encoding/decoding 170 // transformations being applied to the bitmap (such as encoding/decoding
159 // the bitmap). The icon hash is used to determine whether the icon that 171 // the bitmap). The icon hash is used to determine whether the icon that
160 // the user sees matches the icon of a WebAPK that the WebAPK server 172 // the user sees matches the icon of a WebAPK that the WebAPK server
161 // generated for another user. (The icon can be dynamically generated.) 173 // generated for another user. (The icon can be dynamically generated.)
162 // 174 //
163 // We redownload the icon in order to take the Murmur2 hash. The redownload 175 // We redownload the icon in order to take the Murmur2 hash. The redownload
164 // should be fast because the icon should be in the HTTP cache. 176 // should be fast because the icon should be in the HTTP cache.
165 DownloadAppIconAndComputeMurmur2Hash(); 177 DownloadAppIconAndComputeMurmur2Hash();
166 } 178 }
167 179
168 void WebApkInstaller::SetTimeoutMs(int timeout_ms) { 180 void WebApkInstaller::SetTimeoutMs(int timeout_ms) {
169 webapk_download_url_timeout_ms_ = timeout_ms; 181 webapk_download_url_timeout_ms_ = timeout_ms;
170 download_timeout_ms_ = timeout_ms; 182 download_timeout_ms_ = timeout_ms;
171 } 183 }
172 184
173 bool WebApkInstaller::StartDownloadedWebApkInstall( 185 void WebApkInstaller::UpdateAsync(content::BrowserContext* browser_context,
186 const FinishCallback& finish_callback,
187 const std::string& webapk_package,
188 int webapk_version) {
189 UpdateAsyncWithURLRequestContextGetter(
190 Profile::FromBrowserContext(browser_context)->GetRequestContext(),
191 finish_callback, webapk_package, webapk_version);
192 }
193
194 void WebApkInstaller::UpdateAsyncWithURLRequestContextGetter(
195 net::URLRequestContextGetter* request_context_getter,
196 const FinishCallback& finish_callback,
197 const std::string& webapk_package,
198 int webapk_version) {
199 request_context_getter_ = request_context_getter;
200 finish_callback_ = finish_callback;
201 webapk_package_ = webapk_package;
202 webapk_version_ = webapk_version;
203 task_type_ = UPDATE;
204
205 if (!shortcut_info_.icon_url.is_valid()) {
206 OnFailure();
207 return;
208 }
209
210 DownloadAppIconAndComputeMurmur2Hash();
211 }
212
213 bool WebApkInstaller::StartInstallingDownloadedWebApk(
174 JNIEnv* env, 214 JNIEnv* env,
175 const base::android::ScopedJavaLocalRef<jstring>& java_file_path, 215 const base::android::ScopedJavaLocalRef<jstring>& java_file_path,
176 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) { 216 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) {
177 return Java_WebApkInstaller_installAsyncFromNative(env, java_file_path, 217 return Java_WebApkInstaller_installAsyncFromNative(env, java_file_path,
178 java_package_name); 218 java_package_name);
179 } 219 }
180 220
221 bool WebApkInstaller::StartUpdateUsingDownloadedWebApk(
222 JNIEnv* env,
223 const base::android::ScopedJavaLocalRef<jstring>& java_file_path,
224 const base::android::ScopedJavaLocalRef<jstring>& java_package_name) {
225 return Java_WebApkInstaller_updateAsyncFromNative(env, java_file_path,
226 java_package_name);
227 }
228
181 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { 229 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) {
182 timer_.Stop(); 230 timer_.Stop();
183 231
184 if (!source->GetStatus().is_success() || 232 if (!source->GetStatus().is_success() ||
185 source->GetResponseCode() != net::HTTP_OK) { 233 source->GetResponseCode() != net::HTTP_OK) {
186 OnFailure(); 234 OnFailure();
187 return; 235 return;
188 } 236 }
189 237
190 std::string response_string; 238 std::string response_string;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 icon_hasher_.reset(); 271 icon_hasher_.reset();
224 272
225 shortcut_icon_murmur2_hash_ = icon_murmur2_hash; 273 shortcut_icon_murmur2_hash_ = icon_murmur2_hash;
226 274
227 // An empty hash indicates that |icon_hasher_| encountered an error. 275 // An empty hash indicates that |icon_hasher_| encountered an error.
228 if (icon_murmur2_hash.empty()) { 276 if (icon_murmur2_hash.empty()) {
229 OnFailure(); 277 OnFailure();
230 return; 278 return;
231 } 279 }
232 280
233 base::PostTaskAndReplyWithResult( 281 if (task_type_ == INSTALL) {
234 GetBackgroundTaskRunner().get(), FROM_HERE, 282 base::PostTaskAndReplyWithResult(
235 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_, 283 GetBackgroundTaskRunner().get(), FROM_HERE,
236 shortcut_icon_murmur2_hash_), 284 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_,
237 base::Bind(&WebApkInstaller::SendCreateWebApkRequest, 285 shortcut_icon_, shortcut_icon_murmur2_hash_),
238 weak_ptr_factory_.GetWeakPtr())); 286 base::Bind(&WebApkInstaller::SendCreateWebApkRequest,
287 weak_ptr_factory_.GetWeakPtr()));
288 } else if (task_type_ == UPDATE) {
289 base::PostTaskAndReplyWithResult(
290 GetBackgroundTaskRunner().get(), FROM_HERE,
291 base::Bind(&BuildWebApkProtoInBackground, shortcut_info_,
292 shortcut_icon_, shortcut_icon_murmur2_hash_),
293 base::Bind(&WebApkInstaller::SendUpdateWebApkRequest,
294 weak_ptr_factory_.GetWeakPtr()));
295 }
239 } 296 }
240 297
241 void WebApkInstaller::SendCreateWebApkRequest( 298 void WebApkInstaller::SendCreateWebApkRequest(
242 std::unique_ptr<webapk::WebApk> webapk_proto) { 299 std::unique_ptr<webapk::WebApk> webapk) {
300 GURL server_url(server_url_.spec() + kDefaultWebApkServerUrlResponseType);
301 SendRequest(std::move(webapk), net::URLFetcher::POST, server_url);
302 }
303
304 void WebApkInstaller::SendUpdateWebApkRequest(
305 std::unique_ptr<webapk::WebApk> webapk) {
306 webapk->set_package_name(webapk_package_);
307 webapk->set_version(std::to_string(webapk_version_));
308
309 SendRequest(std::move(webapk), net::URLFetcher::PUT,
310 GetServerUrlForUpdate(server_url_, webapk_package_));
311 }
312
313 void WebApkInstaller::SendRequest(std::unique_ptr<webapk::WebApk> request_proto,
314 net::URLFetcher::RequestType request_type,
315 const GURL& server_url) {
243 timer_.Start( 316 timer_.Start(
244 FROM_HERE, 317 FROM_HERE,
245 base::TimeDelta::FromMilliseconds(webapk_download_url_timeout_ms_), 318 base::TimeDelta::FromMilliseconds(webapk_download_url_timeout_ms_),
246 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); 319 base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr()));
247 320
248 url_fetcher_ = 321 url_fetcher_ = net::URLFetcher::Create(server_url, request_type, this);
249 net::URLFetcher::Create(server_url_, net::URLFetcher::POST, this);
250 url_fetcher_->SetRequestContext(request_context_getter_); 322 url_fetcher_->SetRequestContext(request_context_getter_);
251 std::string serialized_request; 323 std::string serialized_request;
252 webapk_proto->SerializeToString(&serialized_request); 324 request_proto->SerializeToString(&serialized_request);
253 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request); 325 url_fetcher_->SetUploadData(kProtoMimeType, serialized_request);
254 url_fetcher_->Start(); 326 url_fetcher_->Start();
255 } 327 }
256 328
257 void WebApkInstaller::OnGotWebApkDownloadUrl(const GURL& download_url, 329 void WebApkInstaller::OnGotWebApkDownloadUrl(const GURL& download_url,
258 const std::string& package_name) { 330 const std::string& package_name) {
259 base::FilePath output_dir; 331 base::FilePath output_dir;
260 base::android::GetCacheDirectory(&output_dir); 332 base::android::GetCacheDirectory(&output_dir);
261 // TODO(pkotwicz): Download WebAPKs into WebAPK-specific subdirectory 333 // TODO(pkotwicz): Download WebAPKs into WebAPK-specific subdirectory
262 // directory. 334 // directory.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 if (!change_permission_success) { 373 if (!change_permission_success) {
302 OnFailure(); 374 OnFailure();
303 return; 375 return;
304 } 376 }
305 377
306 JNIEnv* env = base::android::AttachCurrentThread(); 378 JNIEnv* env = base::android::AttachCurrentThread();
307 base::android::ScopedJavaLocalRef<jstring> java_file_path = 379 base::android::ScopedJavaLocalRef<jstring> java_file_path =
308 base::android::ConvertUTF8ToJavaString(env, file_path.value()); 380 base::android::ConvertUTF8ToJavaString(env, file_path.value());
309 base::android::ScopedJavaLocalRef<jstring> java_package_name = 381 base::android::ScopedJavaLocalRef<jstring> java_package_name =
310 base::android::ConvertUTF8ToJavaString(env, package_name); 382 base::android::ConvertUTF8ToJavaString(env, package_name);
311 bool success = 383 bool success = false;
312 StartDownloadedWebApkInstall(env, java_file_path, java_package_name); 384 if (task_type_ == INSTALL) {
385 success = StartInstallingDownloadedWebApk(env, java_file_path,
386 java_package_name);
387 } else if (task_type_ == UPDATE) {
388 success = StartUpdateUsingDownloadedWebApk(env, java_file_path,
389 java_package_name);
390 }
313 if (success) 391 if (success)
314 OnSuccess(); 392 OnSuccess();
315 else 393 else
316 OnFailure(); 394 OnFailure();
317 } 395 }
318 396
319 void WebApkInstaller::OnTimeout() { 397 void WebApkInstaller::OnTimeout() {
320 OnFailure(); 398 OnFailure();
321 } 399 }
322 400
323 void WebApkInstaller::OnSuccess() { 401 void WebApkInstaller::OnSuccess() {
324 FinishCallback callback = finish_callback_; 402 FinishCallback callback = finish_callback_;
325 delete this; 403 delete this;
326 callback.Run(true); 404 callback.Run(true);
327 } 405 }
328 406
329 void WebApkInstaller::OnFailure() { 407 void WebApkInstaller::OnFailure() {
330 FinishCallback callback = finish_callback_; 408 FinishCallback callback = finish_callback_;
331 delete this; 409 delete this;
332 callback.Run(false); 410 callback.Run(false);
333 } 411 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698