1 package com.android.cts.verifier.jobscheduler; 2 3 import android.annotation.TargetApi; 4 import android.app.job.JobScheduler; 5 import android.content.BroadcastReceiver; 6 import android.content.ComponentName; 7 import android.content.Context; 8 import android.content.Intent; 9 import android.os.Bundle; 10 import android.view.View; 11 import android.widget.Button; 12 import android.widget.Toast; 13 14 import com.android.cts.verifier.PassFailButtons; 15 16 import java.util.concurrent.CountDownLatch; 17 import java.util.concurrent.TimeUnit; 18 19 @TargetApi(21) 20 public abstract class ConstraintTestActivity extends PassFailButtons.Activity { 21 22 protected ComponentName mMockComponent; 23 24 protected MockJobService.TestEnvironment mTestEnvironment; 25 protected JobScheduler mJobScheduler; 26 27 /** Avoid cases where user might press "start test" more than once. */ 28 private boolean mTestInProgress; 29 /** 30 * Starts the test - set up by subclass, which also controls the logic for how/when the test 31 * can be started. 32 */ 33 protected Button mStartButton; 34 35 @Override 36 protected void onCreate(Bundle savedInstanceState) { 37 super.onCreate(savedInstanceState); 38 39 mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); 40 mMockComponent = new ComponentName(this, MockJobService.class); 41 mTestEnvironment = MockJobService.TestEnvironment.getTestEnvironment(); 42 } 43 44 /** OnClickListener for the "Start Test" ({@link #mStartButton}) button */ 45 public final void startTest(View v) { 46 if (mTestInProgress) { 47 Toast toast = 48 Toast.makeText( 49 ConstraintTestActivity.this, 50 "Test already in progress", 51 Toast.LENGTH_SHORT); 52 toast.show(); 53 return; 54 } else { 55 mTestInProgress = true; 56 startTestImpl(); 57 } 58 } 59 60 /** Called by subclasses to allow the user to rerun the test if necessary. */ 61 protected final void notifyTestCompleted() { 62 mTestInProgress = false; 63 } 64 65 /** Implemented by subclasses to determine logic for running the test. */ 66 protected abstract void startTestImpl(); 67 68 /** 69 * Broadcast the provided intent, and register a receiver to notify us after the broadcast has 70 * been processed. 71 * This function will block until the broadcast comes back, and <bold>cannot</bold> be called 72 * on the main thread. 73 * @return True if we received the callback, false if not. 74 */ 75 protected boolean sendBroadcastAndBlockForResult(Intent intent) { 76 final CountDownLatch latch = new CountDownLatch(1); 77 sendOrderedBroadcast(intent, null, new BroadcastReceiver() { 78 @Override 79 public void onReceive(Context context, Intent intent) { 80 latch.countDown(); 81 } 82 }, null, -1, null, null); 83 try { 84 return latch.await(5, TimeUnit.SECONDS); 85 } catch (InterruptedException e) { 86 return false; 87 } 88 } 89 90 /** Extended by test activities to report results of a test. */ 91 protected abstract class TestResultRunner implements Runnable { 92 final int mJobId; 93 final boolean mTestPassed; 94 95 TestResultRunner(int jobId, boolean testPassed) { 96 mJobId = jobId; 97 mTestPassed = testPassed; 98 } 99 protected void noteInvalidTest() { 100 final Toast toast = 101 Toast.makeText( 102 ConstraintTestActivity.this, 103 "Invalid result returned from test thread: job=" + mJobId + ", res=" 104 + mTestPassed, 105 Toast.LENGTH_SHORT); 106 toast.show(); 107 } 108 } 109 } 110