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 package org.chromium.android_webview.crash; | 5 package org.chromium.android_webview.crash; |
6 | 6 |
7 import android.annotation.TargetApi; | 7 import android.annotation.TargetApi; |
8 import android.app.Service; | 8 import android.app.Service; |
9 import android.app.job.JobInfo; | 9 import android.app.job.JobInfo; |
10 import android.app.job.JobScheduler; | |
11 import android.content.ComponentName; | |
12 import android.content.Context; | 10 import android.content.Context; |
13 import android.content.Intent; | 11 import android.content.Intent; |
14 import android.os.Binder; | 12 import android.os.Binder; |
15 import android.os.Build; | 13 import android.os.Build; |
16 import android.os.IBinder; | 14 import android.os.IBinder; |
17 import android.os.ParcelFileDescriptor; | 15 import android.os.ParcelFileDescriptor; |
| 16 import android.os.PersistableBundle; |
18 | 17 |
19 import org.chromium.base.Log; | 18 import org.chromium.base.Log; |
20 import org.chromium.base.VisibleForTesting; | 19 import org.chromium.base.VisibleForTesting; |
21 import org.chromium.components.minidump_uploader.CrashFileManager; | 20 import org.chromium.components.minidump_uploader.CrashFileManager; |
| 21 import org.chromium.components.minidump_uploader.MinidumpUploadJobService; |
22 | 22 |
23 import java.io.File; | 23 import java.io.File; |
24 import java.io.IOException; | 24 import java.io.IOException; |
25 | 25 |
26 /** | 26 /** |
27 * Service that is responsible for receiving crash dumps from an application, fo
r upload. | 27 * Service that is responsible for receiving crash dumps from an application, fo
r upload. |
28 */ | 28 */ |
29 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | 29 @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
30 public class CrashReceiverService extends Service { | 30 public class CrashReceiverService extends Service { |
31 private static final String TAG = "CrashReceiverService"; | 31 private static final String TAG = "CrashReceiverService"; |
32 | 32 |
33 private static final String WEBVIEW_CRASH_DIR = "WebView_Crashes"; | 33 private static final String WEBVIEW_CRASH_DIR = "WebView_Crashes"; |
34 private static final String WEBVIEW_TMP_CRASH_DIR = "WebView_Crashes_Tmp"; | 34 private static final String WEBVIEW_TMP_CRASH_DIR = "WebView_Crashes_Tmp"; |
35 | 35 |
36 private static final int MINIDUMP_UPLOADING_JOB_ID = 42; | |
37 // Initial back-off time for upload-job, this is set to a fairly high number
(30 minutes) to | |
38 // increase the chance of performing uploads in batches if the initial uploa
d fails. | |
39 private static final int JOB_BACKOFF_TIME_IN_MS = 1000 * 60 * 30; | |
40 // Back-off policy for upload-job. | |
41 private static final int JOB_BACKOFF_POLICY = JobInfo.BACKOFF_POLICY_EXPONEN
TIAL; | |
42 | |
43 private Object mCopyingLock = new Object(); | 36 private Object mCopyingLock = new Object(); |
44 private boolean mIsCopying = false; | 37 private boolean mIsCopying = false; |
45 | 38 |
46 @Override | 39 @Override |
47 public void onCreate() { | 40 public void onCreate() { |
48 super.onCreate(); | 41 super.onCreate(); |
49 } | 42 } |
50 | 43 |
51 private final ICrashReceiverService.Stub mBinder = new ICrashReceiverService
.Stub() { | 44 private final ICrashReceiverService.Stub mBinder = new ICrashReceiverService
.Stub() { |
52 @Override | 45 @Override |
(...skipping 15 matching lines...) Expand all Loading... |
68 ParcelFileDescriptor[] fileDescriptors, boolean scheduleUploads) { | 61 ParcelFileDescriptor[] fileDescriptors, boolean scheduleUploads) { |
69 if (!waitUntilWeCanCopy()) { | 62 if (!waitUntilWeCanCopy()) { |
70 Log.e(TAG, "something went wrong when waiting to copy minidumps, bai
ling!"); | 63 Log.e(TAG, "something went wrong when waiting to copy minidumps, bai
ling!"); |
71 return; | 64 return; |
72 } | 65 } |
73 | 66 |
74 try { | 67 try { |
75 boolean copySucceeded = copyMinidumps(context, uid, fileDescriptors)
; | 68 boolean copySucceeded = copyMinidumps(context, uid, fileDescriptors)
; |
76 if (copySucceeded && scheduleUploads) { | 69 if (copySucceeded && scheduleUploads) { |
77 // Only schedule a new job if there actually are any files to up
load. | 70 // Only schedule a new job if there actually are any files to up
load. |
78 scheduleNewJob(); | 71 MinidumpUploadJobService.scheduleUpload(this, AwMinidumpUploadJo
bService.class, |
| 72 JobInfo.NETWORK_TYPE_UNMETERED, PersistableBundle.EMPTY)
; |
79 } | 73 } |
80 } finally { | 74 } finally { |
81 synchronized (mCopyingLock) { | 75 synchronized (mCopyingLock) { |
82 mIsCopying = false; | 76 mIsCopying = false; |
83 mCopyingLock.notifyAll(); | 77 mCopyingLock.notifyAll(); |
84 } | 78 } |
85 } | 79 } |
86 } | 80 } |
87 | 81 |
88 /** | 82 /** |
89 * Wait until we are allowed to copy minidumps. | 83 * Wait until we are allowed to copy minidumps. |
90 * @return whether we are actually allowed to copy the files - if false we s
hould just bail. | 84 * @return whether we are actually allowed to copy the files - if false we s
hould just bail. |
91 */ | 85 */ |
92 private boolean waitUntilWeCanCopy() { | 86 private boolean waitUntilWeCanCopy() { |
93 synchronized (mCopyingLock) { | 87 synchronized (mCopyingLock) { |
94 while (mIsCopying) { | 88 while (mIsCopying) { |
95 try { | 89 try { |
96 mCopyingLock.wait(); | 90 mCopyingLock.wait(); |
97 } catch (InterruptedException e) { | 91 } catch (InterruptedException e) { |
98 Log.e(TAG, "Was interrupted when waiting to copy minidumps",
e); | 92 Log.e(TAG, "Was interrupted when waiting to copy minidumps",
e); |
99 return false; | 93 return false; |
100 } | 94 } |
101 } | 95 } |
102 mIsCopying = true; | 96 mIsCopying = true; |
103 return true; | 97 return true; |
104 } | 98 } |
105 } | 99 } |
106 | 100 |
107 private void scheduleNewJob() { | |
108 JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_
SCHEDULER_SERVICE); | |
109 JobInfo newJob = new JobInfo | |
110 .Builder(MINIDUMP_UPLOADING_JOB_ID /* jobId */, | |
111 new ComponentName(this, AwMinidumpUploa
dJobService.class)) | |
112 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UN
METERED) | |
113 // Minimum delay when a job is retried (a retry
will happen when | |
114 // there are minidumps left after trying to upl
oad all minidumps - | |
115 // this could e.g. happen if we add more minidu
mps at the same time | |
116 // as uploading old ones). | |
117 .setBackoffCriteria(JOB_BACKOFF_TIME_IN_MS, JOB
_BACKOFF_POLICY) | |
118 .build(); | |
119 if (jobScheduler.schedule(newJob) == JobScheduler.RESULT_FAILURE) { | |
120 throw new RuntimeException("couldn't schedule " + newJob); | |
121 } | |
122 } | |
123 | |
124 /** | 101 /** |
125 * Copy minidumps from the {@param fileDescriptors} to the directory where W
ebView stores its | 102 * Copy minidumps from the {@param fileDescriptors} to the directory where W
ebView stores its |
126 * minidump files. {@param context} is used to look up the directory in whic
h the files will be | 103 * minidump files. {@param context} is used to look up the directory in whic
h the files will be |
127 * saved. | 104 * saved. |
128 * @return whether any minidump was copied. | 105 * @return whether any minidump was copied. |
129 */ | 106 */ |
130 @VisibleForTesting | 107 @VisibleForTesting |
131 public static boolean copyMinidumps( | 108 public static boolean copyMinidumps( |
132 Context context, int uid, ParcelFileDescriptor[] fileDescriptors) { | 109 Context context, int uid, ParcelFileDescriptor[] fileDescriptors) { |
133 CrashFileManager crashFileManager = new CrashFileManager(createWebViewCr
ashDir(context)); | 110 CrashFileManager crashFileManager = new CrashFileManager(createWebViewCr
ashDir(context)); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 @VisibleForTesting | 188 @VisibleForTesting |
212 public static File getWebViewTmpCrashDir(Context context) { | 189 public static File getWebViewTmpCrashDir(Context context) { |
213 return new File(context.getCacheDir(), WEBVIEW_TMP_CRASH_DIR); | 190 return new File(context.getCacheDir(), WEBVIEW_TMP_CRASH_DIR); |
214 } | 191 } |
215 | 192 |
216 @Override | 193 @Override |
217 public IBinder onBind(Intent intent) { | 194 public IBinder onBind(Intent intent) { |
218 return mBinder; | 195 return mBinder; |
219 } | 196 } |
220 } | 197 } |
OLD | NEW |