1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.car.bugreport; 17 18 import android.app.job.JobInfo; 19 import android.app.job.JobScheduler; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.os.SystemProperties; 23 import android.util.Log; 24 25 /** 26 * Utilities for scheduling upload jobs. 27 */ 28 class JobSchedulingUtils { 29 private static final String TAG = JobSchedulingUtils.class.getSimpleName(); 30 31 private static final int UPLOAD_JOB_ID = 1; 32 private static final int RETRY_DELAY_IN_MS = 5_000; 33 34 /** 35 * The system property to disable auto-upload when bug reports are collected. When auto-upload 36 * is disabled, the app waits for user action on collected bug reports: user can either 37 * upload to Google Cloud or copy to flash drive. 38 */ 39 private static final String PROP_DISABLE_AUTO_UPLOAD = 40 "android.car.bugreport.disableautoupload"; 41 42 /** 43 * Schedules an upload job under the current user. 44 * 45 * <p>Make sure this method is called under the primary user. 46 * 47 * <ul> 48 * <li>require network connectivity 49 * <li>good quality network (large upload size) 50 * <li>persist across reboots 51 * </ul> 52 */ scheduleUploadJob(Context context)53 static void scheduleUploadJob(Context context) { 54 JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); 55 if (jobScheduler == null) { 56 Log.w(TAG, "Cannot get JobScheduler from context."); 57 return; 58 } 59 60 JobInfo pendingJob = jobScheduler.getPendingJob(UPLOAD_JOB_ID); 61 // if there is already a pending job, do not schedule a new one. 62 if (pendingJob != null) { 63 Log.d(TAG, "Upload job is already active, not re-scheduling"); 64 return; 65 } 66 67 // NOTE: Don't set estimated network bytes, because we want bug reports to be uploaded 68 // without any constraints. 69 jobScheduler.schedule(new JobInfo.Builder(UPLOAD_JOB_ID, 70 new ComponentName(context, UploadJob.class)) 71 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) 72 .setBackoffCriteria(RETRY_DELAY_IN_MS, JobInfo.BACKOFF_POLICY_LINEAR) 73 .build()); 74 } 75 76 /** 77 * Returns true if collected bugreports should be uploaded automatically. 78 * 79 * <p>If it returns false, the app maps to an alternative workflow that requires user action 80 * after bugreport is successfully written. A user then has an option to choose whether to 81 * upload the bugreport or copy it to an external drive. 82 */ uploadByDefault()83 static boolean uploadByDefault() { 84 return !SystemProperties.getBoolean(PROP_DISABLE_AUTO_UPLOAD, false); 85 } 86 } 87