Home | History | Annotate | Download | only in cts
      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 android.jobscheduler.cts;
     17 
     18 import static android.jobscheduler.cts.jobtestapp.TestJobService.ACTION_JOB_STARTED;
     19 import static android.jobscheduler.cts.jobtestapp.TestJobService.ACTION_JOB_STOPPED;
     20 import static android.jobscheduler.cts.jobtestapp.TestJobService.JOB_PARAMS_EXTRA_KEY;
     21 
     22 import android.app.job.JobParameters;
     23 import android.content.BroadcastReceiver;
     24 import android.content.ComponentName;
     25 import android.content.Context;
     26 import android.content.Intent;
     27 import android.content.IntentFilter;
     28 import android.jobscheduler.cts.jobtestapp.TestActivity;
     29 import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
     30 import android.os.SystemClock;
     31 import android.util.Log;
     32 
     33 /**
     34  * Common functions to interact with the test app.
     35  */
     36 class TestAppInterface {
     37     private static final String TAG = TestAppInterface.class.getSimpleName();
     38 
     39     static final String TEST_APP_PACKAGE = "android.jobscheduler.cts.jobtestapp";
     40     private static final String TEST_APP_ACTIVITY = TEST_APP_PACKAGE + ".TestActivity";
     41     static final String TEST_APP_RECEIVER = TEST_APP_PACKAGE + ".TestJobSchedulerReceiver";
     42 
     43     private final Context mContext;
     44     private final int mJobId;
     45 
     46     /* accesses must be synchronized on itself */
     47     private final TestJobStatus mTestJobStatus = new TestJobStatus();
     48 
     49     TestAppInterface(Context ctx, int jobId) {
     50         mContext = ctx;
     51         mJobId = jobId;
     52 
     53         final IntentFilter intentFilter = new IntentFilter();
     54         intentFilter.addAction(ACTION_JOB_STARTED);
     55         intentFilter.addAction(ACTION_JOB_STOPPED);
     56         mContext.registerReceiver(mReceiver, intentFilter);
     57     }
     58 
     59     void cleanup() {
     60         final Intent cancelJobsIntent = new Intent(TestJobSchedulerReceiver.ACTION_CANCEL_JOBS);
     61         cancelJobsIntent.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER));
     62         cancelJobsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     63         mContext.sendBroadcast(cancelJobsIntent);
     64         mContext.sendBroadcast(new Intent(TestActivity.ACTION_FINISH_ACTIVITY));
     65         mContext.unregisterReceiver(mReceiver);
     66         mTestJobStatus.reset();
     67     }
     68 
     69     void scheduleJob(boolean allowWhileIdle, boolean needNetwork) {
     70         final Intent scheduleJobIntent = new Intent(TestJobSchedulerReceiver.ACTION_SCHEDULE_JOB);
     71         scheduleJobIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
     72         scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_JOB_ID_KEY, mJobId);
     73         scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_ALLOW_IN_IDLE, allowWhileIdle);
     74         scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_REQUIRE_NETWORK_ANY, needNetwork);
     75         scheduleJobIntent.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER));
     76         mContext.sendBroadcast(scheduleJobIntent);
     77     }
     78 
     79     void startAndKeepTestActivity() {
     80         final Intent testActivity = new Intent();
     81         testActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     82         testActivity.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_ACTIVITY));
     83         mContext.startActivity(testActivity);
     84     }
     85 
     86     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
     87         @Override
     88         public void onReceive(Context context, Intent intent) {
     89             Log.d(TAG, "Received action " + intent.getAction());
     90             switch (intent.getAction()) {
     91                 case ACTION_JOB_STARTED:
     92                 case ACTION_JOB_STOPPED:
     93                     final JobParameters params = intent.getParcelableExtra(JOB_PARAMS_EXTRA_KEY);
     94                     Log.d(TAG, "JobId: " + params.getJobId());
     95                     synchronized (mTestJobStatus) {
     96                         mTestJobStatus.running = ACTION_JOB_STARTED.equals(intent.getAction());
     97                         mTestJobStatus.jobId = params.getJobId();
     98                     }
     99                     break;
    100             }
    101         }
    102     };
    103 
    104     boolean awaitJobStart(long maxWait) throws Exception {
    105         return waitUntilTrue(maxWait, () -> {
    106             synchronized (mTestJobStatus) {
    107                 return (mTestJobStatus.jobId == mJobId) && mTestJobStatus.running;
    108             }
    109         });
    110     }
    111 
    112     boolean awaitJobStop(long maxWait) throws Exception {
    113         return waitUntilTrue(maxWait, () -> {
    114             synchronized (mTestJobStatus) {
    115                 return (mTestJobStatus.jobId == mJobId) && !mTestJobStatus.running;
    116             }
    117         });
    118     }
    119 
    120     private boolean waitUntilTrue(long maxWait, Condition condition) throws Exception {
    121         final long deadLine = SystemClock.uptimeMillis() + maxWait;
    122         do {
    123             Thread.sleep(500);
    124         } while (!condition.isTrue() && SystemClock.uptimeMillis() < deadLine);
    125         return condition.isTrue();
    126     }
    127 
    128     private static final class TestJobStatus {
    129         int jobId;
    130         boolean running;
    131 
    132         private void reset() {
    133             running = false;
    134         }
    135     }
    136 
    137     private interface Condition {
    138         boolean isTrue() throws Exception;
    139     }
    140 }
    141