| package com.android.cts.verifier.jobscheduler; |
| |
| import android.annotation.TargetApi; |
| import android.app.job.JobInfo; |
| import android.content.BroadcastReceiver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.net.ConnectivityManager; |
| import android.net.NetworkInfo; |
| import android.os.AsyncTask; |
| import android.os.Bundle; |
| import android.util.Log; |
| import android.widget.Button; |
| import android.widget.ImageView; |
| |
| import com.android.cts.verifier.R; |
| |
| /** |
| * The majority of the connectivity constraints are done in the device-side test app |
| * android.jobscheduler.cts.deviceside. However a manual tester is required to completely turn off |
| * connectivity on the device in order to verify that jobs with connectivity constraints will not |
| * run in the absence of an internet connection. |
| */ |
| @TargetApi(21) |
| public class ConnectivityConstraintTestActivity extends ConstraintTestActivity { |
| private static final String TAG = "ConnectivityConstraintTestActivity"; |
| private static final int ANY_CONNECTIVITY_JOB_ID = |
| ConnectivityConstraintTestActivity.class.hashCode() + 0; |
| private static final int UNMETERED_CONNECTIVITY_JOB_ID = |
| ConnectivityConstraintTestActivity.class.hashCode() + 1; |
| private static final int NO_CONNECTIVITY_JOB_ID = |
| ConnectivityConstraintTestActivity.class.hashCode() + 2; |
| |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| // Set up the UI. |
| setContentView(R.layout.js_connectivity); |
| setPassFailButtonClickListeners(); |
| setInfoResources(R.string.js_connectivity_test, R.string.js_connectivity_instructions, -1); |
| mStartButton = (Button) findViewById(R.id.js_connectivity_start_test_button); |
| |
| // Disable test start if there is data connectivity. |
| mStartButton.setEnabled(isDataUnavailable()); |
| // Register receiver to listen for connectivity changes. |
| IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); |
| registerReceiver(mConnectivityChangedReceiver, intentFilter); |
| |
| } |
| |
| @Override |
| protected void onDestroy() { |
| super.onDestroy(); |
| unregisterReceiver(mConnectivityChangedReceiver); |
| } |
| |
| @Override |
| protected void startTestImpl() { |
| new TestConnectivityConstraint().execute(); |
| } |
| |
| /** Ensure that there's no connectivity before we allow the test to start. */ |
| BroadcastReceiver mConnectivityChangedReceiver = new BroadcastReceiver() { |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| Log.d(TAG, "received: " + intent); |
| String extras = ""; |
| for (String name : intent.getExtras().keySet()) { |
| extras += " |" + name + " " + intent.getExtras().get(name) + "|"; |
| |
| } |
| Log.d(TAG, "extras: " + extras); |
| if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { |
| // Only enable the test when we know there is no connectivity. |
| mStartButton.setEnabled(isDataUnavailable()); |
| } |
| } |
| }; |
| |
| private void testUnmeteredConstraintFails_noConnectivity() { |
| testConnectivityConstraintFailsImpl( |
| JobInfo.NETWORK_TYPE_UNMETERED, UNMETERED_CONNECTIVITY_JOB_ID); |
| } |
| |
| private void testAnyConnectivityConstraintFails_noConnectivity() { |
| testConnectivityConstraintFailsImpl(JobInfo.NETWORK_TYPE_ANY, ANY_CONNECTIVITY_JOB_ID); |
| } |
| |
| private void testNoConnectivityConstraintExecutes_noConnectivity() { |
| JobInfo testJob = new JobInfo.Builder(NO_CONNECTIVITY_JOB_ID, mMockComponent) |
| .setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE) |
| .setOverrideDeadline(100000L) // Will not expire. |
| .build(); |
| |
| mTestEnvironment.setUp(); |
| mTestEnvironment.setExpectedExecutions(1); |
| |
| mJobScheduler.schedule(testJob); |
| |
| // Send intent to kick off ready jobs that the JobScheduler might be lazily holding on to. |
| sendBroadcastAndBlockForResult(EXPEDITE_STABLE_CHARGING); |
| |
| boolean testPassed; |
| try { |
| testPassed = mTestEnvironment.awaitExecution(); |
| } catch (InterruptedException e) { |
| testPassed = false; |
| } |
| runOnUiThread( |
| new ConnectivityConstraintTestResultRunner(NO_CONNECTIVITY_JOB_ID, testPassed)); |
| } |
| |
| private void testConnectivityConstraintFailsImpl(int requiredNetworkType, int jobId) { |
| // Use arguments provided to construct job with required connectivity constraint. |
| JobInfo testJob = new JobInfo.Builder(jobId, mMockComponent) |
| .setRequiredNetworkType(requiredNetworkType) |
| .build(); |
| |
| mTestEnvironment.setUp(); |
| mTestEnvironment.setExpectedExecutions(0); |
| |
| mJobScheduler.schedule(testJob); |
| |
| // Send intent to kick off ready jobs that the JobScheduler might be lazily holding on to. |
| sendBroadcastAndBlockForResult(EXPEDITE_STABLE_CHARGING); |
| |
| boolean testPassed; |
| try { |
| testPassed = mTestEnvironment.awaitTimeout(); |
| } catch (InterruptedException e) { |
| testPassed = false; |
| } |
| runOnUiThread( |
| new ConnectivityConstraintTestResultRunner(jobId, testPassed)); |
| } |
| |
| /** Query the active network connection and return if there is no data connection. */ |
| private boolean isDataUnavailable() { |
| final ConnectivityManager cm = |
| (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); |
| final NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); |
| |
| return (activeNetwork == null) || |
| !activeNetwork.isConnectedOrConnecting(); |
| } |
| |
| private class TestConnectivityConstraint extends AsyncTask<Void, Void, Void> { |
| |
| @Override |
| protected Void doInBackground(Void... voids) { |
| testUnmeteredConstraintFails_noConnectivity(); |
| testAnyConnectivityConstraintFails_noConnectivity(); |
| testNoConnectivityConstraintExecutes_noConnectivity(); |
| |
| notifyTestCompleted(); |
| return null; |
| } |
| } |
| |
| private class ConnectivityConstraintTestResultRunner extends TestResultRunner { |
| ConnectivityConstraintTestResultRunner(int jobId, boolean testPassed) { |
| super(jobId, testPassed); |
| } |
| |
| @Override |
| public void run() { |
| ImageView view; |
| if (mJobId == ANY_CONNECTIVITY_JOB_ID) { |
| view = (ImageView) findViewById(R.id.connectivity_off_test_any_connectivity_image); |
| } else if (mJobId == UNMETERED_CONNECTIVITY_JOB_ID) { |
| view = (ImageView) findViewById(R.id.connectivity_off_test_unmetered_image); |
| } else if (mJobId == NO_CONNECTIVITY_JOB_ID) { |
| view = (ImageView) findViewById(R.id.connectivity_off_test_no_connectivity_image); |
| } else { |
| noteInvalidTest(); |
| return; |
| } |
| view.setImageResource(mTestPassed ? R.drawable.fs_good : R.drawable.fs_error); |
| } |
| } |
| |
| } |