Home | History | Annotate | Download | only in flashlight
      1 /*
      2  * Copyright 2015 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.flashlight;
     18 
     19 import com.android.cts.verifier.PassFailButtons;
     20 import com.android.cts.verifier.R;
     21 
     22 import android.content.Context;
     23 import android.hardware.camera2.CameraManager;
     24 import android.hardware.camera2.CameraCharacteristics;
     25 import android.os.Bundle;
     26 import android.os.Handler;
     27 import android.util.Log;
     28 import android.view.View;
     29 import android.widget.Button;
     30 import android.widget.TextView;
     31 
     32 import java.util.HashSet;
     33 import java.util.HashMap;
     34 
     35 /**
     36  * This test checks the flashlight functionality by turning on and off the flashlight. After it
     37  * turns on or off the flashlight, it asks for user input to verify the flashlight status. The
     38  * test will pass when the user input is correct for all camera devices with a flash unit.
     39  */
     40 public class CameraFlashlightActivity extends PassFailButtons.Activity {
     41 
     42     private static final String TAG = "CameraFlashlight";
     43 
     44     private CameraManager mCameraManager;
     45     private TestState mTestState;
     46     private final HashSet<String> mPendingCameraIds = new HashSet<>();
     47     private String mCurrentCameraId;
     48 
     49     private Button mInstructionButton;
     50     private Button mOnButton;
     51     private Button mOffButton;
     52     private TextView mInstructionTextView;
     53     private final HashSet<View> mAllButtons = new HashSet<>();
     54     // TestState -> enabled buttons
     55     private final HashMap<TestState, HashSet<View>> mStateButtonsMap = new HashMap<>();
     56 
     57     private enum TestState {
     58         NOT_STARTED,
     59         TESTING_ON,
     60         WAITING_ON_CALLBACK_ON,
     61         RESPONDED_ON_CORRECTLY,
     62         WAITING_ON_CALLBACK_OFF,
     63         TESTING_OFF,
     64         RESPONDED_OFF_CORRECTLY,
     65         ALL_PASSED,
     66         FAILED
     67     }
     68 
     69     private final View.OnClickListener mInstructionButtonListener = new View.OnClickListener() {
     70         @Override
     71         public void onClick(View v) {
     72             switch (mTestState) {
     73                 case NOT_STARTED:
     74                     // Start testing turning on the first camera's flashlight.
     75                     // Fall through.
     76                 case RESPONDED_OFF_CORRECTLY:
     77                     // Current camera passed. Start testing turning on next camera's flashlight.
     78                     if (mPendingCameraIds.size() == 0) {
     79                         // Passed
     80                         mTestState = TestState.ALL_PASSED;
     81                         updateButtonsAndInstructionLocked();
     82                         return;
     83                     }
     84 
     85                     mCurrentCameraId = (String)mPendingCameraIds.toArray()[0];
     86                     mPendingCameraIds.remove(mCurrentCameraId);
     87 
     88                     try {
     89                         mCameraManager.setTorchMode(mCurrentCameraId, true);
     90                         mTestState = TestState.WAITING_ON_CALLBACK_ON;
     91                     } catch (Exception e) {
     92                         e.printStackTrace();
     93                         mTestState = TestState.FAILED;
     94                     }
     95                     break;
     96 
     97                 case RESPONDED_ON_CORRECTLY:
     98                     // Flashlight is on and user responded correctly.
     99                     // Turning off the flashlight.
    100                     try {
    101                         mCameraManager.setTorchMode(mCurrentCameraId, false);
    102                         mTestState = TestState.WAITING_ON_CALLBACK_OFF;
    103                     } catch (Exception e) {
    104                         e.printStackTrace();
    105                         mTestState = TestState.FAILED;
    106                     }
    107                     break;
    108 
    109                 case FAILED:
    110                     // The test failed, report failure.
    111                     if (mCurrentCameraId != null) {
    112                         try {
    113                             mCameraManager.setTorchMode(mCurrentCameraId, false);
    114                         } catch (Exception e) {
    115                             e.printStackTrace();
    116                             Log.e(TAG, "Test failed but cannot turn off the torch");
    117                         }
    118                     }
    119                     setTestResultAndFinish(false);
    120                     break;
    121 
    122                 case ALL_PASSED:
    123                     // The test passed, report pass.
    124                     setTestResultAndFinish(true);
    125                     break;
    126             }
    127 
    128             updateButtonsAndInstructionLocked();
    129         }
    130     };
    131 
    132     private final View.OnClickListener mOnButtonListener = new View.OnClickListener() {
    133         @Override
    134         public void onClick(View v) {
    135             // Check if user responded correctly.
    136             if (mTestState == TestState.TESTING_ON) {
    137                 mTestState = TestState.RESPONDED_ON_CORRECTLY;
    138             } else {
    139                 mTestState = TestState.FAILED;
    140             }
    141             updateButtonsAndInstructionLocked();
    142         }
    143     };
    144 
    145     private final View.OnClickListener mOffButtonListener = new View.OnClickListener() {
    146         @Override
    147         public void onClick(View v) {
    148             // Check if user responded correctly.
    149             if (mTestState == TestState.TESTING_OFF) {
    150                 mTestState = TestState.RESPONDED_OFF_CORRECTLY;
    151             } else {
    152                 mTestState = TestState.FAILED;
    153             }
    154             updateButtonsAndInstructionLocked();
    155         }
    156     };
    157 
    158     private final CameraManager.TorchCallback mTorchCallback = new CameraManager.TorchCallback() {
    159         @Override
    160         public void onTorchModeChanged(String cameraId, boolean enabled) {
    161             if (!cameraId.equals(mCurrentCameraId)) {
    162                 return;
    163             }
    164 
    165             // Move to next state after receiving the expected callback.
    166             if (mTestState == TestState.WAITING_ON_CALLBACK_ON && enabled) {
    167                 mTestState = TestState.TESTING_ON;
    168             } else if (mTestState == TestState.WAITING_ON_CALLBACK_OFF && !enabled) {
    169                 mTestState = TestState.TESTING_OFF;
    170             }
    171             updateButtonsAndInstructionLocked();
    172         }
    173     };
    174 
    175     @Override
    176     protected void onCreate(Bundle savedInstanceState) {
    177         super.onCreate(savedInstanceState);
    178 
    179         // initialize state -> buttons map
    180         for (TestState state : TestState.values()) {
    181             mStateButtonsMap.put(state, new HashSet<View>());
    182         }
    183 
    184         mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    185 
    186         try {
    187             String[] cameraIds = mCameraManager.getCameraIdList();
    188             for (String id : cameraIds) {
    189                 CameraCharacteristics info = mCameraManager.getCameraCharacteristics(id);
    190                 if (info.get(CameraCharacteristics.FLASH_INFO_AVAILABLE).booleanValue() ==
    191                         true) {
    192                     mPendingCameraIds.add(id);
    193                 }
    194             }
    195             mCameraManager.registerTorchCallback(mTorchCallback, new Handler());
    196         } catch (Exception e) {
    197             e.printStackTrace();
    198             mTestState = TestState.FAILED;
    199             updateButtonsAndInstructionLocked();
    200             return;
    201         }
    202 
    203         // Setup the UI.
    204         setContentView(R.layout.camera_flashlight);
    205         setPassFailButtonClickListeners();
    206         setInfoResources(R.string.camera_flashlight_test, R.string.camera_flashlight_info, -1);
    207 
    208         mInstructionTextView = (TextView) findViewById(R.id.flash_instruction_text);
    209 
    210         // Get the buttons and attach the listener.
    211         mInstructionButton = (Button) findViewById(R.id.flash_instruction_button);
    212         mInstructionButton.setOnClickListener(mInstructionButtonListener);
    213         mStateButtonsMap.get(TestState.NOT_STARTED).add(mInstructionButton);
    214         mStateButtonsMap.get(TestState.RESPONDED_ON_CORRECTLY).add(mInstructionButton);
    215         mStateButtonsMap.get(TestState.RESPONDED_OFF_CORRECTLY).add(mInstructionButton);
    216         mStateButtonsMap.get(TestState.ALL_PASSED).add(mInstructionButton);
    217         mStateButtonsMap.get(TestState.FAILED).add(mInstructionButton);
    218         mAllButtons.add(mInstructionButton);
    219 
    220         mOnButton = (Button) findViewById(R.id.flash_on_button);
    221         mOnButton.setOnClickListener(mOnButtonListener);
    222         mStateButtonsMap.get(TestState.TESTING_ON).add(mOnButton);
    223         mStateButtonsMap.get(TestState.TESTING_OFF).add(mOnButton);
    224         mAllButtons.add(mOnButton);
    225 
    226         mOffButton = (Button) findViewById(R.id.flash_off_button);
    227         mOffButton.setOnClickListener(mOffButtonListener);
    228         mStateButtonsMap.get(TestState.TESTING_ON).add(mOffButton);
    229         mStateButtonsMap.get(TestState.TESTING_OFF).add(mOffButton);
    230         mAllButtons.add(mOffButton);
    231 
    232         View passButton = getPassButton();
    233         mStateButtonsMap.get(TestState.ALL_PASSED).add(passButton);
    234         mAllButtons.add(passButton);
    235 
    236         mTestState = TestState.NOT_STARTED;
    237         updateButtonsAndInstructionLocked();
    238     }
    239 
    240 
    241     private void updateButtonsAndInstructionLocked() {
    242         for (View v : mAllButtons) {
    243             v.setEnabled(false);
    244         }
    245 
    246         // Only enable the buttons for this state.
    247         HashSet<View> views = mStateButtonsMap.get(mTestState);
    248         for (View v : views) {
    249             v.setEnabled(true);
    250         }
    251 
    252         switch (mTestState) {
    253             case TESTING_ON:
    254             case TESTING_OFF:
    255                 mInstructionTextView.setText(String.format(
    256                         getString(R.string.camera_flashlight_question_text), mCurrentCameraId));
    257                 break;
    258             case RESPONDED_ON_CORRECTLY:
    259             case RESPONDED_OFF_CORRECTLY:
    260                 mInstructionTextView.setText(R.string.camera_flashlight_next_text);
    261                 mInstructionButton.setText(R.string.camera_flashlight_next_button);
    262                 break;
    263             case FAILED:
    264                 mInstructionTextView.setText(R.string.camera_flashlight_failed_text);
    265                 mInstructionButton.setText(R.string.camera_flashlight_done_button);
    266                 break;
    267             case ALL_PASSED:
    268                 mInstructionTextView.setText(R.string.camera_flashlight_passed_text);
    269                 mInstructionButton.setText(R.string.camera_flashlight_done_button);
    270                 break;
    271             default:
    272                 break;
    273         }
    274     }
    275 }
    276