1 /* 2 * Copyright (C) 2017 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 com.android.cts.verifier.sensors; 17 18 import android.app.AlarmManager; 19 import android.app.PendingIntent; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.hardware.Sensor; 25 import android.hardware.SensorEvent; 26 import android.hardware.SensorEventListener; 27 import android.hardware.SensorManager; 28 import android.hardware.cts.helpers.SensorNotSupportedException; 29 import android.hardware.cts.helpers.SuspendStateMonitor; 30 import android.os.PowerManager; 31 import android.os.PowerManager.WakeLock; 32 import android.os.SystemClock; 33 import android.support.v4.content.LocalBroadcastManager; 34 import android.util.Log; 35 36 import com.android.cts.verifier.R; 37 import com.android.cts.verifier.sensors.helpers.SensorTestScreenManipulator; 38 import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity; 39 40 import java.util.concurrent.CountDownLatch; 41 import java.util.concurrent.TimeUnit; 42 43 import junit.framework.Assert; 44 import static junit.framework.Assert.fail; 45 46 47 /** 48 * Manual test for testing the low-latency offbody detect sensor. This test consists of 3 49 * sub-tests designed to verify the sensor event data, verify event trigger response times 50 * are within spec for the sensor type, and to verify that the sensor can wake the device. 51 */ 52 public class OffBodySensorTestActivity 53 extends SensorCtsVerifierTestActivity { 54 private static final String TAG="OffbodySensorTest"; 55 private static String ACTION_ALARM = "OffBodySensorTestActivity.ACTION_ALARM"; 56 private static final int MAX_OFF_BODY_EVENT_LATENCY_MS = 1000; 57 private static final int MAX_ON_BODY_EVENT_LATENCY_MS = 5000; 58 private static final int LLOB_EVENT_MAX_DELAY_SEC = 20; 59 private static final long MAX_ALLOWED_DELAY_MS = TimeUnit.SECONDS.toMillis(1); 60 private static final long RESULT_REPORT_SHOW_TIME_MS = TimeUnit.SECONDS.toMillis(5); 61 private static final int OFFBODY_EVENT_VALUES_LENGTH = 1; 62 63 private static final float OFF_BODY_EVENT_VALUE = 0; 64 private static final float ON_BODY_EVENT_VALUE = 1; 65 private static final float BAD_VALUE_SEEN_INIT = 0; 66 private static float mBadValueSeen = BAD_VALUE_SEEN_INIT; 67 68 private enum State { 69 OFF_BODY, ON_BODY, UNKNOWN 70 } 71 72 // time to wait for offbody event after the device has gone into suspend. Even after 73 // 45 secs if LLOB sensor does not trigger, the test will fail. 74 private static final long ALARM_WAKE_UP_AP_DELAY_MS = TimeUnit.SECONDS.toMillis(45); 75 76 // acceptable time difference between event time and AP wake up time. 77 private static final long MAX_ACCEPTABLE_DELAY_EVENT_AP_WAKE_UP_NS = 78 TimeUnit.MILLISECONDS.toNanos(1200); 79 80 private static final int NANOSECONDS_PER_MILLISECOND = 1000000; 81 private AlarmManager mAlarmManager; 82 private SensorManager mSensorManager; 83 private Sensor mOffBodySensor; 84 private boolean mOffBodySensorRegistered; 85 private long mTestStartTimestampMs; 86 private State mPreviousSensorState; 87 private PendingIntent mPendingIntent; 88 private PowerManager.WakeLock mDeviceSuspendLock; 89 private SensorEventVerifier mVerifier; 90 private SensorTestScreenManipulator mScreenManipulator; 91 92 public class SensorEventRegistry { 93 public final SensorEvent event; 94 public final long receiveTimestampNanos; 95 96 public SensorEventRegistry(SensorEvent event, long realtimeTimestampNanos) { 97 this.event = event; 98 this.receiveTimestampNanos = realtimeTimestampNanos; 99 } 100 } 101 102 private class SensorEventVerifier implements SensorEventListener { 103 private volatile CountDownLatch mCountDownLatch; 104 private volatile SensorEventRegistry mEventRegistry; 105 private volatile long mTimestampForLastSensorEvent = 0; 106 107 @Override 108 public void onAccuracyChanged(Sensor sensor, int accuracy) {} 109 110 @Override 111 public void onSensorChanged(SensorEvent event) { 112 long elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos(); 113 int type = event.sensor.getType(); 114 115 if (type == Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT) { 116 switch((int) event.values[0]) { 117 case (int) OFF_BODY_EVENT_VALUE: 118 Log.i(TAG, "onSensorChanged(): OFF_BODY ts="+event.timestamp+ 119 ", now="+elapsedRealtimeNanos+", delta="+ 120 (elapsedRealtimeNanos-event.timestamp)/1000000+"mS"); 121 mPreviousSensorState = State.OFF_BODY; 122 break; 123 case (int) ON_BODY_EVENT_VALUE: 124 Log.i(TAG, "onSensorChanged(): ON_BODY ts = "+event.timestamp+ 125 ", now="+elapsedRealtimeNanos+", delta="+ 126 (elapsedRealtimeNanos-event.timestamp)/1000000+"mS"); 127 mPreviousSensorState = State.ON_BODY; 128 break; 129 default: 130 Log.e(TAG, "onSensorChanged(): invalid value "+event.values[0]+ 131 " received"); 132 mBadValueSeen = event.values[0]; 133 break; 134 } 135 mEventRegistry = new SensorEventRegistry(event, elapsedRealtimeNanos); 136 getTestLogger().logMessage( 137 R.string.snsr_offbody_state_change, 138 (int) event.values[0], 139 elapsedRealtimeNanos); 140 releaseLatch(); 141 } 142 } 143 144 public void releaseLatch() { 145 if (mCountDownLatch != null) { 146 mCountDownLatch.countDown(); 147 } 148 } 149 150 public long getTimeStampForSensorEvent() { 151 return mTimestampForLastSensorEvent; 152 } 153 154 public String awaitAndVerifyEvent(float expectedResponseValue) throws Throwable { 155 return awaitAndVerifyEvent(expectedResponseValue, 0); 156 } 157 158 public String awaitAndVerifyEvent(float expectedResponseValue, int maxEventLatencyMs) 159 throws Throwable { 160 SensorEventRegistry registry = waitForEvent(); 161 String eventArrivalMessage; 162 if ((registry == null) || (registry.event == null)) { 163 eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, false); 164 Assert.fail(eventArrivalMessage); 165 } 166 167 // verify an event arrived, and it is indeed a Low Latency Offbody Detect event 168 SensorEvent event = registry.event; 169 eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, event != null); 170 Assert.assertNotNull(eventArrivalMessage, event); 171 172 String result = verifyEvent(registry, expectedResponseValue, maxEventLatencyMs); 173 return result; 174 } 175 176 public String verifyEvent(SensorEventRegistry registry, float expectedResponseValue, 177 int maxEventLatencyMs) throws Throwable { 178 int eventType = registry.event.sensor.getType(); 179 String eventTypeMessage = getString( 180 R.string.snsr_offbody_event_type, 181 Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, 182 eventType); 183 Assert.assertEquals(eventTypeMessage, 184 Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, 185 eventType); 186 187 float value = registry.event.values[0]; 188 String sensorName = registry.event.sensor.getName(); 189 String eventName = (value == ON_BODY_EVENT_VALUE) ? "ON-BODY" : "OFF-BODY"; 190 191 long eventLatencyMs = (registry.receiveTimestampNanos/NANOSECONDS_PER_MILLISECOND) 192 - mTestStartTimestampMs; 193 194 int valuesLength = registry.event.values.length; 195 String valuesLengthMessage = getString( 196 R.string.snsr_event_length, 197 OFFBODY_EVENT_VALUES_LENGTH, 198 valuesLength, 199 sensorName); 200 Assert.assertEquals(valuesLengthMessage, OFFBODY_EVENT_VALUES_LENGTH, valuesLength); 201 202 String valuesMessage = getString( 203 R.string.snsr_event_value, 204 expectedResponseValue, 205 value, 206 sensorName); 207 Assert.assertEquals(valuesMessage, expectedResponseValue, value); 208 209 if (maxEventLatencyMs != 0) { 210 Log.i(TAG, "event latency was "+eventLatencyMs+" ms for "+ 211 eventName+" event"); 212 String responseViolationMessage = getString( 213 R.string.snsr_offbody_response_timing_violation, 214 eventName, 215 maxEventLatencyMs, 216 eventLatencyMs); 217 boolean violation = (eventLatencyMs > maxEventLatencyMs); 218 Assert.assertFalse(responseViolationMessage, violation); 219 } 220 return null; 221 } 222 223 private void verifyOffbodyEventNotInvalid() throws InterruptedException { 224 if (mBadValueSeen != BAD_VALUE_SEEN_INIT) { 225 Assert.fail( 226 String.format(getString(R.string.snsr_offbody_event_invalid_value), 227 OFF_BODY_EVENT_VALUE, 228 ON_BODY_EVENT_VALUE, 229 mBadValueSeen)); 230 } 231 } 232 233 private SensorEventRegistry waitForEvent() throws InterruptedException { 234 return waitForEvent(null); 235 } 236 237 private SensorEventRegistry waitForEvent(PowerManager.WakeLock suspendLock) 238 throws InterruptedException { 239 mCountDownLatch = new CountDownLatch(1); 240 241 if ((suspendLock != null) && suspendLock.isHeld()) { 242 suspendLock.release(); 243 } 244 245 mCountDownLatch.await(LLOB_EVENT_MAX_DELAY_SEC, TimeUnit.SECONDS); 246 247 if ((suspendLock != null) && !suspendLock.isHeld()) { 248 suspendLock.acquire(); 249 } 250 251 SensorEventRegistry registry = mEventRegistry; 252 253 // Save the last timestamp when the event triggered. 254 if (mEventRegistry != null && mEventRegistry.event != null) { 255 mTimestampForLastSensorEvent = mEventRegistry.event.timestamp; 256 } 257 258 mEventRegistry = null; 259 verifyOffbodyEventNotInvalid(); 260 return registry != null ? registry : new SensorEventRegistry(null, 0); 261 } 262 263 public SensorEvent waitForSensorEvent() throws InterruptedException { 264 SensorEvent event = null; 265 mCountDownLatch = new CountDownLatch(1); 266 mCountDownLatch.await(LLOB_EVENT_MAX_DELAY_SEC, TimeUnit.SECONDS); 267 268 if (mEventRegistry != null && mEventRegistry.event != null) { 269 event = mEventRegistry.event; 270 } 271 272 mEventRegistry = null; 273 verifyOffbodyEventNotInvalid(); 274 return event; 275 } 276 } 277 278 public OffBodySensorTestActivity() { 279 super(OffBodySensorTestActivity.class); 280 } 281 282 283 @Override 284 protected void activitySetUp() throws InterruptedException { 285 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 286 mDeviceSuspendLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 287 "OffBodySensorTestActivity"); 288 mDeviceSuspendLock.acquire(); 289 mOffBodySensorRegistered = false; 290 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 291 mOffBodySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, 292 true); 293 if (mOffBodySensor == null) { 294 setTestResultAndFinish(true); 295 return; 296 } 297 LocalBroadcastManager.getInstance(this).registerReceiver(myBroadCastReceiver, 298 new IntentFilter(ACTION_ALARM)); 299 Intent intent = new Intent(this, AlarmReceiver.class); 300 mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); 301 mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); 302 mScreenManipulator = new SensorTestScreenManipulator(this); 303 try { 304 mScreenManipulator.initialize(this); 305 } catch (InterruptedException e) { 306 } 307 } 308 309 private void startTimeoutTimer(long delayMs) { 310 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, 311 SystemClock.elapsedRealtime() + delayMs, 312 mPendingIntent); 313 } 314 315 private void stopTimeoutTimer() { 316 mAlarmManager.cancel(mPendingIntent); 317 } 318 319 private void stopOffbodySensorListener(SensorEventVerifier verifier) { 320 if (mOffBodySensorRegistered) { 321 mSensorManager.unregisterListener(verifier); 322 mOffBodySensorRegistered = false; 323 } 324 } 325 326 private boolean startOffbodySensorListener(SensorEventVerifier verifier) { 327 if (!mOffBodySensorRegistered) { 328 if (!mSensorManager.registerListener(verifier, mOffBodySensor, 329 SensorManager.SENSOR_DELAY_FASTEST)) { 330 Log.e(TAG, "error registering listener for LLOB"); 331 setTestResultAndFinish(true); 332 return false; 333 } 334 mOffBodySensorRegistered = true; 335 } 336 return true; 337 } 338 339 public static class AlarmReceiver extends BroadcastReceiver { 340 @Override 341 public void onReceive(Context context, Intent intent) { 342 Intent alarm_intent = new Intent(context, OffBodySensorTestActivity.class); 343 alarm_intent.setAction(OffBodySensorTestActivity.ACTION_ALARM); 344 LocalBroadcastManager.getInstance(context).sendBroadcastSync(alarm_intent); 345 } 346 } 347 348 public BroadcastReceiver myBroadCastReceiver = new BroadcastReceiver() { 349 @Override 350 public void onReceive(Context context, Intent intent) { 351 mVerifier.releaseLatch(); 352 mScreenManipulator.turnScreenOn(); 353 if (!mDeviceSuspendLock.isHeld()) { 354 mDeviceSuspendLock.acquire(); 355 } 356 } 357 }; 358 359 public String testOffbodyDetectResponseTime() throws Throwable { 360 Sensor wakeUpSensor = mSensorManager.getDefaultSensor( 361 Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); 362 if (wakeUpSensor == null) { 363 throw new SensorNotSupportedException(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); 364 } 365 return runOffbodyDetectResponseTimeTest(wakeUpSensor); 366 } 367 368 public String testOnbodyDetectResponseTime() throws Throwable { 369 Sensor wakeUpSensor = mSensorManager.getDefaultSensor( 370 Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); 371 if (wakeUpSensor == null) { 372 throw new SensorNotSupportedException(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); 373 } 374 return runOnbodyDetectResponseTimeTest(wakeUpSensor); 375 } 376 377 public String testWakeAPOffbodyDetect() throws Throwable { 378 Sensor wakeUpSensor = mSensorManager.getDefaultSensor( 379 Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); 380 if (wakeUpSensor == null) { 381 throw new SensorNotSupportedException(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, true); 382 } 383 return runWakeAPOffbodyDetectTest(wakeUpSensor); 384 } 385 386 public String runOffbodyDetectResponseTimeTest(Sensor sensor) throws Throwable { 387 boolean success; 388 String eventArrivalMessage; 389 mOffBodySensor = sensor; 390 mBadValueSeen = BAD_VALUE_SEEN_INIT; 391 392 try { 393 // If device not currently on-body, instruct user to put it on wrist 394 mTestStartTimestampMs = 0; 395 mVerifier = new SensorEventVerifier(); 396 success = startOffbodySensorListener(mVerifier); 397 Assert.assertTrue( 398 getString(R.string.snsr_offbody_sensor_registration, success), 399 success); 400 SensorEvent event = mVerifier.waitForSensorEvent(); 401 eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, event != null); 402 Assert.assertNotNull(eventArrivalMessage, event); 403 404 SensorTestLogger logger = getTestLogger(); 405 if (event.values[0] != ON_BODY_EVENT_VALUE) { 406 // Instruct user on how to perform offbody detect test 407 logger.logInstructions(R.string.snsr_start_offbody_sensor_test_instr); 408 waitForUserToBegin(); 409 if (mPreviousSensorState != State.ON_BODY) { 410 event = mVerifier.waitForSensorEvent(); 411 eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, 412 event != null); 413 Assert.assertNotNull(eventArrivalMessage, event); 414 if (event.values[0] != ON_BODY_EVENT_VALUE) { 415 Assert.fail( 416 String.format(getString(R.string.snsr_offbody_event_wrong_value), 417 ON_BODY_EVENT_VALUE, 418 event.values[0])); 419 } 420 } 421 } 422 423 // Instruct user on how to perform offbody detect test 424 logger.logInstructions(R.string.snsr_offbody_detect_test_instr); 425 waitForUserToBegin(); 426 mTestStartTimestampMs = SystemClock.elapsedRealtime(); 427 428 // Verify off-body event latency is within spec 429 mVerifier.awaitAndVerifyEvent(OFF_BODY_EVENT_VALUE, MAX_OFF_BODY_EVENT_LATENCY_MS); 430 } finally { 431 stopOffbodySensorListener(mVerifier); 432 } 433 return null; 434 } 435 436 public String runOnbodyDetectResponseTimeTest(Sensor sensor) throws Throwable { 437 mOffBodySensor = sensor; 438 SensorTestLogger logger = getTestLogger(); 439 mBadValueSeen = BAD_VALUE_SEEN_INIT; 440 441 try { 442 // If device not currently off-body, instruct user to remove it from wrist 443 mTestStartTimestampMs = 0; 444 mVerifier = new SensorEventVerifier(); 445 boolean success = startOffbodySensorListener(mVerifier); 446 Assert.assertTrue( 447 getString(R.string.snsr_offbody_sensor_registration, success), 448 success); 449 SensorEvent event = mVerifier.waitForSensorEvent(); 450 String eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, 451 event != null); 452 Assert.assertNotNull(eventArrivalMessage, event); 453 if (event.values[0] != OFF_BODY_EVENT_VALUE) { 454 // Instruct user on how to perform offbody detect test 455 logger.logInstructions(R.string.snsr_start_onbody_sensor_test_instr); 456 waitForUserToBegin(); 457 if (mPreviousSensorState != State.OFF_BODY) { 458 event = mVerifier.waitForSensorEvent(); 459 eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, 460 event != null); 461 Assert.assertNotNull(eventArrivalMessage, event); 462 if (event.values[0] != OFF_BODY_EVENT_VALUE) { 463 Assert.fail( 464 String.format(getString(R.string.snsr_offbody_event_wrong_value), 465 OFF_BODY_EVENT_VALUE, 466 event.values[0])); 467 } 468 } 469 } 470 471 // Display on-body latency test instructions 472 logger.logInstructions(R.string.snsr_onbody_detect_test_instr); 473 waitForUserToBegin(); 474 mTestStartTimestampMs = SystemClock.elapsedRealtime(); 475 mVerifier.awaitAndVerifyEvent(ON_BODY_EVENT_VALUE, MAX_ON_BODY_EVENT_LATENCY_MS); 476 } finally { 477 stopOffbodySensorListener(mVerifier); 478 } 479 return null; 480 } 481 482 public String runWakeAPOffbodyDetectTest(Sensor sensor) throws Throwable { 483 final long ALARM_WAKE_UP_DELAY_MS = 40000; 484 String eventArrivalMessage; 485 SensorEventRegistry registry; 486 SensorTestLogger logger = getTestLogger(); 487 mBadValueSeen = BAD_VALUE_SEEN_INIT; 488 mVerifier = new SensorEventVerifier(); 489 mOffBodySensor = sensor; 490 mTestStartTimestampMs = 0; 491 492 mTestStartTimestampMs = SystemClock.elapsedRealtime(); 493 SuspendStateMonitor suspendStateMonitor = new SuspendStateMonitor(); 494 try { 495 boolean success = startOffbodySensorListener(mVerifier); 496 Assert.assertTrue( 497 getString(R.string.snsr_offbody_sensor_registration, success), 498 success); 499 500 // grab the current off-body state, which should be ON-BODY 501 if (mPreviousSensorState != State.ON_BODY) { 502 registry = mVerifier.waitForEvent(); 503 if ((registry == null) || (registry.event == null) || 504 (registry.event.values[0] != ON_BODY_EVENT_VALUE)) { 505 eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, false); 506 Assert.fail(eventArrivalMessage); 507 508 // Tell user to put watch on wrist 509 logger.logInstructions(R.string.snsr_start_offbody_sensor_test_instr); 510 waitForUserToBegin(); 511 if (mPreviousSensorState != State.ON_BODY) { 512 registry = mVerifier.waitForEvent(); 513 if ((registry == null) || (registry.event == null)) { 514 eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, false); 515 Assert.fail(eventArrivalMessage); 516 } else { 517 Assert.assertTrue( 518 String.format(getString(R.string.snsr_offbody_event_wrong_value), 519 ON_BODY_EVENT_VALUE, 520 registry.event.values[0]), 521 ON_BODY_EVENT_VALUE == registry.event.values[0]); 522 } 523 } 524 } 525 } 526 527 // Instruct user on how to perform offbody detect sleep test 528 logger.logInstructions(R.string.snsr_ap_wake_offbody_detect_test_instr); 529 waitForUserToBegin(); 530 531 long testStartTimeNs = SystemClock.elapsedRealtimeNanos(); 532 startTimeoutTimer(ALARM_WAKE_UP_AP_DELAY_MS); 533 534 // Wait for the first event to trigger. Device is expected to go into suspend here. 535 registry = mVerifier.waitForEvent(mDeviceSuspendLock); 536 if ((registry == null) || (registry.event == null)) { 537 eventArrivalMessage = getString(R.string.snsr_offbody_event_arrival, false); 538 Assert.fail(eventArrivalMessage); 539 } 540 541 mVerifier.verifyEvent(registry, OFF_BODY_EVENT_VALUE, 0); 542 543 long eventTimeStampNs = registry.event.timestamp; 544 long endTimeNs = SystemClock.elapsedRealtimeNanos(); 545 long lastWakeupTimeNs = TimeUnit.MILLISECONDS.toNanos( 546 suspendStateMonitor.getLastWakeUpTime()); 547 Assert.assertTrue(getString(R.string.snsr_device_did_not_go_into_suspend), 548 testStartTimeNs < lastWakeupTimeNs && lastWakeupTimeNs < endTimeNs); 549 long timestampDelta = Math.abs(lastWakeupTimeNs - eventTimeStampNs); 550 Assert.assertTrue( 551 String.format(getString(R.string.snsr_device_did_not_wake_up_at_trigger), 552 TimeUnit.NANOSECONDS.toMillis(lastWakeupTimeNs), 553 TimeUnit.NANOSECONDS.toMillis(eventTimeStampNs)), 554 timestampDelta < MAX_ACCEPTABLE_DELAY_EVENT_AP_WAKE_UP_NS); 555 } finally { 556 stopTimeoutTimer(); 557 suspendStateMonitor.cancel(); 558 mScreenManipulator.turnScreenOn(); 559 playSound(); 560 } 561 return null; 562 } 563 564 @Override 565 protected void activityCleanUp() { 566 if (mOffBodySensorRegistered) { 567 stopOffbodySensorListener(mVerifier); 568 } 569 stopTimeoutTimer(); 570 LocalBroadcastManager.getInstance(this).unregisterReceiver(myBroadCastReceiver); 571 if (mOffBodySensor != null) { 572 mOffBodySensor = null; 573 } 574 if (mScreenManipulator != null){ 575 mScreenManipulator.close(); 576 } 577 if ((mDeviceSuspendLock != null) && mDeviceSuspendLock.isHeld()) { 578 mDeviceSuspendLock.release(); 579 } 580 } 581 } 582