blob: 4d37b3eecf3e8713d582b8d21571549e57a6b75b [file] [log] [blame]
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.verifier.camera.flashlight;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
import android.content.Context;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraCharacteristics;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.HashSet;
import java.util.HashMap;
/**
* This test checks the flashlight functionality by turning on and off the flashlight. After it
* turns on or off the flashlight, it asks for user input to verify the flashlight status. The
* test will pass when the user input is correct for all camera devices with a flash unit.
*/
public class CameraFlashlightActivity extends PassFailButtons.Activity {
private static final String TAG = "CameraFlashlight";
private CameraManager mCameraManager;
private TestState mTestState;
private final HashSet<String> mPendingCameraIds = new HashSet<>();
private String mCurrentCameraId;
private Button mInstructionButton;
private Button mOnButton;
private Button mOffButton;
private TextView mInstructionTextView;
private final HashSet<View> mAllButtons = new HashSet<>();
// TestState -> enabled buttons
private final HashMap<TestState, HashSet<View>> mStateButtonsMap = new HashMap<>();
private enum TestState {
NOT_STARTED,
TESTING_ON,
WAITING_ON_CALLBACK_ON,
RESPONDED_ON_CORRECTLY,
WAITING_ON_CALLBACK_OFF,
TESTING_OFF,
RESPONDED_OFF_CORRECTLY,
ALL_PASSED,
FAILED
}
private final View.OnClickListener mInstructionButtonListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (mTestState) {
case NOT_STARTED:
// Start testing turning on the first camera's flashlight.
// Fall through.
case RESPONDED_OFF_CORRECTLY:
// Current camera passed. Start testing turning on next camera's flashlight.
if (mPendingCameraIds.size() == 0) {
// Passed
mTestState = TestState.ALL_PASSED;
updateButtonsAndInstructionLocked();
return;
}
mCurrentCameraId = (String)mPendingCameraIds.toArray()[0];
mPendingCameraIds.remove(mCurrentCameraId);
try {
mCameraManager.setTorchMode(mCurrentCameraId, true);
mTestState = TestState.WAITING_ON_CALLBACK_ON;
} catch (Exception e) {
e.printStackTrace();
mTestState = TestState.FAILED;
}
break;
case RESPONDED_ON_CORRECTLY:
// Flashlight is on and user responded correctly.
// Turning off the flashlight.
try {
mCameraManager.setTorchMode(mCurrentCameraId, false);
mTestState = TestState.WAITING_ON_CALLBACK_OFF;
} catch (Exception e) {
e.printStackTrace();
mTestState = TestState.FAILED;
}
break;
case FAILED:
// The test failed, report failure.
if (mCurrentCameraId != null) {
try {
mCameraManager.setTorchMode(mCurrentCameraId, false);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Test failed but cannot turn off the torch");
}
}
setTestResultAndFinish(false);
break;
case ALL_PASSED:
// The test passed, report pass.
setTestResultAndFinish(true);
break;
}
updateButtonsAndInstructionLocked();
}
};
private final View.OnClickListener mOnButtonListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// Check if user responded correctly.
if (mTestState == TestState.TESTING_ON) {
mTestState = TestState.RESPONDED_ON_CORRECTLY;
} else {
mTestState = TestState.FAILED;
}
updateButtonsAndInstructionLocked();
}
};
private final View.OnClickListener mOffButtonListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// Check if user responded correctly.
if (mTestState == TestState.TESTING_OFF) {
mTestState = TestState.RESPONDED_OFF_CORRECTLY;
} else {
mTestState = TestState.FAILED;
}
updateButtonsAndInstructionLocked();
}
};
private final CameraManager.TorchCallback mTorchCallback = new CameraManager.TorchCallback() {
@Override
public void onTorchModeChanged(String cameraId, boolean enabled) {
if (!cameraId.equals(mCurrentCameraId)) {
return;
}
// Move to next state after receiving the expected callback.
if (mTestState == TestState.WAITING_ON_CALLBACK_ON && enabled) {
mTestState = TestState.TESTING_ON;
} else if (mTestState == TestState.WAITING_ON_CALLBACK_OFF && !enabled) {
mTestState = TestState.TESTING_OFF;
}
updateButtonsAndInstructionLocked();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// initialize state -> buttons map
for (TestState state : TestState.values()) {
mStateButtonsMap.put(state, new HashSet<View>());
}
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
String[] cameraIds = mCameraManager.getCameraIdList();
for (String id : cameraIds) {
CameraCharacteristics info = mCameraManager.getCameraCharacteristics(id);
if (info.get(CameraCharacteristics.FLASH_INFO_AVAILABLE).booleanValue() ==
true) {
mPendingCameraIds.add(id);
}
}
mCameraManager.registerTorchCallback(mTorchCallback, new Handler());
} catch (Exception e) {
e.printStackTrace();
mTestState = TestState.FAILED;
updateButtonsAndInstructionLocked();
return;
}
// Setup the UI.
setContentView(R.layout.camera_flashlight);
setPassFailButtonClickListeners();
setInfoResources(R.string.camera_flashlight_test, R.string.camera_flashlight_info, -1);
mInstructionTextView = (TextView) findViewById(R.id.flash_instruction_text);
// Get the buttons and attach the listener.
mInstructionButton = (Button) findViewById(R.id.flash_instruction_button);
mInstructionButton.setOnClickListener(mInstructionButtonListener);
mStateButtonsMap.get(TestState.NOT_STARTED).add(mInstructionButton);
mStateButtonsMap.get(TestState.RESPONDED_ON_CORRECTLY).add(mInstructionButton);
mStateButtonsMap.get(TestState.RESPONDED_OFF_CORRECTLY).add(mInstructionButton);
mStateButtonsMap.get(TestState.ALL_PASSED).add(mInstructionButton);
mStateButtonsMap.get(TestState.FAILED).add(mInstructionButton);
mAllButtons.add(mInstructionButton);
mOnButton = (Button) findViewById(R.id.flash_on_button);
mOnButton.setOnClickListener(mOnButtonListener);
mStateButtonsMap.get(TestState.TESTING_ON).add(mOnButton);
mStateButtonsMap.get(TestState.TESTING_OFF).add(mOnButton);
mAllButtons.add(mOnButton);
mOffButton = (Button) findViewById(R.id.flash_off_button);
mOffButton.setOnClickListener(mOffButtonListener);
mStateButtonsMap.get(TestState.TESTING_ON).add(mOffButton);
mStateButtonsMap.get(TestState.TESTING_OFF).add(mOffButton);
mAllButtons.add(mOffButton);
View passButton = getPassButton();
mStateButtonsMap.get(TestState.ALL_PASSED).add(passButton);
mAllButtons.add(passButton);
mTestState = TestState.NOT_STARTED;
updateButtonsAndInstructionLocked();
}
private void updateButtonsAndInstructionLocked() {
for (View v : mAllButtons) {
v.setEnabled(false);
}
// Only enable the buttons for this state.
HashSet<View> views = mStateButtonsMap.get(mTestState);
for (View v : views) {
v.setEnabled(true);
}
switch (mTestState) {
case TESTING_ON:
case TESTING_OFF:
mInstructionTextView.setText(String.format(
getString(R.string.camera_flashlight_question_text), mCurrentCameraId));
break;
case RESPONDED_ON_CORRECTLY:
case RESPONDED_OFF_CORRECTLY:
mInstructionTextView.setText(R.string.camera_flashlight_next_text);
mInstructionButton.setText(R.string.camera_flashlight_next_button);
break;
case FAILED:
mInstructionTextView.setText(R.string.camera_flashlight_failed_text);
mInstructionButton.setText(R.string.camera_flashlight_done_button);
break;
case ALL_PASSED:
mInstructionTextView.setText(R.string.camera_flashlight_passed_text);
mInstructionButton.setText(R.string.camera_flashlight_done_button);
break;
default:
break;
}
}
}