1 /* 2 * Copyright (C) 2011 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 17 package com.android.cts.verifier.camera.analyzer; 18 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.graphics.Bitmap; 25 import android.graphics.BitmapFactory; 26 import android.graphics.ImageFormat; 27 import android.hardware.Camera; 28 import android.hardware.usb.UsbAccessory; 29 import android.hardware.usb.UsbManager; 30 import android.os.ParcelFileDescriptor; 31 import android.util.Log; 32 import android.view.SurfaceView; 33 import android.widget.ImageView; 34 import android.widget.Toast; 35 36 import java.io.FileDescriptor; 37 import java.io.FileInputStream; 38 import java.io.FileOutputStream; 39 import java.io.IOException; 40 import java.util.ArrayList; 41 import java.util.List; 42 43 /** 44 * Implements a test to verify whether the Auto Exposure Lock functions as 45 * described in the API. 46 * 47 * The test consists three sub-categories. The first set of tests focus on 48 * testing whether the auto exposure lock works in various situations. 49 * For all tests in this set, the lock is set during the period when the camera 50 * preview is open. In this way the lock locks exposure according to the 51 * lighting at the moment of setting the lock. The second set of tests focus on 52 * testing whether the auto exposure lock works as expected after turning the 53 * preview off and on. The lock is set during the period when the camera 54 * preview is turned off. The lock is expected to lock an exposure level 55 * identical to the one before the preview is turned off. One special case in 56 * this category is to set lock before the preview is turned on for the first 57 * time. 58 */ 59 public class AutoLockTest extends CameraTests { 60 61 private static final String TAG = "AutoLockTest"; 62 /** USB permission to connect to ADK. */ 63 private static final String ACTION_USB_PERMISSION = "com.android.cts.verifier.USB_PERMISSION"; 64 /** Defines a long sleep period.*/ 65 private static final int SHORT_SLEEP = 2000; 66 /** Defines a short sleep period. */ 67 private static final int LONG_SLEEP = 4000; 68 69 /** Test results in text format. */ 70 private String mDebugText = new String(); 71 /** Detailed report. */ 72 private String mResultText = new String(); 73 /** Thread lock of the camera callbacks. */ 74 private final Object mProcessingImage = new Object(); 75 /** Memory address of the native test handler. */ 76 private long mTestHandler; 77 /** Array storing the reference test results. */ 78 private ArrayList<Boolean> mReferenceCompareResults; 79 /** Array storing the reference test scenario logs. */ 80 private ArrayList<String> mReferenceLogs; 81 /** Number of tests so far. */ 82 private int mTestCount; 83 84 /** Usb Manager of the USB connections. */ 85 private UsbManager mUsbManager; 86 /** Intent for getting the permission to access the ADK. */ 87 private PendingIntent mPermissionIntent; 88 /** Boolean to represent whether a permission is gained. */ 89 private boolean mPermissionRequestPending; 90 /** USB accessory pointing to the ADK. */ 91 private UsbAccessory mAccessory; 92 /** File descriptor of the USB communication port. */ 93 private ParcelFileDescriptor mFileDescriptor; 94 /** Output stream to write commands for ADK to. */ 95 private FileOutputStream mOutputStream; 96 97 /** Pointer to the CameraAnalyzerActivity activity. */ 98 private CameraAnalyzerActivity mActivity; 99 /** Boolean to tell whether the accessory is opened. */ 100 private boolean mSetupReady; 101 /** Thread lock for setting up the usb. */ 102 private final Object mUsbSetup = new Object(); 103 /** Boolean to indicate whether there is an ADK attached. */ 104 private boolean mUsingUsb = false; 105 /** Test results.*/ 106 private int[] mTestResults; 107 /** Number of tests. */ 108 private int mNumTests; 109 /** Singleton test instance.*/ 110 private static AutoLockTest singletonTest = null; 111 112 /** 113 * Receives the notice of whether the connection to ADK is granted or 114 * denied. 115 */ 116 private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { 117 @Override 118 public void onReceive(Context context, Intent intent) { 119 String action = intent.getAction(); 120 Log.v(TAG, String.format("Received USB broadcast with action %s ", action)); 121 122 if (ACTION_USB_PERMISSION.equals(action)) { 123 synchronized (this) { 124 UsbAccessory accessory = 125 (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); 126 127 if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { 128 // Grants the permission to connect to the ADK. 129 Log.v(TAG, "Open accessory 3"); 130 openAccessory(accessory); 131 // Overwrites the old camera instsance with the one currently opened 132 // by the CameraAnalyzerActivity instance, since the permission 133 // dialogue pauses the CameraAnalyzerActivity and forces the camera to 134 // be released and reopened when the dialogue disappears. 135 mTestCamera = mActivity.getCameraInstance(); 136 } else { 137 // Denies the permission to connect to the ADK. 138 Log.d(TAG, "permission denied for accessory " + accessory); 139 } 140 // Marks that the permission request has been processed. 141 mPermissionRequestPending = false; 142 } 143 } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) { 144 // Invokes when the USB is detached. 145 // Closes the accessory if it has not been closed. 146 Log.v(TAG, "Usb device detached"); 147 mUsingUsb = false; 148 UsbAccessory accessory = 149 (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); 150 if (accessory != null && accessory.equals(mAccessory)) { 151 closeAccessory(); 152 } 153 } 154 } 155 }; 156 157 /** 158 * Opens the ADK from USB and attaches the output stream with it. 159 * 160 * Notifies the tread lock that the USB setup is ready. 161 */ 162 private void openAccessory(UsbAccessory accessory) { 163 Log.d(TAG, "openAccessory: " + accessory); 164 mFileDescriptor = mUsbManager.openAccessory(accessory); 165 166 if (mFileDescriptor != null) { 167 mAccessory = accessory; 168 FileDescriptor fd = mFileDescriptor.getFileDescriptor(); 169 mOutputStream = new FileOutputStream(fd); 170 Log.d(TAG, "accessory opened"); 171 } else { 172 Log.d(TAG, "accessory open fail"); 173 } 174 175 // Unlocks the thread lock of waiting for the USB to be ready. 176 synchronized (mUsbSetup) { 177 mSetupReady = true; 178 Log.v(TAG, "Setup ready"); 179 mUsbSetup.notifyAll(); 180 } 181 } 182 183 /** 184 * Closes the ADK and detaches the output stream from it. 185 */ 186 private void closeAccessory() { 187 try { 188 if (mFileDescriptor != null) { 189 mFileDescriptor.close(); 190 } 191 } catch (IOException e) { 192 } finally { 193 mFileDescriptor = null; 194 mAccessory = null; 195 } 196 } 197 198 /** 199 * Constructs the AutoLockTest class, which can execute a series of tests 200 * to verify whether the device's Auto Exposure Lock is working properly. 201 * 202 * The test uses the LED lights on an ADK device as light source to change 203 * the lighting condition of the environment. The usb connection to the 204 * ADK board is established in the constructor. 205 * 206 * @param hostActivity pointer to the <code>CameraAnalyzerActivity</code> 207 * that instructs the Auto Lock Test 208 * @param mCamera pointer to the current camera instance 209 */ 210 private AutoLockTest(){ 211 super(); 212 } 213 214 public static synchronized AutoLockTest getSingletonTest() { 215 if (singletonTest == null) { 216 Log.v(TAG, "Creating a new AutoLockTest instance"); 217 singletonTest = new AutoLockTest(); 218 singletonTest.initializeTest(); 219 } 220 return singletonTest; 221 } 222 223 private void initializeTest() { 224 // Creates a native test handler with a 120x160 pixel debug output 225 mTestHandler = createAutoLockTest(); 226 mReferenceCompareResults = new ArrayList<Boolean>(); 227 mReferenceLogs = new ArrayList<String>(); 228 mNumTests = 4; 229 mTestResults = new int[mNumTests]; 230 for (int i = 0; i < mNumTests; ++i) { 231 mTestResults[i] = CameraTests.CAMERA_TEST_NOT_RUN; 232 } 233 } 234 235 public void updateCamera() {} 236 237 public void setActivity(CameraAnalyzerActivity hostActivity){ 238 if (mUsingUsb) { 239 closeConnection(); 240 } 241 242 mActivity = hostActivity; 243 244 mSetupReady = false; 245 246 Log.v(TAG, "Start to test ADK connection"); 247 // Starts to establish the connection to the ADK board. 248 mUsbManager = (UsbManager) mActivity.getSystemService(Context.USB_SERVICE); 249 mPermissionIntent = PendingIntent.getBroadcast(mActivity, 0, 250 new Intent(ACTION_USB_PERMISSION), 0); 251 IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); 252 filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED); 253 filter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED); 254 mActivity.registerReceiver(mUsbReceiver, filter); 255 256 if (mActivity.getLastNonConfigurationInstance() != null) { 257 mAccessory = (UsbAccessory) mActivity.getLastNonConfigurationInstance(); 258 Log.v(TAG, "Open acceossory 1"); 259 openAccessory(mAccessory); 260 } 261 262 // Skips the permission listener if the user already grants the ADK 263 // permission previously in the app. 264 UsbAccessory[] accessories = mUsbManager.getAccessoryList(); 265 UsbAccessory accessory = (accessories == null ? null : accessories[0]); 266 if (accessory != null) { 267 if (mUsbManager.hasPermission(accessory)) { 268 Log.v(TAG, "Open accessory 2"); 269 openAccessory(accessory); 270 } else { 271 synchronized (mUsbReceiver) { 272 if (!mPermissionRequestPending) { 273 mUsbManager.requestPermission(accessory, mPermissionIntent); 274 mPermissionRequestPending = true; 275 } 276 } 277 } 278 mUsingUsb = true; 279 } else { 280 Log.d(TAG, "accessory is null"); 281 mUsingUsb = false; 282 } 283 284 } 285 286 /** 287 * Closes the accessories and unregister the USB listener at the end of 288 * tests. 289 */ 290 public void closeConnection() { 291 closeAccessory(); 292 mActivity.unregisterReceiver(mUsbReceiver); 293 } 294 295 protected void finalize () { 296 if (mUsingUsb) { 297 closeConnection(); 298 } 299 } 300 301 /** 302 * Runs the Auto Lock tests. A total of 19 tests have been coded and 303 * included. Developers can freely comment out tests not interested. In 304 * the release version, all tests will be executed. 305 */ 306 @Override 307 public synchronized void run(int index){ 308 if (index == 0) { 309 for (int i = 1; i < mNumTests; ++i) { 310 run(i); 311 } 312 return; 313 } 314 315 Log.v(TAG, "AutoLockTest thread started!"); 316 317 if (mUsingUsb && (!mSetupReady)) { 318 // USB connection is not set up. Locks thread and wait. 319 Log.v(TAG, "Setup not ready, waiting"); 320 synchronized (mUsbSetup) { 321 try{ 322 Log.v(TAG, "Start waiting for Image"); 323 mUsbSetup.wait(); 324 } catch (InterruptedException e) { 325 Log.v(TAG, "Callback wait fails!"); 326 } 327 } 328 } 329 330 // Restarts the camera intance and attach the preview to the corrent 331 // UI elements. 332 restartCamera(); 333 startPreview(); 334 335 mTestCount = 0; 336 switch (index) { 337 case 1: 338 Log.v(TAG, "SP -> TP1 -> SP -> +1 -> Lock -> -1 -> TP2"); 339 test0(); 340 Log.v(TAG, "SP -> TP1 -> SP -> Lock -> +1 -> TP2 -> -1"); 341 test1(); 342 Log.v(TAG, "SP -> Lock -> +1 -> TP1 -> SP -> -1 -> Lock -> TP2"); 343 test2(); 344 Log.v(TAG, "SP -> Lock -> +1 -> TP1 -> SP -> Lock -> -1 -> TP2"); 345 test3(); 346 break; 347 case 2: 348 Log.v(TAG, "SP -> +1 -> TP1 -> -1 -> Lock -> SP -> TP2"); 349 test4(); 350 Log.v(TAG, "SP -> +1 -> TP1 -> Lock -> SP -> -1 -> TP2"); 351 test5(); 352 Log.v(TAG, "SP -> TP1 -> +1 -> Lock -> SP -> -1 -> TP2"); 353 test6(); 354 Log.v(TAG, "SP -> TP1 -> +1 -> Lock -> SP -> TP2"); 355 test7(); 356 Log.v(TAG, "SP -> TP1 -> Lock -> SP -> +1 -> TP2"); 357 test8(); 358 Log.v(TAG, "SP -> +1 -> Lock -> -1 -> TP1 -> Lock -> SP -> TP2"); 359 test9(); 360 Log.v(TAG, "SP -> +1 -> Lock -> TP1 -> -1 -> Lock -> SP -> TP2"); 361 test10(); 362 Log.v(TAG, "SP -> Lock -> TP1 -> +1 -> Lock -> SP -> -1 -> TP2"); 363 test11(); 364 break; 365 case 3: 366 Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> Restart -> Lock -> SP -> +1 -> TP2"); 367 test12(); 368 Log.v(TAG, "Restart -> Lock -> SP -> +1 -> TP1 -> -1 -> Lock -> SP -> TP2"); 369 test13(); 370 Log.v(TAG, "Restart -> Lock -> SP -> +1 -> TP1 -> Lock -> SP -> -1 -> TP2"); 371 test14(); 372 Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> +1 -> Lock -> SP -> -1 -> TP2"); 373 test15(); 374 Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> +1 -> Lock -> SP -> TP2"); 375 test16(); 376 Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> Lock -> SP -> +1 -> TP2"); 377 test17(); 378 Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> Lock -> SP -> TP2"); 379 test18(); 380 break; 381 default: 382 break; 383 } 384 385 releaseLock(); 386 387 Log.v(TAG, "Ready to process data"); 388 boolean[] testCompareResults = new boolean[2 * mTestCount]; 389 390 // Processes the data stored in the native test handler instance. 391 // Stores the test results into a boolean array. 392 processAutoLockTest(mTestHandler, testCompareResults); 393 394 // Prepares the test result text output with the booelan result array. 395 prepareDebugText(testCompareResults, index); 396 mReferenceCompareResults.clear(); 397 mReferenceLogs.clear(); 398 } 399 400 /** 401 * Compares two images taken under the same lighting, Image 1 without AE 402 * lock and Image 2 with AE locked under a bright light. Image 1 is 403 * expected to be brighter than Image 2. 404 * Tests whether AE lock works compared to no AE lock. 405 */ 406 private void test0() { 407 releaseLock(); 408 takePicture(); 409 startPreview(); 410 turnOnLight(); 411 setLock(); 412 turnOffLight(); 413 takePicture(); 414 startPreview(); 415 releaseLock(); 416 mReferenceCompareResults.add(true); 417 mReferenceCompareResults.add(false); 418 mReferenceLogs.add("Same lighting condition with one different lock"); 419 ++mTestCount; 420 } 421 422 /** 423 * Compares two images taken under different lighting, Image 1 without AE 424 * lock and Image 2 with with AE locked under the same light Image 1 is 425 * taken. Image 2 is taken under a bright light. Image 1 is expected to be 426 * darker than Image 2. 427 * Tests whether AE lock works compared to no AE lock. 428 */ 429 private void test1() { 430 releaseLock(); 431 takePicture(); 432 startPreview(); 433 setLock(); 434 turnOnLight(); 435 takePicture(); 436 turnOffLight(); 437 startPreview(); 438 releaseLock(); 439 mReferenceCompareResults.add(false); 440 mReferenceCompareResults.add(false); 441 mReferenceLogs.add("One same lock with different lighting"); 442 ++mTestCount; 443 } 444 445 /** 446 * Compares two images taken under different light, both with AE locked 447 * under the same lighting. Image 1 is taken under a brighter light. 448 * Image 1 is expected to be brighter than Image 2. 449 * Tests whether AE locks the exposure to the same level in the same 450 * lighting condition after preview restarts. 451 */ 452 private void test2() { 453 releaseLock(); 454 setLock(); 455 turnOnLight(); 456 takePicture(); 457 startPreview(); 458 turnOffLight(); 459 setLock(); 460 takePicture(); 461 startPreview(); 462 releaseLock(); 463 mReferenceCompareResults.add(true); 464 mReferenceCompareResults.add(false); 465 mReferenceLogs.add("Same locking locations with different lighting"); 466 ++mTestCount; 467 } 468 469 /** 470 * Compares two images taken under different light, Image 1 with AE locked 471 * under normal light and Image 2 with AE locked under a bright light. 472 * Image 1 is taken under a bright light and Image 2 is taken in the normal 473 * lighting. Image 1 is expected to be brighter than Image 2. 474 * Tests whether AE lock can adjust to change of lighting conditions. 475 */ 476 private void test3() { 477 releaseLock(); 478 setLock(); 479 turnOnLight(); 480 takePicture(); 481 startPreview(); 482 setLock(); 483 turnOffLight(); 484 takePicture(); 485 startPreview(); 486 releaseLock(); 487 mReferenceCompareResults.add(true); 488 mReferenceCompareResults.add(false); 489 mReferenceLogs.add("Different locking locations with different lighting"); 490 ++mTestCount; 491 } 492 493 /** 494 * Compares two images taken under different lighting, Image 1 without 495 * AE lock and Image 2 with AE lock set before camera preview resumes. 496 * Image 1 is taken under a bright light and the light is turned off before 497 * camera preview starts again. Image 1 is expected to be brighter than 498 * Image 2. 499 * Tests whether setting AE lock between camera preview stops and restarts 500 * can retain the exposure level of the previous AE-unlocked photo. 501 */ 502 private void test4() { 503 releaseLock(); 504 turnOnLight(); 505 takePicture(); 506 turnOffLight(); 507 setLock(); 508 startPreview(); 509 takePicture(); 510 startPreview(); 511 releaseLock(); 512 mReferenceCompareResults.add(true); 513 mReferenceCompareResults.add(false); 514 mReferenceLogs.add("Lock after takePicture and light change, before preview"); 515 ++mTestCount; 516 } 517 518 /** 519 * Compares two images taken under different lighting, Image 1 without 520 * AE lock and Image 2 with AE lock set before camera preview resumes. 521 * Image 1 is taken under a bright light and the light is turned off after 522 * preview restars but before Image 2 is taken. Image 1 is expected to be 523 * brighter than Image 2. 524 * Tests whether setting AE lock between camera preview stops and restarts 525 * can retain the exposure level of the previous AE-unlocked photo. 526 */ 527 private void test5() { 528 releaseLock(); 529 turnOnLight(); 530 takePicture(); 531 setLock(); 532 startPreview(); 533 turnOffLight(); 534 takePicture(); 535 startPreview(); 536 releaseLock(); 537 mReferenceCompareResults.add(true); 538 mReferenceCompareResults.add(false); 539 mReferenceLogs.add("Lock between takePicture and light change, w/o light change"); 540 ++mTestCount; 541 } 542 543 private void test6() { 544 releaseLock(); 545 takePicture(); 546 turnOnLight(); 547 setLock(); 548 startPreview(); 549 turnOffLight(); 550 takePicture(); 551 startPreview(); 552 releaseLock(); 553 mReferenceCompareResults.add(false); 554 mReferenceCompareResults.add(true); 555 mReferenceLogs.add("Lock after takePicture and light change, before preview."); 556 ++mTestCount; 557 } 558 559 private void test7() { 560 releaseLock(); 561 takePicture(); 562 turnOnLight(); 563 setLock(); 564 startPreview(); 565 takePicture(); 566 startPreview(); 567 releaseLock(); 568 turnOffLight(); 569 mReferenceCompareResults.add(false); 570 mReferenceCompareResults.add(false); 571 mReferenceLogs.add("Lock after takePicture and light change, before preview."); 572 ++mTestCount; 573 } 574 575 private void test8() { 576 releaseLock(); 577 takePicture(); 578 setLock(); 579 startPreview(); 580 turnOnLight(); 581 takePicture(); 582 startPreview(); 583 releaseLock(); 584 turnOffLight(); 585 mReferenceCompareResults.add(false); 586 mReferenceCompareResults.add(false); 587 mReferenceLogs.add("Lock after takePicture and before startPreview."); 588 ++mTestCount; 589 } 590 591 private void test9() { 592 releaseLock(); 593 turnOnLight(); 594 setLock(); 595 turnOffLight(); 596 takePicture(); 597 setLock(); 598 startPreview(); 599 takePicture(); 600 releaseLock(); 601 startPreview(); 602 mReferenceCompareResults.add(false); 603 mReferenceCompareResults.add(true); 604 mReferenceLogs.add("Lock after first lock with changing light"); 605 ++mTestCount; 606 } 607 608 private void test10() { 609 releaseLock(); 610 turnOnLight(); 611 setLock(); 612 takePicture(); 613 turnOffLight(); 614 setLock(); 615 startPreview(); 616 takePicture(); 617 releaseLock(); 618 startPreview(); 619 mReferenceCompareResults.add(true); 620 mReferenceCompareResults.add(false); 621 mReferenceLogs.add("Lock after first lock with changing light"); 622 ++mTestCount; 623 } 624 625 private void test11() { 626 releaseLock(); 627 setLock(); 628 takePicture(); 629 turnOnLight(); 630 setLock(); 631 startPreview(); 632 turnOffLight(); 633 takePicture(); 634 releaseLock(); 635 startPreview(); 636 mReferenceCompareResults.add(false); 637 mReferenceCompareResults.add(true); 638 mReferenceLogs.add("Lock after first lock with changing light"); 639 ++mTestCount; 640 } 641 642 private void test12() { 643 //"Restart -> Lock -> SP -> TP1 -> Restart -> Lock -> SP -> +1 -> TP2" 644 restartCamera(); 645 setLock(); 646 startPreview(); 647 takePicture(); 648 releaseLock(); 649 restartCamera(); 650 setLock(); 651 startPreview(); 652 turnOnLight(); 653 takePicture(); 654 releaseLock(); 655 turnOffLight(); 656 startPreview(); 657 //mTestCamera.release(); 658 mReferenceCompareResults.add(false); 659 mReferenceCompareResults.add(false); 660 mReferenceLogs.add("Lock before first preview"); 661 ++mTestCount; 662 } 663 664 private void test13() { 665 //"Restart -> Lock -> SP -> +1 -> TP1 -> -1 -> Lock -> SP -> TP2" 666 restartCamera(); 667 setLock(); 668 startPreview(); 669 turnOnLight(); 670 takePicture(); 671 turnOffLight(); 672 setLock(); 673 startPreview(); 674 takePicture(); 675 releaseLock(); 676 startPreview(); 677 mReferenceCompareResults.add(true); 678 mReferenceCompareResults.add(false); 679 mReferenceLogs.add("Lock after first lock with changing light"); 680 ++mTestCount; 681 } 682 683 private void test14() { 684 //"Restart -> Lock -> SP -> +1 -> TP1 -> Lock -> SP -> -1 -> TP2" 685 restartCamera(); 686 setLock(); 687 startPreview(); 688 turnOnLight(); 689 takePicture(); 690 setLock(); 691 startPreview(); 692 turnOffLight(); 693 takePicture(); 694 releaseLock(); 695 startPreview(); 696 mReferenceCompareResults.add(true); 697 mReferenceCompareResults.add(false); 698 mReferenceLogs.add("Lock after first lock with changing light"); 699 ++mTestCount; 700 } 701 702 private void test15() { 703 //"Restart -> Lock -> SP -> TP1 -> +1 -> Lock -> SP -> -1 -> TP2" 704 restartCamera(); 705 setLock(); 706 startPreview(); 707 takePicture(); 708 turnOnLight(); 709 setLock(); 710 startPreview(); 711 turnOffLight(); 712 takePicture(); 713 releaseLock(); 714 startPreview(); 715 mReferenceCompareResults.add(false); 716 mReferenceCompareResults.add(true); 717 mReferenceLogs.add("Lock after first lock with changing light"); 718 ++mTestCount; 719 } 720 721 private void test16() { 722 //"Restart -> Lock -> SP -> TP1 -> +1 -> Lock -> SP -> TP2" 723 restartCamera(); 724 setLock(); 725 startPreview(); 726 takePicture(); 727 turnOnLight(); 728 setLock(); 729 startPreview(); 730 takePicture(); 731 turnOffLight(); 732 releaseLock(); 733 startPreview(); 734 mReferenceCompareResults.add(false); 735 mReferenceCompareResults.add(false); 736 mReferenceLogs.add("Lock after first lock with changing light"); 737 ++mTestCount; 738 } 739 740 private void test17() { 741 //"Restart -> Lock -> SP -> TP1 -> Lock -> SP -> +1 -> TP2" 742 restartCamera(); 743 setLock(); 744 startPreview(); 745 takePicture(); 746 setLock(); 747 startPreview(); 748 turnOnLight(); 749 takePicture(); 750 turnOffLight(); 751 releaseLock(); 752 startPreview(); 753 mReferenceCompareResults.add(false); 754 mReferenceCompareResults.add(false); 755 mReferenceLogs.add("Lock after first lock with changing light"); 756 ++mTestCount; 757 } 758 759 private void test18() { 760 //"Restart -> Lock -> SP -> TP1 -> Lock -> SP -> TP2" 761 restartCamera(); 762 setLock(); 763 startPreview(); 764 takePicture(); 765 setLock(); 766 startPreview(); 767 takePicture(); 768 releaseLock(); 769 startPreview(); 770 mReferenceCompareResults.add(false); 771 mReferenceCompareResults.add(true); 772 mReferenceLogs.add("Lock after first lock with changing light"); 773 ++mTestCount; 774 } 775 776 /** 777 * Restarts the camera by releasing the current instance and get a new 778 * instance. Also connects this new camera instance's preview to the proper 779 * UI surfaceview. 780 */ 781 private void restartCamera() { 782 Log.v(TAG, "Restarting Camera"); 783 784 mTestCamera.release(); 785 Log.v(TAG, "Camera released"); 786 787 try { 788 mTestCamera = Camera.open(mActivity.getCameraIdx()); 789 } catch (RuntimeException e) { 790 throw new RuntimeException("Failed to open the camera", e); 791 } 792 793 Camera.Parameters params = mTestCamera.getParameters(); 794 params.setPictureFormat(ImageFormat.JPEG); 795 params.setPictureSize(640, 480); 796 mTestCamera.setParameters(params); 797 798 try { 799 mTestCamera.setPreviewDisplay(super.getCameraView().getHolder()); 800 } catch (IOException e) { 801 throw new RuntimeException("Unable to connect camera to display: " + e); 802 } 803 } 804 805 /** 806 * Starts Camera preview with a delay of 2 seconds to let it adjust to 807 * the lighting condition. 808 */ 809 private void startPreview() { 810 mTestCamera.startPreview(); 811 try{ 812 Log.v(TAG, "Waiting"); 813 Thread.sleep(2000); 814 Log.v(TAG, "END Waiting"); 815 } catch (InterruptedException e){} 816 } 817 818 /** 819 * Sends command to ADK to turn on all the LED lights to white. 820 * Waits for 4 seconds for the camera to adjust to the new lighting. 821 */ 822 private void turnOnLight() { 823 Log.v(TAG, "Turn on light"); 824 if (mUsingUsb) { 825 byte[] buffer = new byte[3]; 826 827 buffer[0] = (byte) 3; 828 buffer[1] = (byte) 0; 829 buffer[2] = (byte) 1; 830 if (mOutputStream != null && buffer[1] != -1) { 831 try { 832 mOutputStream.write(buffer); 833 } catch (IOException e) { 834 Log.e(TAG, "write failed", e); 835 } 836 } 837 } else { 838 mActivity.runOnUiThread(new Runnable() { 839 public void run() { 840 Toast.makeText(mActivity.getApplicationContext(), "Turn on light!", 4).show(); 841 842 } 843 }); 844 } 845 846 try{ 847 Log.v(TAG, "Waiting, Please Turn on light"); 848 Thread.sleep(LONG_SLEEP); 849 Log.v(TAG, "END Waiting"); 850 } catch (InterruptedException e){} 851 } 852 853 /** 854 * Sends command to ADK to turn off all LED lights. 855 * Waits for 4 seconds for the camera to adjust to the new lighting. 856 */ 857 private void turnOffLight() { 858 Log.v(TAG, "Turn off light"); 859 if (mUsingUsb) { 860 byte[] buffer = new byte[3]; 861 862 buffer[0] = (byte) 3; 863 buffer[1] = (byte) 0; 864 buffer[2] = (byte) 0; 865 if (mOutputStream != null && buffer[1] != -1) { 866 try { 867 mOutputStream.write(buffer); 868 } catch (IOException e) { 869 Log.e(TAG, "write failed", e); 870 } 871 } 872 } else { 873 mActivity.runOnUiThread(new Runnable() { 874 public void run() { 875 Toast.makeText(mActivity.getApplicationContext(), "Turn off light!", 4).show(); 876 877 } 878 }); 879 } 880 881 try{ 882 Log.v(TAG, "Waiting, Please Turn off light"); 883 Thread.sleep(LONG_SLEEP); 884 Log.v(TAG, "END Waiting"); 885 } catch (InterruptedException e){} 886 } 887 888 /** 889 * Sets the Auto Exposure Lock. 890 * Waits for 2 seonds for the lock to function. 891 */ 892 private void setLock() { 893 Camera.Parameters params = mTestCamera.getParameters(); 894 895 params.setAutoExposureLock(true); 896 params.setAutoWhiteBalanceLock(true); 897 mTestCamera.setParameters(params); 898 try{ 899 Log.v(TAG, "Waiting to set lock"); 900 Thread.sleep(2000); 901 Log.v(TAG, "END Waiting"); 902 } catch (InterruptedException e){} 903 } 904 905 /** 906 * Releases the Auto Exposure Lock. 907 * Waits for 4 seconds afterwards for the Auto Exposure to be adjusted 908 * to the lighting condition. 909 */ 910 private void releaseLock() { 911 Camera.Parameters params = mTestCamera.getParameters(); 912 913 params.setAutoExposureLock(false); 914 params.setAutoWhiteBalanceLock(false); 915 mTestCamera.setParameters(params); 916 try{ 917 Log.v(TAG, "Waiting to release lock"); 918 Thread.sleep(LONG_SLEEP); 919 Log.v(TAG, "END Waiting"); 920 } catch (InterruptedException e){} 921 922 } 923 924 /** 925 * Takes a picture and locks thread until the picture callback finishes. 926 */ 927 private void takePicture(){ 928 mTestCamera.takePicture(null, null, null, mTestJpegListener); 929 930 synchronized (mProcessingImage) { 931 try{ 932 Log.v(TAG, "Start waiting for Image"); 933 // System.gc(); 934 mProcessingImage.wait(); 935 } catch (InterruptedException e){ 936 Log.v(TAG, "Callback wait fails!"); 937 } 938 } 939 } 940 941 /** 942 * Prepare for the result to be shown in the UI. The result for each single 943 * test is shown in green if it matches the reference result. It is shown 944 * in red otherwise. 945 */ 946 private void prepareDebugText(boolean[] testCompareResults, int index) { 947 boolean groupTestPassed = true; 948 for (int i = 0; i < mTestCount; ++i) { 949 String testLog; 950 boolean testPassed = true; 951 testLog = mReferenceLogs.get(i); 952 mDebugText += (testLog + "<br/>"); 953 954 if (testCompareResults[i * 2] == mReferenceCompareResults.get(i * 2)) { 955 mDebugText += String.format( 956 "Picture 1 brighter than Picture 2 is %b \n", 957 testCompareResults[i * 2]); 958 } else { 959 mDebugText += String.format( 960 "Picture 1 brighter than Picture 2 is %b \n", 961 testCompareResults[i * 2]); 962 testPassed = false; 963 } 964 965 if (testCompareResults[i * 2 + 1] == mReferenceCompareResults.get(i * 2 + 1)) { 966 mDebugText += String.format( 967 "Picture 1 is equivalent to Picture 2 is %b \n", 968 testCompareResults[i * 2 + 1]); 969 } else { 970 mDebugText += String.format( 971 "Picture 1 is equivalent to Picture 2 is %b \n", 972 testCompareResults[i * 2 + 1]); 973 testPassed = false; 974 } 975 976 if (testPassed) { 977 mDebugText += "Test passed! \n"; 978 } else { 979 mDebugText += "Test failed! \n"; 980 groupTestPassed = false; 981 } 982 } 983 if (groupTestPassed) { 984 mTestResults[index] = CameraTests.CAMERA_TEST_SUCCESS; 985 } else { 986 mTestResults[index] = CameraTests.CAMERA_TEST_FAILURE; 987 } 988 } 989 990 /** 991 * Clears the debug text so that new test results can be added. 992 */ 993 public void clearDebugText() { 994 mDebugText = ""; 995 } 996 997 @Override 998 public String getDebugText() { 999 return mDebugText; 1000 } 1001 1002 @Override 1003 public String getResultText() { 1004 return mDebugText; 1005 } 1006 1007 @Override 1008 public String getTestName() { 1009 return "Auto Exposure Lock test: \n"; 1010 } 1011 1012 @Override 1013 public String getTestName(int index) { 1014 switch (index) { 1015 case 0: 1016 return "Run all tests"; 1017 case 1: 1018 return "Compulsory tests"; 1019 case 2: 1020 return "Recommended tests (preview behavior)"; 1021 case 3: 1022 return "Optional tests (default lock)"; 1023 default: 1024 return ""; 1025 } 1026 } 1027 1028 @Override 1029 public int getResult(int index) { 1030 return mTestResults[index]; 1031 } 1032 1033 @Override 1034 public int getNumTests() { 1035 return mNumTests; 1036 } 1037 1038 private Camera.PictureCallback mTestJpegListener = new Camera.PictureCallback() { 1039 public void onPictureTaken(byte[] data, Camera mCamera) { 1040 Log.v(TAG, "Shutter pressed down!"); 1041 Bitmap inputImage; 1042 1043 // Decodes the camera input data into Bitmap. 1044 // Constructs a native image class with the image. 1045 inputImage = BitmapFactory.decodeByteArray(data, 0, data.length); 1046 long bufferAddress = findNative(inputImage); 1047 Log.v(TAG, "findNative method finishes"); 1048 1049 // Cleans up memory taken by the Bitmap. 1050 data = null; 1051 inputImage.recycle(); 1052 inputImage = null; 1053 System.gc(); 1054 1055 // Passes data from the native image class to the native 1056 // test handler. 1057 createAutoLockClass(bufferAddress, mTestHandler, 1058 getCheckerCenter(), getCheckerRadius()); 1059 1060 // Unlocks the thread lock. 1061 synchronized (mProcessingImage) { 1062 mProcessingImage.notifyAll(); 1063 } 1064 } 1065 }; 1066 1067 private native long createAutoLockTest(); 1068 1069 private native void createAutoLockClass(long bufferAddress, long handlerAddress, 1070 long checkerCenterAddress, 1071 long checkerRadiusAddress); 1072 1073 private native void processAutoLockTest(long handlerAddress, boolean[] testCompareResults); 1074 1075 static { 1076 System.loadLibrary("cameraanalyzer"); 1077 } 1078 } 1079