1*b7c941bbSAndroid Build Coastguard Worker /* 2*b7c941bbSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*b7c941bbSAndroid Build Coastguard Worker * 4*b7c941bbSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*b7c941bbSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*b7c941bbSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*b7c941bbSAndroid Build Coastguard Worker * 8*b7c941bbSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*b7c941bbSAndroid Build Coastguard Worker * 10*b7c941bbSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*b7c941bbSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*b7c941bbSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*b7c941bbSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*b7c941bbSAndroid Build Coastguard Worker * limitations under the License. 15*b7c941bbSAndroid Build Coastguard Worker */ 16*b7c941bbSAndroid Build Coastguard Worker 17*b7c941bbSAndroid Build Coastguard Worker package android.jobscheduler; 18*b7c941bbSAndroid Build Coastguard Worker 19*b7c941bbSAndroid Build Coastguard Worker import android.annotation.NonNull; 20*b7c941bbSAndroid Build Coastguard Worker import android.annotation.TargetApi; 21*b7c941bbSAndroid Build Coastguard Worker import android.app.Notification; 22*b7c941bbSAndroid Build Coastguard Worker import android.app.job.JobInfo; 23*b7c941bbSAndroid Build Coastguard Worker import android.app.job.JobParameters; 24*b7c941bbSAndroid Build Coastguard Worker import android.app.job.JobScheduler; 25*b7c941bbSAndroid Build Coastguard Worker import android.app.job.JobService; 26*b7c941bbSAndroid Build Coastguard Worker import android.app.job.JobWorkItem; 27*b7c941bbSAndroid Build Coastguard Worker import android.content.ClipData; 28*b7c941bbSAndroid Build Coastguard Worker import android.content.Context; 29*b7c941bbSAndroid Build Coastguard Worker import android.content.Intent; 30*b7c941bbSAndroid Build Coastguard Worker import android.content.pm.PackageManager; 31*b7c941bbSAndroid Build Coastguard Worker import android.net.Uri; 32*b7c941bbSAndroid Build Coastguard Worker import android.os.Process; 33*b7c941bbSAndroid Build Coastguard Worker import android.util.Log; 34*b7c941bbSAndroid Build Coastguard Worker 35*b7c941bbSAndroid Build Coastguard Worker import junit.framework.Assert; 36*b7c941bbSAndroid Build Coastguard Worker 37*b7c941bbSAndroid Build Coastguard Worker import java.util.ArrayList; 38*b7c941bbSAndroid Build Coastguard Worker import java.util.List; 39*b7c941bbSAndroid Build Coastguard Worker import java.util.concurrent.CountDownLatch; 40*b7c941bbSAndroid Build Coastguard Worker import java.util.concurrent.TimeUnit; 41*b7c941bbSAndroid Build Coastguard Worker 42*b7c941bbSAndroid Build Coastguard Worker /** 43*b7c941bbSAndroid Build Coastguard Worker * Handles callback from the framework {@link android.app.job.JobScheduler}. The behaviour of this 44*b7c941bbSAndroid Build Coastguard Worker * class is configured through the static 45*b7c941bbSAndroid Build Coastguard Worker * {@link TestEnvironment}. 46*b7c941bbSAndroid Build Coastguard Worker */ 47*b7c941bbSAndroid Build Coastguard Worker @TargetApi(21) 48*b7c941bbSAndroid Build Coastguard Worker public class MockJobService extends JobService { 49*b7c941bbSAndroid Build Coastguard Worker private static final String TAG = "MockJobService"; 50*b7c941bbSAndroid Build Coastguard Worker 51*b7c941bbSAndroid Build Coastguard Worker /** Wait this long before timing out the test. */ 52*b7c941bbSAndroid Build Coastguard Worker private static final long DEFAULT_TIMEOUT_MILLIS = 30000L; // 30 seconds. 53*b7c941bbSAndroid Build Coastguard Worker 54*b7c941bbSAndroid Build Coastguard Worker private JobParameters mParams; 55*b7c941bbSAndroid Build Coastguard Worker 56*b7c941bbSAndroid Build Coastguard Worker ArrayList<JobWorkItem> mReceivedWork = new ArrayList<>(); 57*b7c941bbSAndroid Build Coastguard Worker 58*b7c941bbSAndroid Build Coastguard Worker ArrayList<JobWorkItem> mPendingCompletions = new ArrayList<>(); 59*b7c941bbSAndroid Build Coastguard Worker 60*b7c941bbSAndroid Build Coastguard Worker private boolean mWaitingForStop; 61*b7c941bbSAndroid Build Coastguard Worker 62*b7c941bbSAndroid Build Coastguard Worker private long mEstimatedDownloadBytes = JobInfo.NETWORK_BYTES_UNKNOWN; 63*b7c941bbSAndroid Build Coastguard Worker private long mEstimatedUploadBytes = JobInfo.NETWORK_BYTES_UNKNOWN; 64*b7c941bbSAndroid Build Coastguard Worker private long mTransferredDownloadBytes = JobInfo.NETWORK_BYTES_UNKNOWN; 65*b7c941bbSAndroid Build Coastguard Worker private long mTransferredUploadBytes = JobInfo.NETWORK_BYTES_UNKNOWN; 66*b7c941bbSAndroid Build Coastguard Worker 67*b7c941bbSAndroid Build Coastguard Worker @Override onDestroy()68*b7c941bbSAndroid Build Coastguard Worker public void onDestroy() { 69*b7c941bbSAndroid Build Coastguard Worker super.onDestroy(); 70*b7c941bbSAndroid Build Coastguard Worker Log.i(TAG, "Destroying test service"); 71*b7c941bbSAndroid Build Coastguard Worker if (TestEnvironment.getTestEnvironment().getExpectedWork() != null) { 72*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, mParams, 0, 0, mReceivedWork, 73*b7c941bbSAndroid Build Coastguard Worker null); 74*b7c941bbSAndroid Build Coastguard Worker } 75*b7c941bbSAndroid Build Coastguard Worker } 76*b7c941bbSAndroid Build Coastguard Worker 77*b7c941bbSAndroid Build Coastguard Worker @Override onCreate()78*b7c941bbSAndroid Build Coastguard Worker public void onCreate() { 79*b7c941bbSAndroid Build Coastguard Worker super.onCreate(); 80*b7c941bbSAndroid Build Coastguard Worker Log.i(TAG, "Created test service."); 81*b7c941bbSAndroid Build Coastguard Worker } 82*b7c941bbSAndroid Build Coastguard Worker 83*b7c941bbSAndroid Build Coastguard Worker @Override onStartJob(JobParameters params)84*b7c941bbSAndroid Build Coastguard Worker public boolean onStartJob(JobParameters params) { 85*b7c941bbSAndroid Build Coastguard Worker Log.i(TAG, "Test job executing: " + params.getJobId()); 86*b7c941bbSAndroid Build Coastguard Worker mParams = params; 87*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().addEvent( 88*b7c941bbSAndroid Build Coastguard Worker new TestEnvironment.Event( 89*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.Event.EVENT_START_JOB, params.getJobId())); 90*b7c941bbSAndroid Build Coastguard Worker 91*b7c941bbSAndroid Build Coastguard Worker final Notification notificationToPost = 92*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().getJobStartNotification(); 93*b7c941bbSAndroid Build Coastguard Worker if (notificationToPost != null) { 94*b7c941bbSAndroid Build Coastguard Worker setNotification(params, 95*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().getJobStartNotificationId(), 96*b7c941bbSAndroid Build Coastguard Worker notificationToPost, 97*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().getJobStartNotificationEndPolicy()); 98*b7c941bbSAndroid Build Coastguard Worker } 99*b7c941bbSAndroid Build Coastguard Worker int permCheckRead = PackageManager.PERMISSION_DENIED; 100*b7c941bbSAndroid Build Coastguard Worker int permCheckWrite = PackageManager.PERMISSION_DENIED; 101*b7c941bbSAndroid Build Coastguard Worker ClipData clip = params.getClipData(); 102*b7c941bbSAndroid Build Coastguard Worker if (clip != null) { 103*b7c941bbSAndroid Build Coastguard Worker permCheckRead = checkUriPermission(clip.getItemAt(0).getUri(), Process.myPid(), 104*b7c941bbSAndroid Build Coastguard Worker Process.myUid(), Intent.FLAG_GRANT_READ_URI_PERMISSION); 105*b7c941bbSAndroid Build Coastguard Worker permCheckWrite = checkUriPermission(clip.getItemAt(0).getUri(), Process.myPid(), 106*b7c941bbSAndroid Build Coastguard Worker Process.myUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 107*b7c941bbSAndroid Build Coastguard Worker } 108*b7c941bbSAndroid Build Coastguard Worker 109*b7c941bbSAndroid Build Coastguard Worker TestWorkItem[] expectedWork = TestEnvironment.getTestEnvironment().getExpectedWork(); 110*b7c941bbSAndroid Build Coastguard Worker if (expectedWork != null) { 111*b7c941bbSAndroid Build Coastguard Worker try { 112*b7c941bbSAndroid Build Coastguard Worker if (!TestEnvironment.getTestEnvironment().awaitDoWork()) { 113*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, 114*b7c941bbSAndroid Build Coastguard Worker params, permCheckRead, 115*b7c941bbSAndroid Build Coastguard Worker permCheckWrite, null, "Spent too long waiting to start executing work"); 116*b7c941bbSAndroid Build Coastguard Worker return false; 117*b7c941bbSAndroid Build Coastguard Worker } 118*b7c941bbSAndroid Build Coastguard Worker } catch (InterruptedException e) { 119*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, 120*b7c941bbSAndroid Build Coastguard Worker params, permCheckRead, 121*b7c941bbSAndroid Build Coastguard Worker permCheckWrite, null, "Failed waiting for work: " + e); 122*b7c941bbSAndroid Build Coastguard Worker return false; 123*b7c941bbSAndroid Build Coastguard Worker } 124*b7c941bbSAndroid Build Coastguard Worker JobWorkItem work; 125*b7c941bbSAndroid Build Coastguard Worker int index = 0; 126*b7c941bbSAndroid Build Coastguard Worker while ((work = params.dequeueWork()) != null) { 127*b7c941bbSAndroid Build Coastguard Worker final Intent intent = work.getIntent(); 128*b7c941bbSAndroid Build Coastguard Worker Log.i(TAG, "Received work #" + index + ": " + intent); 129*b7c941bbSAndroid Build Coastguard Worker mReceivedWork.add(work); 130*b7c941bbSAndroid Build Coastguard Worker 131*b7c941bbSAndroid Build Coastguard Worker int flags = 0; 132*b7c941bbSAndroid Build Coastguard Worker 133*b7c941bbSAndroid Build Coastguard Worker if (index < expectedWork.length) { 134*b7c941bbSAndroid Build Coastguard Worker TestWorkItem expected = expectedWork[index]; 135*b7c941bbSAndroid Build Coastguard Worker int grantFlags = intent == null ? 0 : intent.getFlags(); 136*b7c941bbSAndroid Build Coastguard Worker if (expected.requireUrisGranted != null) { 137*b7c941bbSAndroid Build Coastguard Worker for (int ui = 0; ui < expected.requireUrisGranted.length; ui++) { 138*b7c941bbSAndroid Build Coastguard Worker if ((grantFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 139*b7c941bbSAndroid Build Coastguard Worker if (checkUriPermission(expected.requireUrisGranted[ui], 140*b7c941bbSAndroid Build Coastguard Worker Process.myPid(), Process.myUid(), 141*b7c941bbSAndroid Build Coastguard Worker Intent.FLAG_GRANT_READ_URI_PERMISSION) 142*b7c941bbSAndroid Build Coastguard Worker != PackageManager.PERMISSION_GRANTED) { 143*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, 144*b7c941bbSAndroid Build Coastguard Worker params, 145*b7c941bbSAndroid Build Coastguard Worker permCheckRead, permCheckWrite, null, 146*b7c941bbSAndroid Build Coastguard Worker "Expected read permission but not granted: " 147*b7c941bbSAndroid Build Coastguard Worker + expected.requireUrisGranted[ui] 148*b7c941bbSAndroid Build Coastguard Worker + " @ #" + index); 149*b7c941bbSAndroid Build Coastguard Worker return false; 150*b7c941bbSAndroid Build Coastguard Worker } 151*b7c941bbSAndroid Build Coastguard Worker } 152*b7c941bbSAndroid Build Coastguard Worker if ((grantFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 153*b7c941bbSAndroid Build Coastguard Worker if (checkUriPermission(expected.requireUrisGranted[ui], 154*b7c941bbSAndroid Build Coastguard Worker Process.myPid(), Process.myUid(), 155*b7c941bbSAndroid Build Coastguard Worker Intent.FLAG_GRANT_WRITE_URI_PERMISSION) 156*b7c941bbSAndroid Build Coastguard Worker != PackageManager.PERMISSION_GRANTED) { 157*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, 158*b7c941bbSAndroid Build Coastguard Worker params, 159*b7c941bbSAndroid Build Coastguard Worker permCheckRead, permCheckWrite, null, 160*b7c941bbSAndroid Build Coastguard Worker "Expected write permission but not granted: " 161*b7c941bbSAndroid Build Coastguard Worker + expected.requireUrisGranted[ui] 162*b7c941bbSAndroid Build Coastguard Worker + " @ #" + index); 163*b7c941bbSAndroid Build Coastguard Worker return false; 164*b7c941bbSAndroid Build Coastguard Worker } 165*b7c941bbSAndroid Build Coastguard Worker } 166*b7c941bbSAndroid Build Coastguard Worker } 167*b7c941bbSAndroid Build Coastguard Worker } 168*b7c941bbSAndroid Build Coastguard Worker if (expected.requireUrisNotGranted != null) { 169*b7c941bbSAndroid Build Coastguard Worker // XXX note no delay here, current impl will have fully revoked the 170*b7c941bbSAndroid Build Coastguard Worker // permission by the time we return from completing the last work. 171*b7c941bbSAndroid Build Coastguard Worker for (int ui = 0; ui < expected.requireUrisNotGranted.length; ui++) { 172*b7c941bbSAndroid Build Coastguard Worker if ((grantFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 173*b7c941bbSAndroid Build Coastguard Worker if (checkUriPermission(expected.requireUrisNotGranted[ui], 174*b7c941bbSAndroid Build Coastguard Worker Process.myPid(), Process.myUid(), 175*b7c941bbSAndroid Build Coastguard Worker Intent.FLAG_GRANT_READ_URI_PERMISSION) 176*b7c941bbSAndroid Build Coastguard Worker != PackageManager.PERMISSION_DENIED) { 177*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, 178*b7c941bbSAndroid Build Coastguard Worker params, 179*b7c941bbSAndroid Build Coastguard Worker permCheckRead, permCheckWrite, null, 180*b7c941bbSAndroid Build Coastguard Worker "Not expected read permission but granted: " 181*b7c941bbSAndroid Build Coastguard Worker + expected.requireUrisNotGranted[ui] 182*b7c941bbSAndroid Build Coastguard Worker + " @ #" + index); 183*b7c941bbSAndroid Build Coastguard Worker return false; 184*b7c941bbSAndroid Build Coastguard Worker } 185*b7c941bbSAndroid Build Coastguard Worker } 186*b7c941bbSAndroid Build Coastguard Worker if ((grantFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 187*b7c941bbSAndroid Build Coastguard Worker if (checkUriPermission(expected.requireUrisNotGranted[ui], 188*b7c941bbSAndroid Build Coastguard Worker Process.myPid(), Process.myUid(), 189*b7c941bbSAndroid Build Coastguard Worker Intent.FLAG_GRANT_WRITE_URI_PERMISSION) 190*b7c941bbSAndroid Build Coastguard Worker != PackageManager.PERMISSION_DENIED) { 191*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, 192*b7c941bbSAndroid Build Coastguard Worker params, 193*b7c941bbSAndroid Build Coastguard Worker permCheckRead, permCheckWrite, null, 194*b7c941bbSAndroid Build Coastguard Worker "Not expected write permission but granted: " 195*b7c941bbSAndroid Build Coastguard Worker + expected.requireUrisNotGranted[ui] 196*b7c941bbSAndroid Build Coastguard Worker + " @ #" + index); 197*b7c941bbSAndroid Build Coastguard Worker return false; 198*b7c941bbSAndroid Build Coastguard Worker } 199*b7c941bbSAndroid Build Coastguard Worker } 200*b7c941bbSAndroid Build Coastguard Worker } 201*b7c941bbSAndroid Build Coastguard Worker } 202*b7c941bbSAndroid Build Coastguard Worker 203*b7c941bbSAndroid Build Coastguard Worker flags = expected.flags; 204*b7c941bbSAndroid Build Coastguard Worker 205*b7c941bbSAndroid Build Coastguard Worker if ((flags & TestWorkItem.FLAG_WAIT_FOR_STOP) != 0) { 206*b7c941bbSAndroid Build Coastguard Worker Log.i(TAG, "Now waiting to stop"); 207*b7c941bbSAndroid Build Coastguard Worker mWaitingForStop = true; 208*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyWaitingForStop(); 209*b7c941bbSAndroid Build Coastguard Worker return true; 210*b7c941bbSAndroid Build Coastguard Worker } 211*b7c941bbSAndroid Build Coastguard Worker 212*b7c941bbSAndroid Build Coastguard Worker if ((flags & TestWorkItem.FLAG_COMPLETE_NEXT) != 0) { 213*b7c941bbSAndroid Build Coastguard Worker if (!processNextPendingCompletion()) { 214*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, params, 215*b7c941bbSAndroid Build Coastguard Worker 0, 0, null, 216*b7c941bbSAndroid Build Coastguard Worker "Expected to complete next pending work but there was none: " 217*b7c941bbSAndroid Build Coastguard Worker + " @ #" + index); 218*b7c941bbSAndroid Build Coastguard Worker return false; 219*b7c941bbSAndroid Build Coastguard Worker } 220*b7c941bbSAndroid Build Coastguard Worker } 221*b7c941bbSAndroid Build Coastguard Worker } 222*b7c941bbSAndroid Build Coastguard Worker 223*b7c941bbSAndroid Build Coastguard Worker if ((flags & TestWorkItem.FLAG_DELAY_COMPLETE_PUSH_BACK) != 0) { 224*b7c941bbSAndroid Build Coastguard Worker mPendingCompletions.add(work); 225*b7c941bbSAndroid Build Coastguard Worker } else if ((flags & TestWorkItem.FLAG_DELAY_COMPLETE_PUSH_TOP) != 0) { 226*b7c941bbSAndroid Build Coastguard Worker mPendingCompletions.add(0, work); 227*b7c941bbSAndroid Build Coastguard Worker } else { 228*b7c941bbSAndroid Build Coastguard Worker mParams.completeWork(work); 229*b7c941bbSAndroid Build Coastguard Worker } 230*b7c941bbSAndroid Build Coastguard Worker 231*b7c941bbSAndroid Build Coastguard Worker if (index < expectedWork.length) { 232*b7c941bbSAndroid Build Coastguard Worker TestWorkItem expected = expectedWork[index]; 233*b7c941bbSAndroid Build Coastguard Worker if (expected.subitems != null) { 234*b7c941bbSAndroid Build Coastguard Worker final TestWorkItem[] sub = expected.subitems; 235*b7c941bbSAndroid Build Coastguard Worker final JobInfo ji = expected.jobInfo; 236*b7c941bbSAndroid Build Coastguard Worker final JobScheduler js = (JobScheduler) getSystemService( 237*b7c941bbSAndroid Build Coastguard Worker Context.JOB_SCHEDULER_SERVICE); 238*b7c941bbSAndroid Build Coastguard Worker for (int subi = 0; subi < sub.length; subi++) { 239*b7c941bbSAndroid Build Coastguard Worker js.enqueue(ji, new JobWorkItem(sub[subi].intent)); 240*b7c941bbSAndroid Build Coastguard Worker } 241*b7c941bbSAndroid Build Coastguard Worker } 242*b7c941bbSAndroid Build Coastguard Worker } 243*b7c941bbSAndroid Build Coastguard Worker 244*b7c941bbSAndroid Build Coastguard Worker index++; 245*b7c941bbSAndroid Build Coastguard Worker } 246*b7c941bbSAndroid Build Coastguard Worker 247*b7c941bbSAndroid Build Coastguard Worker if (processNextPendingCompletion()) { 248*b7c941bbSAndroid Build Coastguard Worker // We had some pending completions, clean them all out... 249*b7c941bbSAndroid Build Coastguard Worker while (processNextPendingCompletion()) { 250*b7c941bbSAndroid Build Coastguard Worker } 251*b7c941bbSAndroid Build Coastguard Worker // ...and we need to do a final dequeue to complete the job, which should not 252*b7c941bbSAndroid Build Coastguard Worker // return any remaining work. 253*b7c941bbSAndroid Build Coastguard Worker if ((work = params.dequeueWork()) != null) { 254*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, params, 255*b7c941bbSAndroid Build Coastguard Worker 0, 0, null, 256*b7c941bbSAndroid Build Coastguard Worker "Expected no remaining work after dequeue pending, but got: " + work); 257*b7c941bbSAndroid Build Coastguard Worker } 258*b7c941bbSAndroid Build Coastguard Worker } 259*b7c941bbSAndroid Build Coastguard Worker 260*b7c941bbSAndroid Build Coastguard Worker Log.i(TAG, "Done with all work at #" + index); 261*b7c941bbSAndroid Build Coastguard Worker // We don't notifyExecution here because we want to make sure the job properly 262*b7c941bbSAndroid Build Coastguard Worker // stops itself. 263*b7c941bbSAndroid Build Coastguard Worker return true; 264*b7c941bbSAndroid Build Coastguard Worker } else { 265*b7c941bbSAndroid Build Coastguard Worker boolean continueAfterStart 266*b7c941bbSAndroid Build Coastguard Worker = TestEnvironment.getTestEnvironment().handleContinueAfterStart(); 267*b7c941bbSAndroid Build Coastguard Worker try { 268*b7c941bbSAndroid Build Coastguard Worker if (!TestEnvironment.getTestEnvironment().awaitDoJob()) { 269*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, 270*b7c941bbSAndroid Build Coastguard Worker params, permCheckRead, 271*b7c941bbSAndroid Build Coastguard Worker permCheckWrite, null, "Spent too long waiting to start job"); 272*b7c941bbSAndroid Build Coastguard Worker return false; 273*b7c941bbSAndroid Build Coastguard Worker } 274*b7c941bbSAndroid Build Coastguard Worker } catch (InterruptedException e) { 275*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, params, permCheckRead, 276*b7c941bbSAndroid Build Coastguard Worker permCheckWrite, null, "Failed waiting to start job: " + e); 277*b7c941bbSAndroid Build Coastguard Worker return false; 278*b7c941bbSAndroid Build Coastguard Worker } 279*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyExecution(this, params, permCheckRead, 280*b7c941bbSAndroid Build Coastguard Worker permCheckWrite, null, null); 281*b7c941bbSAndroid Build Coastguard Worker return continueAfterStart; 282*b7c941bbSAndroid Build Coastguard Worker } 283*b7c941bbSAndroid Build Coastguard Worker } 284*b7c941bbSAndroid Build Coastguard Worker 285*b7c941bbSAndroid Build Coastguard Worker @Override onNetworkChanged(JobParameters params)286*b7c941bbSAndroid Build Coastguard Worker public void onNetworkChanged(JobParameters params) { 287*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyNetworkChanged(params); 288*b7c941bbSAndroid Build Coastguard Worker } 289*b7c941bbSAndroid Build Coastguard Worker processNextPendingCompletion()290*b7c941bbSAndroid Build Coastguard Worker boolean processNextPendingCompletion() { 291*b7c941bbSAndroid Build Coastguard Worker if (mPendingCompletions.size() <= 0) { 292*b7c941bbSAndroid Build Coastguard Worker return false; 293*b7c941bbSAndroid Build Coastguard Worker } 294*b7c941bbSAndroid Build Coastguard Worker 295*b7c941bbSAndroid Build Coastguard Worker JobWorkItem next = mPendingCompletions.remove(0); 296*b7c941bbSAndroid Build Coastguard Worker mParams.completeWork(next); 297*b7c941bbSAndroid Build Coastguard Worker return true; 298*b7c941bbSAndroid Build Coastguard Worker } 299*b7c941bbSAndroid Build Coastguard Worker 300*b7c941bbSAndroid Build Coastguard Worker @Override onStopJob(JobParameters params)301*b7c941bbSAndroid Build Coastguard Worker public boolean onStopJob(JobParameters params) { 302*b7c941bbSAndroid Build Coastguard Worker Log.i(TAG, "Received stop callback"); 303*b7c941bbSAndroid Build Coastguard Worker TestEnvironment.getTestEnvironment().notifyStopped(params); 304*b7c941bbSAndroid Build Coastguard Worker return mWaitingForStop || TestEnvironment.getTestEnvironment().requestReschedule(); 305*b7c941bbSAndroid Build Coastguard Worker } 306*b7c941bbSAndroid Build Coastguard Worker 307*b7c941bbSAndroid Build Coastguard Worker @Override getTransferredDownloadBytes(@onNull JobParameters params)308*b7c941bbSAndroid Build Coastguard Worker public long getTransferredDownloadBytes(@NonNull JobParameters params) { 309*b7c941bbSAndroid Build Coastguard Worker return mTransferredDownloadBytes; 310*b7c941bbSAndroid Build Coastguard Worker } 311*b7c941bbSAndroid Build Coastguard Worker 312*b7c941bbSAndroid Build Coastguard Worker @Override getTransferredUploadBytes(@onNull JobParameters params)313*b7c941bbSAndroid Build Coastguard Worker public long getTransferredUploadBytes(@NonNull JobParameters params) { 314*b7c941bbSAndroid Build Coastguard Worker return mTransferredUploadBytes; 315*b7c941bbSAndroid Build Coastguard Worker } 316*b7c941bbSAndroid Build Coastguard Worker 317*b7c941bbSAndroid Build Coastguard Worker @Override getTransferredDownloadBytes(@onNull JobParameters params, @NonNull JobWorkItem item)318*b7c941bbSAndroid Build Coastguard Worker public long getTransferredDownloadBytes(@NonNull JobParameters params, 319*b7c941bbSAndroid Build Coastguard Worker @NonNull JobWorkItem item) { 320*b7c941bbSAndroid Build Coastguard Worker return mTransferredDownloadBytes; 321*b7c941bbSAndroid Build Coastguard Worker } 322*b7c941bbSAndroid Build Coastguard Worker 323*b7c941bbSAndroid Build Coastguard Worker @Override getTransferredUploadBytes(@onNull JobParameters params, @NonNull JobWorkItem item)324*b7c941bbSAndroid Build Coastguard Worker public long getTransferredUploadBytes(@NonNull JobParameters params, 325*b7c941bbSAndroid Build Coastguard Worker @NonNull JobWorkItem item) { 326*b7c941bbSAndroid Build Coastguard Worker return mTransferredUploadBytes; 327*b7c941bbSAndroid Build Coastguard Worker } 328*b7c941bbSAndroid Build Coastguard Worker setEstimatedNetworkBytesForTest(long downloadBytes, long uploadBytes)329*b7c941bbSAndroid Build Coastguard Worker private void setEstimatedNetworkBytesForTest(long downloadBytes, long uploadBytes) { 330*b7c941bbSAndroid Build Coastguard Worker mEstimatedDownloadBytes = downloadBytes; 331*b7c941bbSAndroid Build Coastguard Worker mEstimatedUploadBytes = uploadBytes; 332*b7c941bbSAndroid Build Coastguard Worker updateEstimatedNetworkBytes(mParams, downloadBytes, uploadBytes); 333*b7c941bbSAndroid Build Coastguard Worker } 334*b7c941bbSAndroid Build Coastguard Worker setTransferredBytesForTest(long downloadBytes, long uploadBytes)335*b7c941bbSAndroid Build Coastguard Worker private void setTransferredBytesForTest(long downloadBytes, long uploadBytes) { 336*b7c941bbSAndroid Build Coastguard Worker mTransferredDownloadBytes = downloadBytes; 337*b7c941bbSAndroid Build Coastguard Worker mTransferredUploadBytes = uploadBytes; 338*b7c941bbSAndroid Build Coastguard Worker updateTransferredNetworkBytes(mParams, downloadBytes, uploadBytes); 339*b7c941bbSAndroid Build Coastguard Worker } 340*b7c941bbSAndroid Build Coastguard Worker 341*b7c941bbSAndroid Build Coastguard Worker public static final class TestWorkItem { 342*b7c941bbSAndroid Build Coastguard Worker /** 343*b7c941bbSAndroid Build Coastguard Worker * Stop processing work for now, waiting for the service to be stopped. 344*b7c941bbSAndroid Build Coastguard Worker */ 345*b7c941bbSAndroid Build Coastguard Worker public static final int FLAG_WAIT_FOR_STOP = 1<<0; 346*b7c941bbSAndroid Build Coastguard Worker /** 347*b7c941bbSAndroid Build Coastguard Worker * Don't complete this work now, instead push it on the back of the stack of 348*b7c941bbSAndroid Build Coastguard Worker * pending completions. 349*b7c941bbSAndroid Build Coastguard Worker */ 350*b7c941bbSAndroid Build Coastguard Worker public static final int FLAG_DELAY_COMPLETE_PUSH_BACK = 1<<1; 351*b7c941bbSAndroid Build Coastguard Worker /** 352*b7c941bbSAndroid Build Coastguard Worker * Don't complete this work now, instead insert to the top of the stack of 353*b7c941bbSAndroid Build Coastguard Worker * pending completions. 354*b7c941bbSAndroid Build Coastguard Worker */ 355*b7c941bbSAndroid Build Coastguard Worker public static final int FLAG_DELAY_COMPLETE_PUSH_TOP = 1<<2; 356*b7c941bbSAndroid Build Coastguard Worker /** 357*b7c941bbSAndroid Build Coastguard Worker * Complete next pending completion on the stack before completing this one. 358*b7c941bbSAndroid Build Coastguard Worker */ 359*b7c941bbSAndroid Build Coastguard Worker public static final int FLAG_COMPLETE_NEXT = 1<<3; 360*b7c941bbSAndroid Build Coastguard Worker 361*b7c941bbSAndroid Build Coastguard Worker public final Intent intent; 362*b7c941bbSAndroid Build Coastguard Worker public final JobInfo jobInfo; 363*b7c941bbSAndroid Build Coastguard Worker public final int flags; 364*b7c941bbSAndroid Build Coastguard Worker public final int deliveryCount; 365*b7c941bbSAndroid Build Coastguard Worker public final TestWorkItem[] subitems; 366*b7c941bbSAndroid Build Coastguard Worker public final Uri[] requireUrisGranted; 367*b7c941bbSAndroid Build Coastguard Worker public final Uri[] requireUrisNotGranted; 368*b7c941bbSAndroid Build Coastguard Worker TestWorkItem(Intent _intent)369*b7c941bbSAndroid Build Coastguard Worker public TestWorkItem(Intent _intent) { 370*b7c941bbSAndroid Build Coastguard Worker intent = _intent; 371*b7c941bbSAndroid Build Coastguard Worker jobInfo = null; 372*b7c941bbSAndroid Build Coastguard Worker flags = 0; 373*b7c941bbSAndroid Build Coastguard Worker deliveryCount = 1; 374*b7c941bbSAndroid Build Coastguard Worker subitems = null; 375*b7c941bbSAndroid Build Coastguard Worker requireUrisGranted = null; 376*b7c941bbSAndroid Build Coastguard Worker requireUrisNotGranted = null; 377*b7c941bbSAndroid Build Coastguard Worker } 378*b7c941bbSAndroid Build Coastguard Worker TestWorkItem(Intent _intent, int _flags)379*b7c941bbSAndroid Build Coastguard Worker public TestWorkItem(Intent _intent, int _flags) { 380*b7c941bbSAndroid Build Coastguard Worker intent = _intent; 381*b7c941bbSAndroid Build Coastguard Worker jobInfo = null; 382*b7c941bbSAndroid Build Coastguard Worker flags = _flags; 383*b7c941bbSAndroid Build Coastguard Worker deliveryCount = 1; 384*b7c941bbSAndroid Build Coastguard Worker subitems = null; 385*b7c941bbSAndroid Build Coastguard Worker requireUrisGranted = null; 386*b7c941bbSAndroid Build Coastguard Worker requireUrisNotGranted = null; 387*b7c941bbSAndroid Build Coastguard Worker } 388*b7c941bbSAndroid Build Coastguard Worker TestWorkItem(Intent _intent, int _flags, int _deliveryCount)389*b7c941bbSAndroid Build Coastguard Worker public TestWorkItem(Intent _intent, int _flags, int _deliveryCount) { 390*b7c941bbSAndroid Build Coastguard Worker intent = _intent; 391*b7c941bbSAndroid Build Coastguard Worker jobInfo = null; 392*b7c941bbSAndroid Build Coastguard Worker flags = _flags; 393*b7c941bbSAndroid Build Coastguard Worker deliveryCount = _deliveryCount; 394*b7c941bbSAndroid Build Coastguard Worker subitems = null; 395*b7c941bbSAndroid Build Coastguard Worker requireUrisGranted = null; 396*b7c941bbSAndroid Build Coastguard Worker requireUrisNotGranted = null; 397*b7c941bbSAndroid Build Coastguard Worker } 398*b7c941bbSAndroid Build Coastguard Worker TestWorkItem(Intent _intent, JobInfo _jobInfo, TestWorkItem[] _subitems)399*b7c941bbSAndroid Build Coastguard Worker public TestWorkItem(Intent _intent, JobInfo _jobInfo, TestWorkItem[] _subitems) { 400*b7c941bbSAndroid Build Coastguard Worker intent = _intent; 401*b7c941bbSAndroid Build Coastguard Worker jobInfo = _jobInfo; 402*b7c941bbSAndroid Build Coastguard Worker flags = 0; 403*b7c941bbSAndroid Build Coastguard Worker deliveryCount = 1; 404*b7c941bbSAndroid Build Coastguard Worker subitems = _subitems; 405*b7c941bbSAndroid Build Coastguard Worker requireUrisGranted = null; 406*b7c941bbSAndroid Build Coastguard Worker requireUrisNotGranted = null; 407*b7c941bbSAndroid Build Coastguard Worker } 408*b7c941bbSAndroid Build Coastguard Worker TestWorkItem(Intent _intent, Uri[] _requireUrisGranted, Uri[] _requireUrisNotGranted)409*b7c941bbSAndroid Build Coastguard Worker public TestWorkItem(Intent _intent, Uri[] _requireUrisGranted, 410*b7c941bbSAndroid Build Coastguard Worker Uri[] _requireUrisNotGranted) { 411*b7c941bbSAndroid Build Coastguard Worker intent = _intent; 412*b7c941bbSAndroid Build Coastguard Worker jobInfo = null; 413*b7c941bbSAndroid Build Coastguard Worker flags = 0; 414*b7c941bbSAndroid Build Coastguard Worker deliveryCount = 1; 415*b7c941bbSAndroid Build Coastguard Worker subitems = null; 416*b7c941bbSAndroid Build Coastguard Worker requireUrisGranted = _requireUrisGranted; 417*b7c941bbSAndroid Build Coastguard Worker requireUrisNotGranted = _requireUrisNotGranted; 418*b7c941bbSAndroid Build Coastguard Worker } 419*b7c941bbSAndroid Build Coastguard Worker 420*b7c941bbSAndroid Build Coastguard Worker @Override toString()421*b7c941bbSAndroid Build Coastguard Worker public String toString() { 422*b7c941bbSAndroid Build Coastguard Worker return "TestWorkItem { " + intent + " dc=" + deliveryCount + " }"; 423*b7c941bbSAndroid Build Coastguard Worker } 424*b7c941bbSAndroid Build Coastguard Worker } 425*b7c941bbSAndroid Build Coastguard Worker 426*b7c941bbSAndroid Build Coastguard Worker /** 427*b7c941bbSAndroid Build Coastguard Worker * Configures the expected behaviour for each test. This object is shared across consecutive 428*b7c941bbSAndroid Build Coastguard Worker * tests, so to clear state each test is responsible for calling 429*b7c941bbSAndroid Build Coastguard Worker * {@link TestEnvironment#setUp()}. 430*b7c941bbSAndroid Build Coastguard Worker */ 431*b7c941bbSAndroid Build Coastguard Worker public static final class TestEnvironment { 432*b7c941bbSAndroid Build Coastguard Worker 433*b7c941bbSAndroid Build Coastguard Worker private static TestEnvironment kTestEnvironment; 434*b7c941bbSAndroid Build Coastguard Worker //public static final int INVALID_JOB_ID = -1; 435*b7c941bbSAndroid Build Coastguard Worker 436*b7c941bbSAndroid Build Coastguard Worker private CountDownLatch mLatch; 437*b7c941bbSAndroid Build Coastguard Worker private CountDownLatch mWaitingForStopLatch; 438*b7c941bbSAndroid Build Coastguard Worker private CountDownLatch mDoJobLatch; 439*b7c941bbSAndroid Build Coastguard Worker private CountDownLatch mStoppedLatch; 440*b7c941bbSAndroid Build Coastguard Worker private CountDownLatch mDoWorkLatch; 441*b7c941bbSAndroid Build Coastguard Worker private CountDownLatch mNetworkChangeLatch; 442*b7c941bbSAndroid Build Coastguard Worker private TestWorkItem[] mExpectedWork; 443*b7c941bbSAndroid Build Coastguard Worker private boolean mContinueAfterStart; 444*b7c941bbSAndroid Build Coastguard Worker private boolean mRequestReschedule; 445*b7c941bbSAndroid Build Coastguard Worker private JobParameters mExecutedJobParameters; 446*b7c941bbSAndroid Build Coastguard Worker private JobParameters mNetworkChangedJobParameters; 447*b7c941bbSAndroid Build Coastguard Worker private MockJobService mExecutedJobService; 448*b7c941bbSAndroid Build Coastguard Worker private int mExecutedPermCheckRead; 449*b7c941bbSAndroid Build Coastguard Worker private int mExecutedPermCheckWrite; 450*b7c941bbSAndroid Build Coastguard Worker private ArrayList<JobWorkItem> mExecutedReceivedWork; 451*b7c941bbSAndroid Build Coastguard Worker private String mExecutedErrorMessage; 452*b7c941bbSAndroid Build Coastguard Worker private JobParameters mStopJobParameters; 453*b7c941bbSAndroid Build Coastguard Worker private List<Event> mExecutedEvents = new ArrayList<>(); 454*b7c941bbSAndroid Build Coastguard Worker private int mJobStartNotificationId; 455*b7c941bbSAndroid Build Coastguard Worker private Notification mJobStartNotification; 456*b7c941bbSAndroid Build Coastguard Worker private int mJobStartNotificationEndPolicy; 457*b7c941bbSAndroid Build Coastguard Worker getTestEnvironment()458*b7c941bbSAndroid Build Coastguard Worker public static TestEnvironment getTestEnvironment() { 459*b7c941bbSAndroid Build Coastguard Worker if (kTestEnvironment == null) { 460*b7c941bbSAndroid Build Coastguard Worker kTestEnvironment = new TestEnvironment(); 461*b7c941bbSAndroid Build Coastguard Worker } 462*b7c941bbSAndroid Build Coastguard Worker return kTestEnvironment; 463*b7c941bbSAndroid Build Coastguard Worker } 464*b7c941bbSAndroid Build Coastguard Worker getExpectedWork()465*b7c941bbSAndroid Build Coastguard Worker public TestWorkItem[] getExpectedWork() { 466*b7c941bbSAndroid Build Coastguard Worker return mExpectedWork; 467*b7c941bbSAndroid Build Coastguard Worker } 468*b7c941bbSAndroid Build Coastguard Worker getJobStartNotification()469*b7c941bbSAndroid Build Coastguard Worker private Notification getJobStartNotification() { 470*b7c941bbSAndroid Build Coastguard Worker return mJobStartNotification; 471*b7c941bbSAndroid Build Coastguard Worker } 472*b7c941bbSAndroid Build Coastguard Worker getJobStartNotificationEndPolicy()473*b7c941bbSAndroid Build Coastguard Worker private int getJobStartNotificationEndPolicy() { 474*b7c941bbSAndroid Build Coastguard Worker return mJobStartNotificationEndPolicy; 475*b7c941bbSAndroid Build Coastguard Worker } 476*b7c941bbSAndroid Build Coastguard Worker getJobStartNotificationId()477*b7c941bbSAndroid Build Coastguard Worker private int getJobStartNotificationId() { 478*b7c941bbSAndroid Build Coastguard Worker return mJobStartNotificationId; 479*b7c941bbSAndroid Build Coastguard Worker } 480*b7c941bbSAndroid Build Coastguard Worker getLastStartJobParameters()481*b7c941bbSAndroid Build Coastguard Worker public JobParameters getLastStartJobParameters() { 482*b7c941bbSAndroid Build Coastguard Worker return mExecutedJobParameters; 483*b7c941bbSAndroid Build Coastguard Worker } 484*b7c941bbSAndroid Build Coastguard Worker getLastStopJobParameters()485*b7c941bbSAndroid Build Coastguard Worker public JobParameters getLastStopJobParameters() { 486*b7c941bbSAndroid Build Coastguard Worker return mStopJobParameters; 487*b7c941bbSAndroid Build Coastguard Worker } 488*b7c941bbSAndroid Build Coastguard Worker getLastNetworkChangedJobParameters()489*b7c941bbSAndroid Build Coastguard Worker public JobParameters getLastNetworkChangedJobParameters() { 490*b7c941bbSAndroid Build Coastguard Worker return mNetworkChangedJobParameters; 491*b7c941bbSAndroid Build Coastguard Worker } 492*b7c941bbSAndroid Build Coastguard Worker getLastPermCheckRead()493*b7c941bbSAndroid Build Coastguard Worker public int getLastPermCheckRead() { 494*b7c941bbSAndroid Build Coastguard Worker return mExecutedPermCheckRead; 495*b7c941bbSAndroid Build Coastguard Worker } 496*b7c941bbSAndroid Build Coastguard Worker getLastPermCheckWrite()497*b7c941bbSAndroid Build Coastguard Worker public int getLastPermCheckWrite() { 498*b7c941bbSAndroid Build Coastguard Worker return mExecutedPermCheckWrite; 499*b7c941bbSAndroid Build Coastguard Worker } 500*b7c941bbSAndroid Build Coastguard Worker getLastReceivedWork()501*b7c941bbSAndroid Build Coastguard Worker public ArrayList<JobWorkItem> getLastReceivedWork() { 502*b7c941bbSAndroid Build Coastguard Worker return mExecutedReceivedWork; 503*b7c941bbSAndroid Build Coastguard Worker } 504*b7c941bbSAndroid Build Coastguard Worker getLastErrorMessage()505*b7c941bbSAndroid Build Coastguard Worker public String getLastErrorMessage() { 506*b7c941bbSAndroid Build Coastguard Worker return mExecutedErrorMessage; 507*b7c941bbSAndroid Build Coastguard Worker } 508*b7c941bbSAndroid Build Coastguard Worker 509*b7c941bbSAndroid Build Coastguard Worker /** 510*b7c941bbSAndroid Build Coastguard Worker * Block the test thread, waiting on the JobScheduler to execute some previously scheduled 511*b7c941bbSAndroid Build Coastguard Worker * job on this service. 512*b7c941bbSAndroid Build Coastguard Worker */ awaitExecution()513*b7c941bbSAndroid Build Coastguard Worker public boolean awaitExecution() throws InterruptedException { 514*b7c941bbSAndroid Build Coastguard Worker return awaitExecution(DEFAULT_TIMEOUT_MILLIS); 515*b7c941bbSAndroid Build Coastguard Worker } 516*b7c941bbSAndroid Build Coastguard Worker awaitExecution(long timeoutMillis)517*b7c941bbSAndroid Build Coastguard Worker public boolean awaitExecution(long timeoutMillis) throws InterruptedException { 518*b7c941bbSAndroid Build Coastguard Worker final boolean executed = mLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); 519*b7c941bbSAndroid Build Coastguard Worker if (getLastErrorMessage() != null) { 520*b7c941bbSAndroid Build Coastguard Worker Assert.fail(getLastErrorMessage()); 521*b7c941bbSAndroid Build Coastguard Worker } 522*b7c941bbSAndroid Build Coastguard Worker return executed; 523*b7c941bbSAndroid Build Coastguard Worker } 524*b7c941bbSAndroid Build Coastguard Worker 525*b7c941bbSAndroid Build Coastguard Worker /** 526*b7c941bbSAndroid Build Coastguard Worker * Block the test thread, expecting to timeout but still listening to ensure that no jobs 527*b7c941bbSAndroid Build Coastguard Worker * land in the interim. 528*b7c941bbSAndroid Build Coastguard Worker * @return True if the latch timed out waiting on an execution. 529*b7c941bbSAndroid Build Coastguard Worker */ awaitTimeout()530*b7c941bbSAndroid Build Coastguard Worker public boolean awaitTimeout() throws InterruptedException { 531*b7c941bbSAndroid Build Coastguard Worker return awaitTimeout(DEFAULT_TIMEOUT_MILLIS); 532*b7c941bbSAndroid Build Coastguard Worker } 533*b7c941bbSAndroid Build Coastguard Worker awaitTimeout(long timeoutMillis)534*b7c941bbSAndroid Build Coastguard Worker public boolean awaitTimeout(long timeoutMillis) throws InterruptedException { 535*b7c941bbSAndroid Build Coastguard Worker return !mLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); 536*b7c941bbSAndroid Build Coastguard Worker } 537*b7c941bbSAndroid Build Coastguard Worker awaitWaitingForStop()538*b7c941bbSAndroid Build Coastguard Worker public boolean awaitWaitingForStop() throws InterruptedException { 539*b7c941bbSAndroid Build Coastguard Worker return mWaitingForStopLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 540*b7c941bbSAndroid Build Coastguard Worker } 541*b7c941bbSAndroid Build Coastguard Worker awaitDoWork()542*b7c941bbSAndroid Build Coastguard Worker public boolean awaitDoWork() throws InterruptedException { 543*b7c941bbSAndroid Build Coastguard Worker return mDoWorkLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 544*b7c941bbSAndroid Build Coastguard Worker } 545*b7c941bbSAndroid Build Coastguard Worker awaitDoJob()546*b7c941bbSAndroid Build Coastguard Worker public boolean awaitDoJob() throws InterruptedException { 547*b7c941bbSAndroid Build Coastguard Worker if (mDoJobLatch == null) { 548*b7c941bbSAndroid Build Coastguard Worker return true; 549*b7c941bbSAndroid Build Coastguard Worker } 550*b7c941bbSAndroid Build Coastguard Worker return mDoJobLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 551*b7c941bbSAndroid Build Coastguard Worker } 552*b7c941bbSAndroid Build Coastguard Worker awaitNetworkChange()553*b7c941bbSAndroid Build Coastguard Worker public boolean awaitNetworkChange() throws InterruptedException { 554*b7c941bbSAndroid Build Coastguard Worker return mNetworkChangeLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 555*b7c941bbSAndroid Build Coastguard Worker } 556*b7c941bbSAndroid Build Coastguard Worker awaitStopped()557*b7c941bbSAndroid Build Coastguard Worker public boolean awaitStopped() throws InterruptedException { 558*b7c941bbSAndroid Build Coastguard Worker return mStoppedLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); 559*b7c941bbSAndroid Build Coastguard Worker } 560*b7c941bbSAndroid Build Coastguard Worker notifyExecution(MockJobService jobService, JobParameters params, int permCheckRead, int permCheckWrite, ArrayList<JobWorkItem> receivedWork, String errorMsg)561*b7c941bbSAndroid Build Coastguard Worker private void notifyExecution(MockJobService jobService, JobParameters params, 562*b7c941bbSAndroid Build Coastguard Worker int permCheckRead, int permCheckWrite, 563*b7c941bbSAndroid Build Coastguard Worker ArrayList<JobWorkItem> receivedWork, String errorMsg) { 564*b7c941bbSAndroid Build Coastguard Worker mExecutedJobService = jobService; 565*b7c941bbSAndroid Build Coastguard Worker mExecutedJobParameters = params; 566*b7c941bbSAndroid Build Coastguard Worker mExecutedPermCheckRead = permCheckRead; 567*b7c941bbSAndroid Build Coastguard Worker mExecutedPermCheckWrite = permCheckWrite; 568*b7c941bbSAndroid Build Coastguard Worker mExecutedReceivedWork = receivedWork; 569*b7c941bbSAndroid Build Coastguard Worker mExecutedErrorMessage = errorMsg; 570*b7c941bbSAndroid Build Coastguard Worker if (mLatch != null) { 571*b7c941bbSAndroid Build Coastguard Worker mLatch.countDown(); 572*b7c941bbSAndroid Build Coastguard Worker } 573*b7c941bbSAndroid Build Coastguard Worker } 574*b7c941bbSAndroid Build Coastguard Worker notifyNetworkChanged(JobParameters params)575*b7c941bbSAndroid Build Coastguard Worker private void notifyNetworkChanged(JobParameters params) { 576*b7c941bbSAndroid Build Coastguard Worker mNetworkChangedJobParameters = params; 577*b7c941bbSAndroid Build Coastguard Worker if (mNetworkChangeLatch != null) { 578*b7c941bbSAndroid Build Coastguard Worker mNetworkChangeLatch.countDown(); 579*b7c941bbSAndroid Build Coastguard Worker } 580*b7c941bbSAndroid Build Coastguard Worker } 581*b7c941bbSAndroid Build Coastguard Worker notifyWaitingForStop()582*b7c941bbSAndroid Build Coastguard Worker private void notifyWaitingForStop() { 583*b7c941bbSAndroid Build Coastguard Worker mWaitingForStopLatch.countDown(); 584*b7c941bbSAndroid Build Coastguard Worker } 585*b7c941bbSAndroid Build Coastguard Worker notifyStopped(JobParameters params)586*b7c941bbSAndroid Build Coastguard Worker private void notifyStopped(JobParameters params) { 587*b7c941bbSAndroid Build Coastguard Worker mStopJobParameters = params; 588*b7c941bbSAndroid Build Coastguard Worker if (mStoppedLatch != null) { 589*b7c941bbSAndroid Build Coastguard Worker mStoppedLatch.countDown(); 590*b7c941bbSAndroid Build Coastguard Worker } 591*b7c941bbSAndroid Build Coastguard Worker } 592*b7c941bbSAndroid Build Coastguard Worker setEstimatedNetworkBytes(long downloadBytes, long uploadBytes)593*b7c941bbSAndroid Build Coastguard Worker public void setEstimatedNetworkBytes(long downloadBytes, long uploadBytes) { 594*b7c941bbSAndroid Build Coastguard Worker mExecutedJobService.setEstimatedNetworkBytesForTest(downloadBytes, uploadBytes); 595*b7c941bbSAndroid Build Coastguard Worker } 596*b7c941bbSAndroid Build Coastguard Worker setTransferredNetworkBytes(long downloadBytes, long uploadBytes)597*b7c941bbSAndroid Build Coastguard Worker public void setTransferredNetworkBytes(long downloadBytes, long uploadBytes) { 598*b7c941bbSAndroid Build Coastguard Worker mExecutedJobService.setTransferredBytesForTest(downloadBytes, uploadBytes); 599*b7c941bbSAndroid Build Coastguard Worker } 600*b7c941bbSAndroid Build Coastguard Worker setExpectedExecutions(int numExecutions)601*b7c941bbSAndroid Build Coastguard Worker public void setExpectedExecutions(int numExecutions) { 602*b7c941bbSAndroid Build Coastguard Worker // For no executions expected, set count to 1 so we can still block for the timeout. 603*b7c941bbSAndroid Build Coastguard Worker if (numExecutions == 0) { 604*b7c941bbSAndroid Build Coastguard Worker mLatch = new CountDownLatch(1); 605*b7c941bbSAndroid Build Coastguard Worker } else { 606*b7c941bbSAndroid Build Coastguard Worker mLatch = new CountDownLatch(numExecutions); 607*b7c941bbSAndroid Build Coastguard Worker } 608*b7c941bbSAndroid Build Coastguard Worker mWaitingForStopLatch = null; 609*b7c941bbSAndroid Build Coastguard Worker mDoJobLatch = null; 610*b7c941bbSAndroid Build Coastguard Worker mStoppedLatch = null; 611*b7c941bbSAndroid Build Coastguard Worker mDoWorkLatch = null; 612*b7c941bbSAndroid Build Coastguard Worker mNetworkChangeLatch = null; 613*b7c941bbSAndroid Build Coastguard Worker mExpectedWork = null; 614*b7c941bbSAndroid Build Coastguard Worker mContinueAfterStart = false; 615*b7c941bbSAndroid Build Coastguard Worker mRequestReschedule = false; 616*b7c941bbSAndroid Build Coastguard Worker mExecutedEvents.clear(); 617*b7c941bbSAndroid Build Coastguard Worker mJobStartNotification = null; 618*b7c941bbSAndroid Build Coastguard Worker } 619*b7c941bbSAndroid Build Coastguard Worker setExpectedWaitForStop()620*b7c941bbSAndroid Build Coastguard Worker public void setExpectedWaitForStop() { 621*b7c941bbSAndroid Build Coastguard Worker mWaitingForStopLatch = new CountDownLatch(1); 622*b7c941bbSAndroid Build Coastguard Worker } 623*b7c941bbSAndroid Build Coastguard Worker setExpectedWork(TestWorkItem[] work)624*b7c941bbSAndroid Build Coastguard Worker public void setExpectedWork(TestWorkItem[] work) { 625*b7c941bbSAndroid Build Coastguard Worker mExpectedWork = work; 626*b7c941bbSAndroid Build Coastguard Worker mDoWorkLatch = new CountDownLatch(1); 627*b7c941bbSAndroid Build Coastguard Worker } 628*b7c941bbSAndroid Build Coastguard Worker setExpectedStopped()629*b7c941bbSAndroid Build Coastguard Worker public void setExpectedStopped() { 630*b7c941bbSAndroid Build Coastguard Worker mStoppedLatch = new CountDownLatch(1); 631*b7c941bbSAndroid Build Coastguard Worker } 632*b7c941bbSAndroid Build Coastguard Worker setExpectedNetworkChange()633*b7c941bbSAndroid Build Coastguard Worker public void setExpectedNetworkChange() { 634*b7c941bbSAndroid Build Coastguard Worker mNetworkChangeLatch = new CountDownLatch(1); 635*b7c941bbSAndroid Build Coastguard Worker } 636*b7c941bbSAndroid Build Coastguard Worker setNotificationAtStart(int notificationId, @NonNull Notification notification, @JobEndNotificationPolicy int jobEndNotificationPolicy)637*b7c941bbSAndroid Build Coastguard Worker public void setNotificationAtStart(int notificationId, 638*b7c941bbSAndroid Build Coastguard Worker @NonNull Notification notification, 639*b7c941bbSAndroid Build Coastguard Worker @JobEndNotificationPolicy int jobEndNotificationPolicy) { 640*b7c941bbSAndroid Build Coastguard Worker mJobStartNotificationId = notificationId; 641*b7c941bbSAndroid Build Coastguard Worker mJobStartNotification = notification; 642*b7c941bbSAndroid Build Coastguard Worker mJobStartNotificationEndPolicy = jobEndNotificationPolicy; 643*b7c941bbSAndroid Build Coastguard Worker } 644*b7c941bbSAndroid Build Coastguard Worker readyToWork()645*b7c941bbSAndroid Build Coastguard Worker public void readyToWork() { 646*b7c941bbSAndroid Build Coastguard Worker mDoWorkLatch.countDown(); 647*b7c941bbSAndroid Build Coastguard Worker } 648*b7c941bbSAndroid Build Coastguard Worker setExpectedWaitForRun()649*b7c941bbSAndroid Build Coastguard Worker public void setExpectedWaitForRun() { 650*b7c941bbSAndroid Build Coastguard Worker mDoJobLatch = new CountDownLatch(1); 651*b7c941bbSAndroid Build Coastguard Worker } 652*b7c941bbSAndroid Build Coastguard Worker readyToRun()653*b7c941bbSAndroid Build Coastguard Worker public void readyToRun() { 654*b7c941bbSAndroid Build Coastguard Worker mDoJobLatch.countDown(); 655*b7c941bbSAndroid Build Coastguard Worker } 656*b7c941bbSAndroid Build Coastguard Worker setContinueAfterStart()657*b7c941bbSAndroid Build Coastguard Worker public void setContinueAfterStart() { 658*b7c941bbSAndroid Build Coastguard Worker mContinueAfterStart = true; 659*b7c941bbSAndroid Build Coastguard Worker } 660*b7c941bbSAndroid Build Coastguard Worker handleContinueAfterStart()661*b7c941bbSAndroid Build Coastguard Worker public boolean handleContinueAfterStart() { 662*b7c941bbSAndroid Build Coastguard Worker boolean res = mContinueAfterStart; 663*b7c941bbSAndroid Build Coastguard Worker mContinueAfterStart = false; 664*b7c941bbSAndroid Build Coastguard Worker return res; 665*b7c941bbSAndroid Build Coastguard Worker } 666*b7c941bbSAndroid Build Coastguard Worker setRequestReschedule()667*b7c941bbSAndroid Build Coastguard Worker public void setRequestReschedule() { 668*b7c941bbSAndroid Build Coastguard Worker mRequestReschedule = true; 669*b7c941bbSAndroid Build Coastguard Worker } 670*b7c941bbSAndroid Build Coastguard Worker requestReschedule()671*b7c941bbSAndroid Build Coastguard Worker boolean requestReschedule() { 672*b7c941bbSAndroid Build Coastguard Worker return mRequestReschedule; 673*b7c941bbSAndroid Build Coastguard Worker } 674*b7c941bbSAndroid Build Coastguard Worker 675*b7c941bbSAndroid Build Coastguard Worker /** Called in each testCase#setup */ setUp()676*b7c941bbSAndroid Build Coastguard Worker public void setUp() { 677*b7c941bbSAndroid Build Coastguard Worker mLatch = null; 678*b7c941bbSAndroid Build Coastguard Worker mExecutedJobParameters = null; 679*b7c941bbSAndroid Build Coastguard Worker mExecutedJobService = null; 680*b7c941bbSAndroid Build Coastguard Worker mStopJobParameters = null; 681*b7c941bbSAndroid Build Coastguard Worker } 682*b7c941bbSAndroid Build Coastguard Worker addEvent(Event event)683*b7c941bbSAndroid Build Coastguard Worker void addEvent(Event event) { 684*b7c941bbSAndroid Build Coastguard Worker mExecutedEvents.add(event); 685*b7c941bbSAndroid Build Coastguard Worker } 686*b7c941bbSAndroid Build Coastguard Worker getExecutedEvents()687*b7c941bbSAndroid Build Coastguard Worker public List<Event> getExecutedEvents() { 688*b7c941bbSAndroid Build Coastguard Worker return mExecutedEvents; 689*b7c941bbSAndroid Build Coastguard Worker } 690*b7c941bbSAndroid Build Coastguard Worker 691*b7c941bbSAndroid Build Coastguard Worker public static class Event { 692*b7c941bbSAndroid Build Coastguard Worker public static final int EVENT_START_JOB = 0; 693*b7c941bbSAndroid Build Coastguard Worker 694*b7c941bbSAndroid Build Coastguard Worker public int event; 695*b7c941bbSAndroid Build Coastguard Worker public int jobId; 696*b7c941bbSAndroid Build Coastguard Worker Event(int event, int jobId)697*b7c941bbSAndroid Build Coastguard Worker public Event(int event, int jobId) { 698*b7c941bbSAndroid Build Coastguard Worker this.event = event; 699*b7c941bbSAndroid Build Coastguard Worker this.jobId = jobId; 700*b7c941bbSAndroid Build Coastguard Worker } 701*b7c941bbSAndroid Build Coastguard Worker 702*b7c941bbSAndroid Build Coastguard Worker @Override equals(Object other)703*b7c941bbSAndroid Build Coastguard Worker public boolean equals(Object other) { 704*b7c941bbSAndroid Build Coastguard Worker if (this == other) { 705*b7c941bbSAndroid Build Coastguard Worker return true; 706*b7c941bbSAndroid Build Coastguard Worker } 707*b7c941bbSAndroid Build Coastguard Worker if (other instanceof Event) { 708*b7c941bbSAndroid Build Coastguard Worker Event otherEvent = (Event) other; 709*b7c941bbSAndroid Build Coastguard Worker return otherEvent.event == event && otherEvent.jobId == jobId; 710*b7c941bbSAndroid Build Coastguard Worker } 711*b7c941bbSAndroid Build Coastguard Worker return false; 712*b7c941bbSAndroid Build Coastguard Worker } 713*b7c941bbSAndroid Build Coastguard Worker 714*b7c941bbSAndroid Build Coastguard Worker @Override hashCode()715*b7c941bbSAndroid Build Coastguard Worker public int hashCode() { 716*b7c941bbSAndroid Build Coastguard Worker return event + 31 * jobId; 717*b7c941bbSAndroid Build Coastguard Worker } 718*b7c941bbSAndroid Build Coastguard Worker 719*b7c941bbSAndroid Build Coastguard Worker @Override toString()720*b7c941bbSAndroid Build Coastguard Worker public String toString() { 721*b7c941bbSAndroid Build Coastguard Worker return "Event{" + event + ", " + jobId + "}"; 722*b7c941bbSAndroid Build Coastguard Worker } 723*b7c941bbSAndroid Build Coastguard Worker } 724*b7c941bbSAndroid Build Coastguard Worker } 725*b7c941bbSAndroid Build Coastguard Worker } 726