| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| package com.android.cts.verifier.sensors; |
| |
| import android.app.AlarmManager; |
| import android.app.PendingIntent; |
| import android.content.BroadcastReceiver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.hardware.Sensor; |
| import android.hardware.SensorEvent; |
| import android.hardware.SensorEventListener; |
| import android.hardware.SensorManager; |
| import android.hardware.cts.helpers.SensorNotSupportedException; |
| import android.hardware.cts.helpers.SuspendStateMonitor; |
| import android.os.PowerManager; |
| import android.os.SystemClock; |
| import androidx.localbroadcastmanager.content.LocalBroadcastManager; |
| import android.util.Log; |
| |
| import com.android.cts.verifier.R; |
| import com.android.cts.verifier.sensors.helpers.SensorTestScreenManipulator; |
| import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity; |
| |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| |
| import junit.framework.Assert; |
| import static junit.framework.Assert.fail; |
| |
| |
| /** |
| * Manual test for testing the low-latency offbody detect sensor. This test consists of 3 |
| * sub-tests designed to verify the sensor event data, verify event trigger response times |
| * are within spec for the sensor type, and to verify that the sensor can wake the device. |
| */ |
| public class OffBodySensorTestActivity |
| extends SensorCtsVerifierTestActivity { |
| private static final String TAG="OffbodySensorTest"; |
| private static String ACTION_ALARM = "OffBodySensorTestActivity.ACTION_ALARM"; |
| private static final int MAX_OFF_BODY_EVENT_LATENCY_MS = 1000; |
| private static final int MAX_ON_BODY_EVENT_LATENCY_MS = 5000; |
| private static final int COUNTDOWN_INTERVAL_MS = 1000; |
| private static final int LLOB_EVENT_MAX_DELAY_SEC = 20; |
| private static final long MAX_ALLOWED_DELAY_MS = TimeUnit.SECONDS.toMillis(1); |
| private static final long RESULT_REPORT_SHOW_TIME_MS = TimeUnit.SECONDS.toMillis(5); |
| private static final int OFFBODY_EVENT_VALUES_LENGTH = 1; |
| private static final int COUNTDOWN_NUM_INTERVALS = 3; |
| |
| private static final float OFF_BODY_EVENT_VALUE = 0; |
| private static final float ON_BODY_EVENT_VALUE = 1; |
| private static final float BAD_VALUE_SEEN_INIT = 0; |
| private static float mBadValueSeen = BAD_VALUE_SEEN_INIT; |
| |
| private enum State { |
| OFF_BODY, ON_BODY, UNKNOWN |
| } |
| |
| // time to wait for offbody event after the device has gone into suspend. Even after |
| // 45 secs if LLOB sensor does not trigger, the test will fail. |
| private static final long ALARM_WAKE_UP_AP_DELAY_MS = TimeUnit.SECONDS.toMillis(45); |
| |
| // acceptable time difference between event time and AP wake up time. |
| private static final long MAX_ACCEPTABLE_DELAY_EVENT_AP_WAKE_UP_NS = |
| TimeUnit.MILLISECONDS.toNanos(1200); |
| |
| private static final int NANOSECONDS_PER_MILLISECOND = 1000000; |
| private AlarmManager mAlarmManager; |
| private SensorManager mSensorManager; |
| private Sensor mOffBodySensor; |
| private boolean mOffBodySensorRegistered; |
| private long mTestStartTimestampMs; |
| private State mPreviousSensorState; |
| private PendingIntent mPendingIntent; |
| private PowerManager.WakeLock mDeviceSuspendLock; |
| private SensorEventVerifier mVerifier; |
| private SensorTestScreenManipulator mScreenManipulator; |
| |
| public class SensorEventRegistry { |
| public final SensorEvent event; |
| public final long receiveTimestampNanos; |
| |
| public SensorEventRegistry(SensorEvent event, long realtimeTimestampNanos) { |
| this.event = event; |
| this.receiveTimestampNanos = realtimeTimestampNanos; |
| } |
| } |
| |
| private class SensorEventVerifier implements SensorEventListener { |
| private volatile CountDownLatch mCountDownLatch; |
| private volatile SensorEventRegistry mEventRegistry; |
| private volatile long mTimestampForLastSensorEvent = 0; |
| |
| @Override |
| public void onAccuracyChanged(Sensor sensor, int accuracy) {} |
| |
| @Override |
| public void onSensorChanged(SensorEvent event) { |
| long elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos(); |
| int type = event.sensor.getType(); |
| |
| if (type == Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT) { |
| switch((int) event.values[0]) { |
| case (int) OFF_BODY_EVENT_VALUE: |
| Log.i(TAG, "onSensorChanged(): OFF_BODY ts="+event.timestamp+ |
| ", now="+elapsedRealtimeNanos+", delta="+ |
| (elapsedRealtimeNanos-event.timestamp)/1000000+"mS"); |
| mPreviousSensorState = State.OFF_BODY; |
| break; |
| case (int) ON_BODY_EVENT_VALUE: |
| Log.i(TAG, "onSensorChanged(): ON_BODY ts = "+event.timestamp+ |
| ", now="+elapsedRealtimeNanos+", delta="+ |
| (elapsedRealtimeNanos-event.timestamp)/1000000+"mS"); |
| mPreviousSensorState = State.ON_BODY; |
| break; |
| default: |
| Log.e(TAG, "onSensorChanged(): invalid value "+event.values[0]+ |
| " received"); |
| mBadValueSeen = event.values[0]; |
| break; |
| } |
| mEventRegistry = new SensorEventRegistry(event, elapsedRealtimeNanos); |
| getTestLogger().logMessage( |
| R.string.snsr_offbody_state_change, |
| (int) event.values[0], |
| elapsedRealtimeNanos); |
| releaseLatch(); |
| } |
| } |
| |
| public void releaseLatch() { |
| if (mCountDownLatch != null) { |
| mCountDownLatch.countDown(); |
| } |
| } |
| |
| public long getTimeStampForSensorEvent() { |
| return mTimestampForLastSensorEvent; |
| } |
| |
| public String awaitAndVerifyEvent(float expectedResponseValue) throws Throwable { |
| return awaitAndVerifyEvent(expectedResponseValue, 0); |
| } |
| |
| public String awaitAndVerifyEvent(float expectedResponseValue, int maxEventLatencyMs) |
| throws Throwable { |
| SensorEventRegistry registry = waitForEvent(); |
| String eventArrivalMessage; |
| if ((registry == null) || (registry.event == null)) { |
| eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, false); |
| Assert.fail(eventArrivalMessage); |
| } |
| |
| // verify an event arrived, and it is indeed a Low Latency Offbody Detect event |
| SensorEvent event = registry.event; |
| eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, event != null); |
| Assert.assertNotNull(eventArrivalMessage, event); |
| |
| String result = verifyEvent(registry, expectedResponseValue, maxEventLatencyMs); |
| return result; |
| } |
| |
| public String verifyEvent(SensorEventRegistry registry, float expectedResponseValue, |
| int maxEventLatencyMs) throws Throwable { |
| int eventType = registry.event.sensor.getType(); |
| String eventTypeMessage = getString( |
| R.string.snsr_offbody_event_type, |
| Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, |
| eventType); |
| Assert.assertEquals(eventTypeMessage, |
| Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, |
| eventType); |
| |
| float value = registry.event.values[0]; |
| String sensorName = registry.event.sensor.getName(); |
| String eventName = (value == ON_BODY_EVENT_VALUE) ? "ON-BODY" : "OFF-BODY"; |
| |
| long eventLatencyMs = (registry.receiveTimestampNanos/NANOSECONDS_PER_MILLISECOND) |
| - mTestStartTimestampMs; |
| |
| int valuesLength = registry.event.values.length; |
| String valuesLengthMessage = getString( |
| R.string.snsr_event_length, |
| OFFBODY_EVENT_VALUES_LENGTH, |
| valuesLength, |
| sensorName); |
| Assert.assertEquals(valuesLengthMessage, OFFBODY_EVENT_VALUES_LENGTH, valuesLength); |
| |
| String valuesMessage = getString( |
| R.string.snsr_event_value, |
| expectedResponseValue, |
| value, |
| sensorName); |
| Assert.assertEquals(valuesMessage, expectedResponseValue, value); |
| |
| if (maxEventLatencyMs != 0) { |
| Log.i(TAG, "event latency was "+eventLatencyMs+" ms for "+ |
| eventName+" event"); |
| String responseViolationMessage = getString( |
| R.string.snsr_offbody_response_timing_violation, |
| eventName, |
| maxEventLatencyMs, |
| eventLatencyMs); |
| boolean violation = (eventLatencyMs > maxEventLatencyMs); |
| Assert.assertFalse(responseViolationMessage, violation); |
| } |
| return null; |
| } |
| |
| private void verifyOffbodyEventNotInvalid() throws InterruptedException { |
| if (mBadValueSeen != BAD_VALUE_SEEN_INIT) { |
| Assert.fail( |
| String.format(getString(R.string.snsr_offbody_event_invalid_value), |
| OFF_BODY_EVENT_VALUE, |
| ON_BODY_EVENT_VALUE, |
| mBadValueSeen)); |
| } |
| } |
| |
| private SensorEventRegistry waitForEvent() throws InterruptedException { |
| return waitForEvent(null); |
| } |
| |
| private SensorEventRegistry waitForEvent(PowerManager.WakeLock suspendLock) |
| throws InterruptedException { |
| mCountDownLatch = new CountDownLatch(1); |
| |
| if ((suspendLock != null) && suspendLock.isHeld()) { |
| suspendLock.release(); |
| } |
| |
| mCountDownLatch.await(LLOB_EVENT_MAX_DELAY_SEC, TimeUnit.SECONDS); |
| |
| if ((suspendLock != null) && !suspendLock.isHeld()) { |
| suspendLock.acquire(); |
| } |
| |
| SensorEventRegistry registry = mEventRegistry; |
| |
| // Save the last timestamp when the event triggered. |
| if (mEventRegistry != null && mEventRegistry.event != null) { |
| mTimestampForLastSensorEvent = mEventRegistry.event.timestamp; |
| } |
| |
| mEventRegistry = null; |
| verifyOffbodyEventNotInvalid(); |
| return registry != null ? registry : new SensorEventRegistry(null, 0); |
| } |
| |
| public SensorEvent waitForSensorEvent() throws InterruptedException { |
| SensorEvent event = null; |
| mCountDownLatch = new CountDownLatch(1); |
| mCountDownLatch.await(LLOB_EVENT_MAX_DELAY_SEC, TimeUnit.SECONDS); |
| |
| if (mEventRegistry != null && mEventRegistry.event != null) { |
| event = mEventRegistry.event; |
| } |
| |
| mEventRegistry = null; |
| verifyOffbodyEventNotInvalid(); |
| return event; |
| } |
| } |
| |
| public OffBodySensorTestActivity() { |
| super(OffBodySensorTestActivity.class); |
| } |
| |
| |
| @Override |
| protected void activitySetUp() throws InterruptedException { |
| PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); |
| mDeviceSuspendLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, |
| "OffBodySensorTestActivity"); |
| mDeviceSuspendLock.acquire(); |
| mOffBodySensorRegistered = false; |
| mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); |
| mOffBodySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, |
| true); |
| if (mOffBodySensor == null) { |
| setTestResultAndFinish(true); |
| return; |
| } |
| LocalBroadcastManager.getInstance(this).registerReceiver(myBroadCastReceiver, |
| new IntentFilter(ACTION_ALARM)); |
| Intent intent = new Intent(this, AlarmReceiver.class); |
| mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); |
| mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); |
| mScreenManipulator = new SensorTestScreenManipulator(this); |
| try { |
| mScreenManipulator.initialize(this); |
| } catch (InterruptedException e) { |
| } |
| } |
| |
| private void startTimeoutTimer(long delayMs) { |
| mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, |
| SystemClock.elapsedRealtime() + delayMs, |
| mPendingIntent); |
| } |
| |
| private void stopTimeoutTimer() { |
| mAlarmManager.cancel(mPendingIntent); |
| } |
| |
| private void stopOffbodySensorListener(SensorEventVerifier verifier) { |
| if (mOffBodySensorRegistered) { |
| mSensorManager.unregisterListener(verifier); |
| mOffBodySensorRegistered = false; |
| } |
| } |
| |
| private boolean startOffbodySensorListener(SensorEventVerifier verifier) { |
| if (!mOffBodySensorRegistered) { |
| if (!mSensorManager.registerListener(verifier, mOffBodySensor, |
| SensorManager.SENSOR_DELAY_FASTEST)) { |
| Log.e(TAG, "error registering listener for LLOB"); |
| setTestResultAndFinish(true); |
| return false; |
| } |
| mOffBodySensorRegistered = true; |
| } |
| return true; |
| } |
| |
| public static class AlarmReceiver extends BroadcastReceiver { |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| Intent alarm_intent = new Intent(context, OffBodySensorTestActivity.class); |
| alarm_intent.setAction(OffBodySensorTestActivity.ACTION_ALARM); |
| LocalBroadcastManager.getInstance(context).sendBroadcastSync(alarm_intent); |
| } |
| } |
| |
| public BroadcastReceiver myBroadCastReceiver = new BroadcastReceiver() { |
| @Override |
| public void onReceive(Context context, Intent intent) { |
| mVerifier.releaseLatch(); |
| mScreenManipulator.turnScreenOn(); |
| if (!mDeviceSuspendLock.isHeld()) { |
| mDeviceSuspendLock.acquire(); |
| } |
| } |
| }; |
| |
| public String testOffbodyDetectResponseTime() throws Throwable { |
| Sensor wakeUpSensor = mSensorManager.getDefaultSensor( |
| Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); |
| if (wakeUpSensor == null) { |
| throw new SensorNotSupportedException(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); |
| } |
| return runOffbodyDetectResponseTimeTest(wakeUpSensor); |
| } |
| |
| public String testOnbodyDetectResponseTime() throws Throwable { |
| Sensor wakeUpSensor = mSensorManager.getDefaultSensor( |
| Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); |
| if (wakeUpSensor == null) { |
| throw new SensorNotSupportedException(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); |
| } |
| return runOnbodyDetectResponseTimeTest(wakeUpSensor); |
| } |
| |
| public String testWakeAPOffbodyDetect() throws Throwable { |
| Sensor wakeUpSensor = mSensorManager.getDefaultSensor( |
| Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); |
| if (wakeUpSensor == null) { |
| throw new SensorNotSupportedException(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); |
| } |
| return runWakeAPOffbodyDetectTest(wakeUpSensor); |
| } |
| |
| public String runOffbodyDetectResponseTimeTest(Sensor sensor) throws Throwable { |
| boolean success; |
| String eventArrivalMessage; |
| mOffBodySensor = sensor; |
| mBadValueSeen = BAD_VALUE_SEEN_INIT; |
| |
| try { |
| // If device not currently on-body, instruct user to put it on wrist |
| mTestStartTimestampMs = 0; |
| mVerifier = new SensorEventVerifier(); |
| success = startOffbodySensorListener(mVerifier); |
| Assert.assertTrue( |
| getString(R.string.snsr_offbody_sensor_registration, success), |
| success); |
| SensorEvent event = mVerifier.waitForSensorEvent(); |
| eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, event != null); |
| Assert.assertNotNull(eventArrivalMessage, event); |
| |
| SensorTestLogger logger = getTestLogger(); |
| if (event.values[0] != ON_BODY_EVENT_VALUE) { |
| // Instruct user on how to perform offbody detect test |
| logger.logInstructions(R.string.snsr_start_offbody_sensor_test_instr); |
| waitForUserToBegin(); |
| if (mPreviousSensorState != State.ON_BODY) { |
| event = mVerifier.waitForSensorEvent(); |
| eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, |
| event != null); |
| Assert.assertNotNull(eventArrivalMessage, event); |
| if (event.values[0] != ON_BODY_EVENT_VALUE) { |
| Assert.fail( |
| String.format(getString(R.string.snsr_offbody_event_wrong_value), |
| ON_BODY_EVENT_VALUE, |
| event.values[0])); |
| } |
| } |
| } |
| |
| // Instruct user on how to perform offbody detect test |
| logger.logInstructions(R.string.snsr_offbody_detect_test_instr); |
| waitForUserToBegin(); |
| |
| // Count down before actually starting, leaving time to react after pressing the Next |
| // button. |
| for (int i = 0; i < COUNTDOWN_NUM_INTERVALS; i++) { |
| try { |
| Thread.sleep(COUNTDOWN_INTERVAL_MS); |
| } catch (InterruptedException e) { |
| // Ignore the interrupt and continue counting down. |
| } |
| logger.logInstructions(R.string.snsr_offbody_detect_test_countdown, |
| COUNTDOWN_NUM_INTERVALS - i - 1); |
| } |
| mTestStartTimestampMs = SystemClock.elapsedRealtime(); |
| |
| // Verify off-body event latency is within spec |
| mVerifier.awaitAndVerifyEvent(OFF_BODY_EVENT_VALUE, MAX_OFF_BODY_EVENT_LATENCY_MS); |
| } finally { |
| stopOffbodySensorListener(mVerifier); |
| } |
| return null; |
| } |
| |
| public String runOnbodyDetectResponseTimeTest(Sensor sensor) throws Throwable { |
| mOffBodySensor = sensor; |
| SensorTestLogger logger = getTestLogger(); |
| mBadValueSeen = BAD_VALUE_SEEN_INIT; |
| |
| try { |
| // If device not currently off-body, instruct user to remove it from wrist |
| mTestStartTimestampMs = 0; |
| mVerifier = new SensorEventVerifier(); |
| boolean success = startOffbodySensorListener(mVerifier); |
| Assert.assertTrue( |
| getString(R.string.snsr_offbody_sensor_registration, success), |
| success); |
| SensorEvent event = mVerifier.waitForSensorEvent(); |
| String eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, |
| event != null); |
| Assert.assertNotNull(eventArrivalMessage, event); |
| if (event.values[0] != OFF_BODY_EVENT_VALUE) { |
| // Instruct user on how to perform offbody detect test |
| logger.logInstructions(R.string.snsr_start_onbody_sensor_test_instr); |
| waitForUserToBegin(); |
| if (mPreviousSensorState != State.OFF_BODY) { |
| event = mVerifier.waitForSensorEvent(); |
| eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, |
| event != null); |
| Assert.assertNotNull(eventArrivalMessage, event); |
| if (event.values[0] != OFF_BODY_EVENT_VALUE) { |
| Assert.fail( |
| String.format(getString(R.string.snsr_offbody_event_wrong_value), |
| OFF_BODY_EVENT_VALUE, |
| event.values[0])); |
| } |
| } |
| } |
| |
| // Display on-body latency test instructions |
| logger.logInstructions(R.string.snsr_onbody_detect_test_instr); |
| waitForUserToBegin(); |
| mTestStartTimestampMs = SystemClock.elapsedRealtime(); |
| mVerifier.awaitAndVerifyEvent(ON_BODY_EVENT_VALUE, MAX_ON_BODY_EVENT_LATENCY_MS); |
| } finally { |
| stopOffbodySensorListener(mVerifier); |
| } |
| return null; |
| } |
| |
| public String runWakeAPOffbodyDetectTest(Sensor sensor) throws Throwable { |
| final long ALARM_WAKE_UP_DELAY_MS = 40000; |
| String eventArrivalMessage; |
| SensorEventRegistry registry; |
| SensorTestLogger logger = getTestLogger(); |
| mBadValueSeen = BAD_VALUE_SEEN_INIT; |
| mVerifier = new SensorEventVerifier(); |
| mOffBodySensor = sensor; |
| mTestStartTimestampMs = 0; |
| |
| mTestStartTimestampMs = SystemClock.elapsedRealtime(); |
| SuspendStateMonitor suspendStateMonitor = new SuspendStateMonitor(); |
| try { |
| boolean success = startOffbodySensorListener(mVerifier); |
| Assert.assertTrue( |
| getString(R.string.snsr_offbody_sensor_registration, success), |
| success); |
| |
| // grab the current off-body state, which should be ON-BODY |
| if (mPreviousSensorState != State.ON_BODY) { |
| registry = mVerifier.waitForEvent(); |
| if ((registry == null) || (registry.event == null) || |
| (registry.event.values[0] != ON_BODY_EVENT_VALUE)) { |
| eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, false); |
| Assert.fail(eventArrivalMessage); |
| |
| // Tell user to put watch on wrist |
| logger.logInstructions(R.string.snsr_start_offbody_sensor_test_instr); |
| waitForUserToBegin(); |
| if (mPreviousSensorState != State.ON_BODY) { |
| registry = mVerifier.waitForEvent(); |
| if ((registry == null) || (registry.event == null)) { |
| eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, false); |
| Assert.fail(eventArrivalMessage); |
| } else { |
| Assert.assertTrue( |
| String.format(getString(R.string.snsr_offbody_event_wrong_value), |
| ON_BODY_EVENT_VALUE, |
| registry.event.values[0]), |
| ON_BODY_EVENT_VALUE == registry.event.values[0]); |
| } |
| } |
| } |
| } |
| |
| // Instruct user on how to perform offbody detect sleep test |
| logger.logInstructions(R.string.snsr_ap_wake_offbody_detect_test_instr); |
| waitForUserToBegin(); |
| |
| long testStartTimeNs = SystemClock.elapsedRealtimeNanos(); |
| startTimeoutTimer(ALARM_WAKE_UP_AP_DELAY_MS); |
| |
| // Wait for the first event to trigger. Device is expected to go into suspend here. |
| registry = mVerifier.waitForEvent(mDeviceSuspendLock); |
| if ((registry == null) || (registry.event == null)) { |
| eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, false); |
| Assert.fail(eventArrivalMessage); |
| } |
| |
| mVerifier.verifyEvent(registry, OFF_BODY_EVENT_VALUE, 0); |
| |
| long eventTimeStampNs = registry.event.timestamp; |
| long endTimeNs = SystemClock.elapsedRealtimeNanos(); |
| long lastWakeupTimeNs = TimeUnit.MILLISECONDS.toNanos( |
| suspendStateMonitor.getLastWakeUpTime()); |
| Assert.assertTrue(getString(R.string.snsr_device_did_not_go_into_suspend), |
| testStartTimeNs < lastWakeupTimeNs && lastWakeupTimeNs < endTimeNs); |
| long timestampDelta = Math.abs(lastWakeupTimeNs - eventTimeStampNs); |
| Assert.assertTrue( |
| String.format(getString(R.string.snsr_device_did_not_wake_up_at_trigger), |
| TimeUnit.NANOSECONDS.toMillis(lastWakeupTimeNs), |
| TimeUnit.NANOSECONDS.toMillis(eventTimeStampNs)), |
| timestampDelta < MAX_ACCEPTABLE_DELAY_EVENT_AP_WAKE_UP_NS); |
| } finally { |
| stopTimeoutTimer(); |
| suspendStateMonitor.cancel(); |
| mScreenManipulator.turnScreenOn(); |
| playSound(); |
| } |
| return null; |
| } |
| |
| @Override |
| protected void activityCleanUp() { |
| if (mOffBodySensorRegistered) { |
| stopOffbodySensorListener(mVerifier); |
| } |
| stopTimeoutTimer(); |
| LocalBroadcastManager.getInstance(this).unregisterReceiver(myBroadCastReceiver); |
| if (mOffBodySensor != null) { |
| mOffBodySensor = null; |
| } |
| if (mScreenManipulator != null){ |
| mScreenManipulator.close(); |
| } |
| if ((mDeviceSuspendLock != null) && mDeviceSuspendLock.isHeld()) { |
| mDeviceSuspendLock.release(); |
| } |
| } |
| } |