blob: 4b70b894640b2550660a7bf6f3eb60fd626f6092 [file] [log] [blame]
package com.android.cts.verifier.jobscheduler;
import android.annotation.TargetApi;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.BatteryManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.view.View;
import com.android.cts.verifier.R;
import com.android.cts.verifier.TimerProgressBar;
/**
* This activity runs the following tests:
* - Ask the tester to ensure the phone is plugged in, and verify that jobs with charging
* constraints are run.
* - Ask the tester to unplug the phone, and verify that jobs with charging constraints will
* not run.
*/
@TargetApi(21)
public class ChargingConstraintTestActivity extends ConstraintTestActivity {
private static final int ON_CHARGING_JOB_ID =
ChargingConstraintTestActivity.class.hashCode() + 0;
private static final int OFF_CHARGING_JOB_ID =
ChargingConstraintTestActivity.class.hashCode() + 1;
// Time in milliseconds to wait after power is connected for the phone
// to get into charging mode.
private static final long WAIT_FOR_CHARGING_DURATION = 3 * 60 * 1000;
private static final int STATE_NOT_RUNNING = 0;
private static final int STATE_WAITING_TO_START_ON_CHARGING_TEST = 1;
private static final int STATE_ON_CHARGING_TEST_PASSED = 2;
private int mTestState;
TimerProgressBar mWaitingForChargingProgressBar;
TextView mWaitingForChargingTextView;
TextView mProblemWithChargerTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up the UI.
setContentView(R.layout.js_charging);
setPassFailButtonClickListeners();
setInfoResources(R.string.js_charging_test, R.string.js_charging_instructions, -1);
mStartButton = (Button) findViewById(R.id.js_charging_start_test_button);
mWaitingForChargingProgressBar = (TimerProgressBar) findViewById(
R.id.js_waiting_for_charging_progress_bar);
mWaitingForChargingTextView = (TextView) findViewById(
R.id.js_waiting_for_charging_text_view);
mProblemWithChargerTextView = (TextView) findViewById(
R.id.js_problem_with_charger_text_view);
if (isDevicePluggedIn()){
mStartButton.setEnabled(true);
}
hideWaitingForStableChargingViews();
mTestState = STATE_NOT_RUNNING;
mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
// Register receiver for connected/disconnected power events.
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
intentFilter.addAction(BatteryManager.ACTION_CHARGING);
intentFilter.addAction(BatteryManager.ACTION_DISCHARGING);
registerReceiver(mChargingChangedReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mChargingChangedReceiver);
}
private boolean isDevicePluggedIn() {
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
// 0 indicates device is on battery power
return status != 0;
}
@Override
public void startTestImpl() {
BatteryManager bm = (BatteryManager) getSystemService(BATTERY_SERVICE);
if (bm.isCharging()) {
new TestDevicePluggedInConstraint().execute();
} else if (isDevicePluggedIn()) {
mTestState = STATE_WAITING_TO_START_ON_CHARGING_TEST;
showWaitingForStableChargingViews();
}
}
private BroadcastReceiver mChargingChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (BatteryManager.ACTION_CHARGING.equals(intent.getAction())) {
if (mTestState == STATE_WAITING_TO_START_ON_CHARGING_TEST) {
mWaitingForChargingProgressBar.forceComplete();
hideWaitingForStableChargingViews();
new TestDevicePluggedInConstraint().execute();
}
} else if (BatteryManager.ACTION_DISCHARGING.equals(intent.getAction())) {
if (mTestState == STATE_ON_CHARGING_TEST_PASSED) {
new TestDeviceUnpluggedConstraint().execute();
}
} else if (Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())) {
if (mTestState == STATE_WAITING_TO_START_ON_CHARGING_TEST) {
showWaitingForStableChargingViews();
} else if (mTestState == STATE_NOT_RUNNING) {
mStartButton.setEnabled(true);
}
mStartButton.setEnabled(true);
} else if (Intent.ACTION_POWER_DISCONNECTED.equals(intent.getAction())) {
hideWaitingForStableChargingViews();
}
}
};
/** Simple state boolean we use to determine whether to continue with the second test. */
private boolean mDeviceUnpluggedTestPassed = false;
/**
* Test blocks and can't be run on the main thread.
*/
private void testChargingConstraintFails_notCharging() {
mTestEnvironment.setUp();
mTestEnvironment.setExpectedExecutions(0);
JobInfo runOnCharge = new JobInfo.Builder(OFF_CHARGING_JOB_ID, mMockComponent)
.setRequiresCharging(true)
.build();
mJobScheduler.schedule(runOnCharge);
boolean testPassed;
try {
testPassed = mTestEnvironment.awaitTimeout();
} catch (InterruptedException e) {
testPassed = false;
}
runOnUiThread(new ChargingConstraintTestResultRunner(OFF_CHARGING_JOB_ID, testPassed));
}
/**
* Test blocks and can't be run on the main thread.
*/
private void testChargingConstraintExecutes_onCharging() {
mTestEnvironment.setUp();
JobInfo delayConstraintAndUnexpiredDeadline =
new JobInfo.Builder(ON_CHARGING_JOB_ID, mMockComponent)
.setRequiresCharging(true)
.build();
mTestEnvironment.setExpectedExecutions(1);
mJobScheduler.schedule(delayConstraintAndUnexpiredDeadline);
boolean testPassed;
try {
testPassed = mTestEnvironment.awaitExecution();
} catch (InterruptedException e) {
testPassed = false;
}
mTestState = testPassed ? STATE_ON_CHARGING_TEST_PASSED : STATE_NOT_RUNNING;
runOnUiThread(new ChargingConstraintTestResultRunner(ON_CHARGING_JOB_ID, testPassed));
}
/** Run test for when the <bold>device is not connected to power.</bold>. */
private class TestDeviceUnpluggedConstraint extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
testChargingConstraintFails_notCharging();
notifyTestCompleted();
return null;
}
@Override
protected void onPostExecute(Void res) {
mTestState = STATE_NOT_RUNNING;
mStartButton.setEnabled(true);
}
}
/** Run test for when the <bold>device is connected to power.</bold> */
private class TestDevicePluggedInConstraint extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
testChargingConstraintExecutes_onCharging();
return null;
}
}
private class ChargingConstraintTestResultRunner extends TestResultRunner {
ChargingConstraintTestResultRunner(int jobId, boolean testPassed) {
super(jobId, testPassed);
}
@Override
public void run() {
ImageView view;
if (mJobId == OFF_CHARGING_JOB_ID) {
view = (ImageView) findViewById(R.id.charging_off_test_image);
} else if (mJobId == ON_CHARGING_JOB_ID) {
view = (ImageView) findViewById(R.id.charging_on_test_image);
} else {
noteInvalidTest();
return;
}
view.setImageResource(mTestPassed ? R.drawable.fs_good : R.drawable.fs_error);
}
}
private void showWaitingForStableChargingViews() {
mWaitingForChargingProgressBar.start(WAIT_FOR_CHARGING_DURATION, 1000,
new TimerProgressBar.TimerExpiredCallback(){
@Override
public void onTimerExpired() {
mProblemWithChargerTextView.setVisibility(View.VISIBLE);
}
}
);
mWaitingForChargingProgressBar.setVisibility(View.VISIBLE);
mWaitingForChargingTextView.setVisibility(View.VISIBLE);
mProblemWithChargerTextView.setVisibility(View.GONE);
}
private void hideWaitingForStableChargingViews() {
mWaitingForChargingProgressBar.forceComplete();
mWaitingForChargingProgressBar.setVisibility(View.GONE);
mWaitingForChargingTextView.setVisibility(View.GONE);
mProblemWithChargerTextView.setVisibility(View.GONE);
}
}