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; | 10 import android.app.job.JobScheduler; |
11 import android.content.ComponentName; | 11 import android.content.ComponentName; |
12 import android.content.Context; | 12 import android.content.Context; |
13 import android.content.Intent; | 13 import android.content.Intent; |
14 import android.os.Binder; | 14 import android.os.Binder; |
15 import android.os.Build; | 15 import android.os.Build; |
16 import android.os.IBinder; | 16 import android.os.IBinder; |
17 import android.os.ParcelFileDescriptor; | 17 import android.os.ParcelFileDescriptor; |
18 | 18 |
19 import org.chromium.base.Log; | 19 import org.chromium.base.Log; |
20 import org.chromium.base.VisibleForTesting; | 20 import org.chromium.base.VisibleForTesting; |
21 import org.chromium.components.minidump_uploader.CrashFileManager; | 21 import org.chromium.components.minidump_uploader.CrashFileManager; |
22 | 22 |
23 import java.io.File; | 23 import java.io.File; |
24 import java.io.IOException; | 24 import java.io.IOException; |
25 import java.util.List; | |
26 | 25 |
27 /** | 26 /** |
28 * 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. |
29 */ | 28 */ |
30 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | 29 @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
31 public class CrashReceiverService extends Service { | 30 public class CrashReceiverService extends Service { |
32 private static final String TAG = "CrashReceiverService"; | 31 private static final String TAG = "CrashReceiverService"; |
33 | 32 |
34 private static final String WEBVIEW_CRASH_DIR = "WebView_Crashes"; | 33 private static final String WEBVIEW_CRASH_DIR = "WebView_Crashes"; |
35 private static final String WEBVIEW_TMP_CRASH_DIR = "WebView_Crashes_Tmp"; | 34 private static final String WEBVIEW_TMP_CRASH_DIR = "WebView_Crashes_Tmp"; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 ParcelFileDescriptor[] fileDescriptors, boolean scheduleUploads) { | 68 ParcelFileDescriptor[] fileDescriptors, boolean scheduleUploads) { |
70 if (!waitUntilWeCanCopy()) { | 69 if (!waitUntilWeCanCopy()) { |
71 Log.e(TAG, "something went wrong when waiting to copy minidumps, bai
ling!"); | 70 Log.e(TAG, "something went wrong when waiting to copy minidumps, bai
ling!"); |
72 return; | 71 return; |
73 } | 72 } |
74 | 73 |
75 try { | 74 try { |
76 boolean copySucceeded = copyMinidumps(context, uid, fileDescriptors)
; | 75 boolean copySucceeded = copyMinidumps(context, uid, fileDescriptors)
; |
77 if (copySucceeded && scheduleUploads) { | 76 if (copySucceeded && scheduleUploads) { |
78 // Only schedule a new job if there actually are any files to up
load. | 77 // Only schedule a new job if there actually are any files to up
load. |
79 scheduleNewJobIfNoJobsActive(); | 78 scheduleNewJob(); |
80 } | 79 } |
81 } finally { | 80 } finally { |
82 synchronized (mCopyingLock) { | 81 synchronized (mCopyingLock) { |
83 mIsCopying = false; | 82 mIsCopying = false; |
84 mCopyingLock.notifyAll(); | 83 mCopyingLock.notifyAll(); |
85 } | 84 } |
86 } | 85 } |
87 } | 86 } |
88 | 87 |
89 /** | 88 /** |
90 * Wait until we are allowed to copy minidumps. | 89 * Wait until we are allowed to copy minidumps. |
91 * @return whether we are actually allowed to copy the files - if false we s
hould just bail. | 90 * @return whether we are actually allowed to copy the files - if false we s
hould just bail. |
92 */ | 91 */ |
93 private boolean waitUntilWeCanCopy() { | 92 private boolean waitUntilWeCanCopy() { |
94 synchronized (mCopyingLock) { | 93 synchronized (mCopyingLock) { |
95 while (mIsCopying) { | 94 while (mIsCopying) { |
96 try { | 95 try { |
97 mCopyingLock.wait(); | 96 mCopyingLock.wait(); |
98 } catch (InterruptedException e) { | 97 } catch (InterruptedException e) { |
99 Log.e(TAG, "Was interrupted when waiting to copy minidumps",
e); | 98 Log.e(TAG, "Was interrupted when waiting to copy minidumps",
e); |
100 return false; | 99 return false; |
101 } | 100 } |
102 } | 101 } |
103 mIsCopying = true; | 102 mIsCopying = true; |
104 return true; | 103 return true; |
105 } | 104 } |
106 } | 105 } |
107 | 106 |
108 /** | 107 private void scheduleNewJob() { |
109 * @return the currently pending job with ID MINIDUMP_UPLOADING_JOB_ID, or n
ull if no such job | |
110 * exists. | |
111 */ | |
112 private static JobInfo getCurrentPendingJob(JobScheduler jobScheduler) { | |
113 List<JobInfo> pendingJobs = jobScheduler.getAllPendingJobs(); | |
114 for (JobInfo job : pendingJobs) { | |
115 if (job.getId() == MINIDUMP_UPLOADING_JOB_ID) return job; | |
116 } | |
117 return null; | |
118 } | |
119 | |
120 private void scheduleNewJobIfNoJobsActive() { | |
121 JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_
SCHEDULER_SERVICE); | 108 JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_
SCHEDULER_SERVICE); |
122 if (getCurrentPendingJob(jobScheduler) != null) { | |
123 return; | |
124 } | |
125 JobInfo newJob = new JobInfo | 109 JobInfo newJob = new JobInfo |
126 .Builder(MINIDUMP_UPLOADING_JOB_ID /* jobId */, | 110 .Builder(MINIDUMP_UPLOADING_JOB_ID /* jobId */, |
127 new ComponentName(this, MinidumpUploadJobService.class)) | 111 new ComponentName(this, MinidumpUploadJobService.class)) |
128 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) | 112 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) |
129 // Minimum delay when a job is retried (a retry will happen when
there are minidumps | 113 // Minimum delay when a job is retried (a retry will happen when
there are minidumps |
130 // left after trying to upload all minidumps - this could e.g. h
appen if we add more | 114 // left after trying to upload all minidumps - this could e.g. h
appen if we add more |
131 // minidumps at the same time as uploading old ones). | 115 // minidumps at the same time as uploading old ones). |
132 .setBackoffCriteria(JOB_BACKOFF_TIME_IN_MS, JOB_BACKOFF_POLICY) | 116 .setBackoffCriteria(JOB_BACKOFF_TIME_IN_MS, JOB_BACKOFF_POLICY) |
133 .build(); | 117 .build(); |
134 if (jobScheduler.schedule(newJob) == JobScheduler.RESULT_FAILURE) { | 118 if (jobScheduler.schedule(newJob) == JobScheduler.RESULT_FAILURE) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 @VisibleForTesting | 210 @VisibleForTesting |
227 public static File getWebViewTmpCrashDir(Context context) { | 211 public static File getWebViewTmpCrashDir(Context context) { |
228 return new File(context.getCacheDir(), WEBVIEW_TMP_CRASH_DIR); | 212 return new File(context.getCacheDir(), WEBVIEW_TMP_CRASH_DIR); |
229 } | 213 } |
230 | 214 |
231 @Override | 215 @Override |
232 public IBinder onBind(Intent intent) { | 216 public IBinder onBind(Intent intent) { |
233 return mBinder; | 217 return mBinder; |
234 } | 218 } |
235 } | 219 } |
OLD | NEW |