• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
openAccessory(UsbAccessory accessory)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      */
closeAccessory()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      */
AutoLockTest()210     private AutoLockTest(){
211         super();
212     }
213 
getSingletonTest()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 
initializeTest()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 
updateCamera()235     public void updateCamera() {}
236 
setActivity(CameraAnalyzerActivity hostActivity)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      */
closeConnection()290     public void closeConnection() {
291         closeAccessory();
292         mActivity.unregisterReceiver(mUsbReceiver);
293     }
294 
finalize()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
run(int index)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      */
test0()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      */
test1()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      */
test2()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      */
test3()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      */
test4()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      */
test5()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 
test6()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 
test7()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 
test8()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 
test9()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 
test10()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 
test11()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 
test12()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 
test13()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 
test14()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 
test15()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 
test16()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 
test17()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 
test18()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      */
restartCamera()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      */
startPreview()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      */
turnOnLight()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      */
turnOffLight()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      */
setLock()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      */
releaseLock()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      */
takePicture()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      */
prepareDebugText(boolean[] testCompareResults, int index)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      */
clearDebugText()993     public void clearDebugText() {
994         mDebugText = "";
995     }
996 
997     @Override
getDebugText()998     public String getDebugText() {
999         return mDebugText;
1000     }
1001 
1002     @Override
getResultText()1003     public String getResultText() {
1004         return mDebugText;
1005     }
1006 
1007     @Override
getTestName()1008     public String getTestName() {
1009         return "Auto Exposure Lock test: \n";
1010     }
1011 
1012     @Override
getTestName(int index)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
getResult(int index)1029     public int getResult(int index) {
1030         return mTestResults[index];
1031     }
1032 
1033     @Override
getNumTests()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 
createAutoLockTest()1067     private native long createAutoLockTest();
1068 
createAutoLockClass(long bufferAddress, long handlerAddress, long checkerCenterAddress, long checkerRadiusAddress)1069     private native void createAutoLockClass(long bufferAddress, long handlerAddress,
1070                                             long checkerCenterAddress,
1071                                             long checkerRadiusAddress);
1072 
processAutoLockTest(long handlerAddress, boolean[] testCompareResults)1073     private native void processAutoLockTest(long handlerAddress, boolean[] testCompareResults);
1074 
1075     static {
1076         System.loadLibrary("cameraanalyzer");
1077     }
1078 }
1079