 Chromium Code Reviews
 Chromium Code Reviews Issue 2737263006:
  [Android Crash Reporting] Allow uploading minidumps via the JobScheduler  (Closed)
    
  
    Issue 2737263006:
  [Android Crash Reporting] Allow uploading minidumps via the JobScheduler  (Closed) 
  | 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 package org.chromium.components.minidump_uploader; | 4 package org.chromium.components.minidump_uploader; | 
| 5 | 5 | 
| 6 import android.annotation.TargetApi; | 6 import android.annotation.TargetApi; | 
| 7 import android.app.job.JobInfo; | |
| 7 import android.app.job.JobParameters; | 8 import android.app.job.JobParameters; | 
| 9 import android.app.job.JobScheduler; | |
| 8 import android.app.job.JobService; | 10 import android.app.job.JobService; | 
| 11 import android.content.Context; | |
| 9 import android.os.Build; | 12 import android.os.Build; | 
| 13 import android.os.PersistableBundle; | |
| 14 | |
| 15 import org.chromium.base.Log; | |
| 10 | 16 | 
| 11 /** | 17 /** | 
| 12 * Class that interacts with the Android JobScheduler to upload Minidumps at app ropriate times. | 18 * Class that interacts with the Android JobScheduler to upload Minidumps at app ropriate times. | 
| 13 */ | 19 */ | 
| 14 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | 20 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | 
| 
Maria
2017/03/16 04:10:43
switch to Marshmallow?
 
Ilya Sherman
2017/03/16 05:21:03
This class is shared between Chrome and Android We
 | |
| 15 public abstract class MinidumpUploadJobService extends JobService { | 21 public abstract class MinidumpUploadJobService extends JobService { | 
| 
nyquist
2017/03/16 14:52:18
Would it be possible to use BackgroundTask here in
 
Ilya Sherman
2017/03/16 17:46:29
This code is shared with the Android Webview imple
 
nyquist
2017/03/16 18:50:02
BackgroundTask does not support Android L yet.
Al
 
Ilya Sherman
2017/03/16 18:56:08
Okay.  In that case it sounds like it wouldn't mak
 
Tobias Sargeant
2017/03/16 19:01:36
Also WebView has different requirements to Chrome
 
nyquist
2017/03/16 20:06:26
I'm not sure what you mean? For now BackgroundTask
 
Tobias Sargeant
2017/03/16 20:51:30
Sorry, I spoke too quickly without looking into ho
 | |
| 16 Object mRunningLock = new Object(); | 22 private static final String TAG = "MinidumpJobService"; | 
| 17 boolean mRunningJob = false; | 23 | 
| 18 MinidumpUploader mMinidumpUploader; | 24 // Initial back-off time for upload-job, i.e. the minimum delay when a job i s retried. A retry | 
| 25 // will happen when there are minidumps left after trying to upload all mini dumps. This could | |
| 26 // happen if an upload attempt fails, or if more minidumps are added at the same time as | |
| 27 // uploading old ones. The initial backoff is set to a fairly high number (3 0 minutes) to | |
| 28 // increase the chance of performing uploads in batches if the initial uploa d fails. | |
| 29 private static final int JOB_INITIAL_BACKOFF_TIME_IN_MS = 1000 * 60 * 30; | |
| 30 | |
| 31 // Back-off policy for upload-job. | |
| 32 private static final int JOB_BACKOFF_POLICY = JobInfo.BACKOFF_POLICY_EXPONEN TIAL; | |
| 33 | |
| 34 private MinidumpUploader mMinidumpUploader; | |
| 35 | |
| 36 // Used in Debug builds to assert that this job service never attempts to ru n more than one job | |
| 37 // at a time: | |
| 38 private final Object mRunningLock = new Object(); | |
| 39 private boolean mRunningJob = false; | |
| 40 | |
| 41 /** | |
| 42 * Schedules uploading of all pending minidumps. | |
| 43 * @param context The application context, in which to schedule the crash re port uploads. | |
| 44 * @param jobInfoBuilder A job info builder that has been initialized with a ny embedder-specific | |
| 45 * requriements. This builder will be extended to include shared require ments, and then used | |
| 46 * to build an upload job for scheduling. | |
| 47 */ | |
| 48 public static void scheduleUpload(Context context, JobInfo.Builder jobInfoBu ilder) { | |
| 49 Log.i(TAG, "Scheduling upload of all pending minidumps."); | |
| 50 JobScheduler scheduler = | |
| 51 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SE RVICE); | |
| 52 JobInfo uploadJob = | |
| 53 jobInfoBuilder | |
| 54 .setBackoffCriteria(JOB_INITIAL_BACKOFF_TIME_IN_MS, JOB_ BACKOFF_POLICY) | |
| 55 .build(); | |
| 56 if (scheduler.schedule(uploadJob) == JobScheduler.RESULT_FAILURE) { | |
| 57 throw new RuntimeException("Couldn't schedule " + uploadJob); | |
| 
Maria
2017/03/16 04:10:43
hmm, when can this happen? If I am reading it corr
 
Ilya Sherman
2017/03/16 05:21:03
It can only happen if the job is misconfigured, i.
 
Maria
2017/03/16 05:45:19
Hmm, how about an assert instead? It will alert th
 
Ilya Sherman
2017/03/16 17:46:29
Okay, I'll check later today whether an assert wou
 
Ilya Sherman
2017/03/16 18:35:19
Actually, I suppose we use asserts in various othe
 | |
| 58 } | |
| 59 } | |
| 19 | 60 | 
| 20 @Override | 61 @Override | 
| 21 public boolean onStartJob(JobParameters params) { | 62 public boolean onStartJob(JobParameters params) { | 
| 22 // Ensure we only run one job at a time. | 63 // Ensure we only run one job at a time. | 
| 23 synchronized (mRunningLock) { | 64 synchronized (mRunningLock) { | 
| 24 assert !mRunningJob; | 65 assert !mRunningJob; | 
| 25 mRunningJob = true; | 66 mRunningJob = true; | 
| 26 } | 67 } | 
| 27 mMinidumpUploader = createMinidumpUploader(); | 68 mMinidumpUploader = createMinidumpUploader(params.getExtras()); | 
| 28 mMinidumpUploader.uploadAllMinidumps(createJobFinishedCallback(params)); | 69 mMinidumpUploader.uploadAllMinidumps(createJobFinishedCallback(params)); | 
| 29 return true; // true = processing work on a separate thread, false = don e already. | 70 return true; // true = processing work on a separate thread, false = don e already. | 
| 30 } | 71 } | 
| 31 | 72 | 
| 32 @Override | 73 @Override | 
| 33 public boolean onStopJob(JobParameters params) { | 74 public boolean onStopJob(JobParameters params) { | 
| 75 Log.i(TAG, "Canceling pending uploads due to change in networking status ."); | |
| 34 boolean reschedule = mMinidumpUploader.cancelUploads(); | 76 boolean reschedule = mMinidumpUploader.cancelUploads(); | 
| 35 synchronized (mRunningLock) { | 77 synchronized (mRunningLock) { | 
| 36 mRunningJob = false; | 78 mRunningJob = false; | 
| 37 } | 79 } | 
| 38 return reschedule; | 80 return reschedule; | 
| 39 } | 81 } | 
| 40 | 82 | 
| 41 @Override | 83 @Override | 
| 42 public void onDestroy() { | 84 public void onDestroy() { | 
| 43 mMinidumpUploader = null; | 85 mMinidumpUploader = null; | 
| 44 super.onDestroy(); | 86 super.onDestroy(); | 
| 45 } | 87 } | 
| 46 | 88 | 
| 47 private MinidumpUploader.UploadsFinishedCallback createJobFinishedCallback( | 89 private MinidumpUploader.UploadsFinishedCallback createJobFinishedCallback( | 
| 48 final JobParameters params) { | 90 final JobParameters params) { | 
| 49 return new MinidumpUploader.UploadsFinishedCallback() { | 91 return new MinidumpUploader.UploadsFinishedCallback() { | 
| 50 @Override | 92 @Override | 
| 51 public void uploadsFinished(boolean reschedule) { | 93 public void uploadsFinished(boolean reschedule) { | 
| 94 if (reschedule) { | |
| 95 Log.i(TAG, "Some minidumps remain un-uploaded; rescheduling. "); | |
| 96 } | |
| 52 synchronized (mRunningLock) { | 97 synchronized (mRunningLock) { | 
| 53 mRunningJob = false; | 98 mRunningJob = false; | 
| 54 } | 99 } | 
| 55 MinidumpUploadJobService.this.jobFinished(params, reschedule); | 100 MinidumpUploadJobService.this.jobFinished(params, reschedule); | 
| 56 } | 101 } | 
| 57 }; | 102 }; | 
| 58 } | 103 } | 
| 59 | 104 | 
| 60 /** | 105 /** | 
| 106 * @param extras Any extra data persisted for this job. | |
| 61 * @return The minidump uploader that jobs should use. | 107 * @return The minidump uploader that jobs should use. | 
| 62 */ | 108 */ | 
| 63 protected abstract MinidumpUploader createMinidumpUploader(); | 109 protected abstract MinidumpUploader createMinidumpUploader(PersistableBundle extras); | 
| 64 } | 110 } | 
| OLD | NEW |