Merge "Camera: external camera fix for CtsVerifier" into pi-dev
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
index 85d2a18..b042fed 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
@@ -26,6 +26,9 @@
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
@@ -104,6 +107,13 @@
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_fov_calibration_photo_capture);
+ int cameraToBeTested = 0;
+ for (int cameraId = 0; cameraId < Camera.getNumberOfCameras(); ++cameraId) {
+ if (!isExternalCamera(cameraId)) {
+ cameraToBeTested++;
+ }
+ }
+
mPreview = (SurfaceView) findViewById(R.id.camera_fov_camera_preview);
mSurfaceHolder = mPreview.getHolder();
mSurfaceHolder.addCallback(this);
@@ -139,7 +149,9 @@
mPreviewSizeCamerasToProcess.clear();
mPreviewSizes = new Size[Camera.getNumberOfCameras()];
for (int cameraId = 0; cameraId < Camera.getNumberOfCameras(); ++cameraId) {
- mPreviewSizeCamerasToProcess.add(cameraId);
+ if (!isExternalCamera(cameraId)) {
+ mPreviewSizeCamerasToProcess.add(cameraId);
+ }
}
showNextDialogToChoosePreviewSize();
}
@@ -181,9 +193,19 @@
}
}
- @Override
- public void onNothingSelected(AdapterView<?> arg0) {}
+ @Override
+ public void onNothingSelected(AdapterView<?> arg0) {}
});
+
+ if (cameraToBeTested == 0) {
+ Log.i(TAG, "No cameras needs to be tested. Setting test pass.");
+ Toast.makeText(this, "No cameras needs to be tested. Test pass.",
+ Toast.LENGTH_LONG).show();
+
+ TestResult.setPassedResult(this, getClass().getName(),
+ "All cameras are external, test skipped!");
+ finish();
+ }
}
@Override
@@ -198,6 +220,10 @@
mSupportedResolutions = new ArrayList<SelectableResolution>();
int numCameras = Camera.getNumberOfCameras();
for (int cameraId = 0; cameraId < numCameras; ++cameraId) {
+ if (isExternalCamera(cameraId)) {
+ continue;
+ }
+
Camera camera = Camera.open(cameraId);
// Get the supported picture sizes and fill the spinner.
@@ -539,4 +565,23 @@
mPreviewOrientation = mJpegOrientation;
}
}
+
+ private boolean isExternalCamera(int cameraId) {
+ CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
+ try {
+ String cameraIdStr = manager.getCameraIdList()[cameraId];
+ CameraCharacteristics characteristics =
+ manager.getCameraCharacteristics(cameraIdStr);
+
+ if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ==
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL) {
+ // External camera doesn't support FOV informations
+ return true;
+ }
+ } catch (CameraAccessException e) {
+ Toast.makeText(this, "Could not access camera " + cameraId +
+ ": " + e.getMessage(), Toast.LENGTH_LONG).show();
+ }
+ return false;
+ }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
index 9024705..8007983 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
@@ -79,7 +79,7 @@
private final ResultReceiver mResultsReceiver = new ResultReceiver();
// Initialized in onCreate
- ArrayList<String> mNonLegacyCameraIds = null;
+ ArrayList<String> mToBeTestedCameraIds = null;
// Scenes
private static final ArrayList<String> mSceneIds = new ArrayList<String> () { {
@@ -164,7 +164,7 @@
return;
}
- if (!mNonLegacyCameraIds.contains(cameraId)) {
+ if (!mToBeTestedCameraIds.contains(cameraId)) {
Log.e(TAG, "Unknown camera id " + cameraId + " reported to ITS");
return;
}
@@ -214,7 +214,7 @@
mExecutedScenes.clear();
mAllScenes.clear();
for (String scene : scenes) {
- for (String c : mNonLegacyCameraIds) {
+ for (String c : mToBeTestedCameraIds) {
mAllScenes.add(new ResultKey(c, scene));
}
}
@@ -333,20 +333,22 @@
CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
try {
String[] cameraIds = manager.getCameraIdList();
- mNonLegacyCameraIds = new ArrayList<String>();
- boolean allCamerasAreLegacy = true;
+ mToBeTestedCameraIds = new ArrayList<String>();
for (String id : cameraIds) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
- if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
- != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
- mNonLegacyCameraIds.add(id);
- allCamerasAreLegacy = false;
+ int hwLevel = characteristics.get(
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+ if (hwLevel
+ != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY &&
+ hwLevel
+ != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL) {
+ mToBeTestedCameraIds.add(id);
}
}
- if (allCamerasAreLegacy) {
+ if (mToBeTestedCameraIds.size() == 0) {
showToast(R.string.all_legacy_devices);
ItsTestActivity.this.getReportLog().setSummary(
- "PASS: all cameras on this device are LEGACY"
+ "PASS: all cameras on this device are LEGACY or EXTERNAL"
, 1.0, ResultType.NEUTRAL, ResultUnit.NONE);
setTestResultAndFinish(true);
}
@@ -375,7 +377,7 @@
}
protected void setupItsTests(ArrayTestListAdapter adapter) {
- for (String cam : mNonLegacyCameraIds) {
+ for (String cam : mToBeTestedCameraIds) {
for (String scene : mSceneIds) {
adapter.add(new DialogTestListItem(this,
testTitle(cam, scene),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
index 0a397e8..1f17cdf 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
@@ -16,12 +16,16 @@
package com.android.cts.verifier.camera.video;
import android.app.AlertDialog;
+import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Size;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
import android.media.CamcorderProfile;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
@@ -38,6 +42,7 @@
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
+import android.widget.Toast;
import android.widget.VideoView;
import com.android.cts.verifier.PassFailButtons;
@@ -79,6 +84,7 @@
private int mCurrentCameraId = -1;
private Camera mCamera;
+ private boolean mIsExternalCamera;
private MediaRecorder mMediaRecorder;
@@ -141,6 +147,19 @@
return mediaFile;
}
+ private static final int BIT_RATE_720P = 8000000;
+ private static final int BIT_RATE_MIN = 64000;
+ private static final int BIT_RATE_MAX = BIT_RATE_720P;
+
+ private int getVideoBitRate(Camera.Size sz) {
+ int rate = BIT_RATE_720P;
+ float scaleFactor = sz.height * sz.width / (float)(1280 * 720);
+ rate = (int)(rate * scaleFactor);
+
+ // Clamp to the MIN, MAX range.
+ return Math.max(BIT_RATE_MIN, Math.min(BIT_RATE_MAX, rate));
+ }
+
private boolean prepareVideoRecorder() {
mMediaRecorder = new MediaRecorder();
@@ -154,7 +173,39 @@
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: set a CamcorderProfile
- mMediaRecorder.setProfile(CamcorderProfile.get(mCurrentCameraId, mCurrentVideoSizeId));
+ if (mIsExternalCamera) {
+ Camera.Size recordSize = null;
+ switch (mCurrentVideoSizeId) {
+ case CamcorderProfile.QUALITY_QCIF:
+ recordSize = mCamera.new Size(176, 144);
+ break;
+ case CamcorderProfile.QUALITY_QVGA:
+ recordSize = mCamera.new Size(320, 240);
+ break;
+ case CamcorderProfile.QUALITY_CIF:
+ recordSize = mCamera.new Size(352, 288);
+ break;
+ case CamcorderProfile.QUALITY_480P:
+ recordSize = mCamera.new Size(720, 480);
+ break;
+ case CamcorderProfile.QUALITY_720P:
+ recordSize = mCamera.new Size(1280, 720);
+ break;
+ default:
+ String msg = "Unknown CamcorderProfile: " + mCurrentVideoSizeId;
+ Log.e(TAG, msg);
+ releaseMediaRecorder();
+ throw new AssertionError(msg);
+ }
+
+ mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
+ mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
+ mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
+ mMediaRecorder.setVideoEncodingBitRate(getVideoBitRate(recordSize));
+ mMediaRecorder.setVideoSize(recordSize.width, recordSize.height);
+ } else {
+ mMediaRecorder.setProfile(CamcorderProfile.get(mCurrentCameraId, mCurrentVideoSizeId));
+ }
// Step 4: set output file
outputVideoFile = getOutputMediaFile(MEDIA_TYPE_VIDEO);
@@ -450,15 +501,28 @@
int[] qualityArray = {
CamcorderProfile.QUALITY_LOW,
CamcorderProfile.QUALITY_HIGH,
- CamcorderProfile.QUALITY_QCIF,
- CamcorderProfile.QUALITY_QVGA,
- CamcorderProfile.QUALITY_CIF,
- CamcorderProfile.QUALITY_480P,
- CamcorderProfile.QUALITY_720P,
- CamcorderProfile.QUALITY_1080P,
+ CamcorderProfile.QUALITY_QCIF, // 176x144
+ CamcorderProfile.QUALITY_QVGA, // 320x240
+ CamcorderProfile.QUALITY_CIF, // 352x288
+ CamcorderProfile.QUALITY_480P, // 720x480
+ CamcorderProfile.QUALITY_720P, // 1280x720
+ CamcorderProfile.QUALITY_1080P, // 1920x1080 or 1920x1088
CamcorderProfile.QUALITY_2160P
};
+ final Camera.Size skip = mCamera.new Size(-1, -1);
+ Camera.Size[] videoSizeArray = {
+ skip,
+ skip,
+ mCamera.new Size(176, 144),
+ mCamera.new Size(320, 240),
+ mCamera.new Size(352, 288),
+ mCamera.new Size(720, 480),
+ mCamera.new Size(1280, 720),
+ skip,
+ skip
+ };
+
String[] nameArray = {
"LOW",
"HIGH",
@@ -474,10 +538,23 @@
ArrayList<VideoSizeNamePair> availableSizes =
new ArrayList<VideoSizeNamePair> ();
+ Camera.Parameters p = mCamera.getParameters();
+ List<Camera.Size> supportedVideoSizes = p.getSupportedVideoSizes();
for (int i = 0; i < qualityArray.length; i++) {
- if (CamcorderProfile.hasProfile(cameraId, qualityArray[i])) {
- VideoSizeNamePair pair = new VideoSizeNamePair(qualityArray[i], nameArray[i]);
- availableSizes.add(pair);
+ if (mIsExternalCamera) {
+ Camera.Size videoSz = videoSizeArray[i];
+ if (videoSz.equals(skip)) {
+ continue;
+ }
+ if (supportedVideoSizes.contains(videoSz)) {
+ VideoSizeNamePair pair = new VideoSizeNamePair(qualityArray[i], nameArray[i]);
+ availableSizes.add(pair);
+ }
+ } else {
+ if (CamcorderProfile.hasProfile(cameraId, qualityArray[i])) {
+ VideoSizeNamePair pair = new VideoSizeNamePair(qualityArray[i], nameArray[i]);
+ availableSizes.add(pair);
+ }
}
}
return availableSizes;
@@ -511,12 +588,38 @@
CamcorderProfile.QUALITY_2160P
};
+ final Camera.Size skip = mCamera.new Size(-1, -1);
+ Camera.Size[] videoSizeArray = {
+ skip,
+ skip,
+ mCamera.new Size(176, 144),
+ mCamera.new Size(320, 240),
+ mCamera.new Size(352, 288),
+ mCamera.new Size(720, 480),
+ mCamera.new Size(1280, 720),
+ skip,
+ skip
+ };
+
ArrayList<ResolutionQuality> qualityList = new ArrayList<ResolutionQuality>();
+ Camera.Parameters p = mCamera.getParameters();
+ List<Camera.Size> supportedVideoSizes = p.getSupportedVideoSizes();
for (int i = 0; i < possibleQuality.length; i++) {
- if (CamcorderProfile.hasProfile(cameraId, possibleQuality[i])) {
- CamcorderProfile profile = CamcorderProfile.get(cameraId, possibleQuality[i]);
- qualityList.add(new ResolutionQuality(possibleQuality[i],
- profile.videoFrameWidth, profile.videoFrameHeight));
+ if (mIsExternalCamera) {
+ Camera.Size videoSz = videoSizeArray[i];
+ if (videoSz.equals(skip)) {
+ continue;
+ }
+ if (supportedVideoSizes.contains(videoSz)) {
+ qualityList.add(new ResolutionQuality(possibleQuality[i],
+ videoSz.width, videoSz.height));
+ }
+ } else {
+ if (CamcorderProfile.hasProfile(cameraId, possibleQuality[i])) {
+ CamcorderProfile profile = CamcorderProfile.get(cameraId, possibleQuality[i]);
+ qualityList.add(new ResolutionQuality(possibleQuality[i],
+ profile.videoFrameWidth, profile.videoFrameHeight));
+ }
}
}
@@ -595,6 +698,7 @@
failTest("camera not available" + e.getMessage());
return;
}
+ mIsExternalCamera = isExternalCamera(id);
Camera.Parameters p = mCamera.getParameters();
if (VERBOSE) {
@@ -767,4 +871,23 @@
.show();
}
+ private boolean isExternalCamera(int cameraId) {
+ CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
+ try {
+ String cameraIdStr = manager.getCameraIdList()[cameraId];
+ CameraCharacteristics characteristics =
+ manager.getCameraCharacteristics(cameraIdStr);
+
+ if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ==
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL) {
+ // External camera doesn't support FOV informations
+ return true;
+ }
+ } catch (CameraAccessException e) {
+ Toast.makeText(this, "Could not access camera " + cameraId +
+ ": " + e.getMessage(), Toast.LENGTH_LONG).show();
+ }
+ return false;
+ }
+
}