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

Side by Side Diff: android_webview/java/src/org/chromium/android_webview/AwVariationsSeedFetchService.java

Issue 2975693002: Add AwVariationsSeedFetchService and refactory VariationsSeedFetcher (Closed)
Patch Set: Update a bug in deleting file Created 3 years, 5 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 2017 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 package org.chromium.android_webview;
6
7 import android.annotation.TargetApi;
8 import android.app.job.JobParameters;
9 import android.app.job.JobService;
10 import android.os.AsyncTask;
11 import android.os.Build;
12
13 import org.chromium.base.ContextUtils;
14 import org.chromium.base.Log;
15 import org.chromium.base.ThreadUtils;
16 import org.chromium.components.variations.firstrun.VariationsSeedFetcher;
17 import org.chromium.components.variations.firstrun.VariationsSeedFetcher.SeedInf o;
18
19 import java.io.Closeable;
20 import java.io.File;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.ObjectOutputStream;
24 import java.io.Serializable;
25 import java.util.concurrent.locks.Lock;
26 import java.util.concurrent.locks.ReentrantLock;
27
28 /**
29 * AwVariationsSeedFetchService is a Job Service to fetch test seed data which i s used by Finch
30 * to enable AB testing experiments in the native code. The fetched data is stor ed in the local
31 * directory which belongs to the Service process.
32 */
33 @TargetApi(Build.VERSION_CODES.LOLLIPOP) // JobService requires API level 21.
34 public class AwVariationsSeedFetchService extends JobService {
35 private static final String TAG = "AwVartnsSeedFetchSvc";
36
37 public static final String WEBVIEW_VARIATIONS_DIR = "WebView_Variations/";
38 public static final String SEED_DATA_FILENAME = "variations_seed_data";
39 public static final String SEED_PREF_FILENAME = "variations_seed_pref";
40
41 // Synchronization lock to prevent simultaneous local seed file writing.
42 private static final Lock sLock = new ReentrantLock();
43
44 @Override
45 public boolean onStartJob(JobParameters params) {
46 // Ensure we can use ContextUtils later on.
47 ContextUtils.initApplicationContext(this.getApplicationContext());
48 new FetchFinchSeedDataTask(params).execute();
49 return true;
50 }
51
52 @Override
53 public boolean onStopJob(JobParameters params) {
54 // The function will only be called before jobFinished when job paramete rs are no longer
55 // satisfied. The function returns true to make the task rescheduled.
56 return true;
57 }
58
59 private class FetchFinchSeedDataTask extends AsyncTask<Void, Void, Void> {
60 private JobParameters mJobParams;
61
62 FetchFinchSeedDataTask(JobParameters params) {
63 mJobParams = params;
64 }
65
66 @Override
67 protected Void doInBackground(Void... params) {
68 AwVariationsSeedFetchService.fetchSeed();
69 return null;
70 }
71
72 @Override
73 protected void onPostExecute(Void success) {
74 jobFinished(mJobParams, false /* false -> don't reschedule */);
75 }
76 }
77
78 private static void fetchSeed() {
79 assert !ThreadUtils.runningOnUiThread();
80 // TryLock will drop calls from other threads when there is a thread exe cuting the function.
81 // TODO(yiyuny): Add explicitly control to ensure there's only one threa ding fetching at a
82 // time and that the seed doesn't get fetched too frequently
83 if (sLock.tryLock()) {
84 try {
85 SeedInfo seedInfo = VariationsSeedFetcher.get().downloadContent(
86 VariationsSeedFetcher.VariationsPlatform.ANDROID_WEBVIEW , "");
87 storeVariationsSeed(seedInfo);
88 } catch (IOException e) {
89 // Exceptions are handled and logged in the downloadContent func tion and re-throwing
gsennton 2017/07/14 12:45:39 "Exceptions are handled and logged in the download
yiyuny 2017/07/15 00:19:00 Thanks!
90 // exceptions is to stop the normal logic flow after it, so no e rror-handling here.
91 // Not explicitly handing SocketTimeoutException and UnknownHost Exception for they
92 // are both subclasses of IOException.
93 } finally {
94 sLock.unlock();
95 }
96 }
97 }
98
99 /**
100 * SeedPreference is used to serialize/deserialize related fields of seed da ta when reading or
101 * writing them to the internal storage.
102 */
103 public static class SeedPreference implements Serializable {
104 /**
105 * Let the program deserialize the data when the fields are changed.
106 */
107 private static final long serialVersionUID = 0L;
108
109 public final String signature;
110 public final String country;
111 public final String date;
112 public final boolean isGzipCompressed;
113
114 public SeedPreference(SeedInfo seedInfo) {
115 signature = seedInfo.signature;
116 country = seedInfo.country;
117 date = seedInfo.date;
118 isGzipCompressed = seedInfo.isGzipCompressed;
119 }
120 }
121
122 private static File getOrCreateWebViewVariationsDir() {
123 File webViewFileDir = ContextUtils.getApplicationContext().getFilesDir() ;
124 File dir = new File(webViewFileDir, WEBVIEW_VARIATIONS_DIR);
125 if (dir.mkdir() || dir.isDirectory()) {
126 return dir;
127 }
128 return null;
129 }
130
131 private static void storeVariationsSeed(SeedInfo seedInfo) {
132 File webViewVariationsDir = getOrCreateWebViewVariationsDir();
133 if (webViewVariationsDir == null) {
134 Log.e(TAG, "Failed to get or create the webview variations directory .");
135 return;
136 }
137
138 FileOutputStream fosSeedData = null;
139 ObjectOutputStream oosSeedPref = null;
140 try {
141 File seedDataFile = File.createTempFile(SEED_DATA_FILENAME, null, we bViewVariationsDir);
142 fosSeedData = new FileOutputStream(seedDataFile);
143 fosSeedData.write(seedInfo.seedData, 0, seedInfo.seedData.length);
144 renameTempFile(seedDataFile, new File(webViewVariationsDir, SEED_DAT A_FILENAME));
145 // Store separately so that reading large seed data (which is expens ive) can be
146 // prevented when checking the last seed fetch time.
147 File seedPrefFile = File.createTempFile(SEED_PREF_FILENAME, null, we bViewVariationsDir);
148 oosSeedPref = new ObjectOutputStream(new FileOutputStream(seedPrefFi le));
149 oosSeedPref.writeObject(new SeedPreference(seedInfo));
150 renameTempFile(seedPrefFile, new File(webViewVariationsDir, SEED_PRE F_FILENAME));
151 } catch (IOException e) {
152 Log.e(TAG, "IOException failed to write variations seed data or pref erence to a file.");
153 } finally {
154 closeStream(fosSeedData, SEED_DATA_FILENAME);
155 closeStream(oosSeedPref, SEED_PREF_FILENAME);
156 }
157 }
158
159 private static void renameTempFile(File tempFile, File newFile) {
160 newFile.delete();
161 tempFile.renameTo(newFile);
162 }
163
164 private static void closeStream(Closeable stream, String filename) {
165 if (stream != null) {
166 try {
167 stream.close();
168 } catch (IOException e) {
169 Log.e(TAG, "IOException failed to close " + filename + " file.") ;
170 }
171 }
172 }
173 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698