Merge "Add GET_SIGNATURES to getPackageArchiveInfo test" into ics-mr0
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
index 3d3cd1b..fcf3a34 100644
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -23,6 +23,8 @@
import android.hardware.Camera.Area;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.ErrorCallback;
+import android.hardware.Camera.Face;
+import android.hardware.Camera.FaceDetectionListener;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
@@ -342,20 +344,20 @@
int nCameras = Camera.getNumberOfCameras();
for (int id = 0; id < nCameras; id++) {
Log.v(TAG, "Camera id=" + id);
- testTakePictureByCamera(id);
+ initializeMessageLooper(id);
+ mCamera.startPreview();
+ testTakePictureByCamera();
+ terminateMessageLooper();
}
}
- private void testTakePictureByCamera(int cameraId) throws Exception {
- initializeMessageLooper(cameraId);
+ private void testTakePictureByCamera() throws Exception {
Size pictureSize = mCamera.getParameters().getPictureSize();
- mCamera.startPreview();
mCamera.autoFocus(mAutoFocusCallback);
assertTrue(waitForFocusDone());
mJpegData = null;
mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
waitForSnapshotDone();
- terminateMessageLooper();
assertTrue("Shutter callback not received", mShutterCallbackResult);
assertTrue("Raw picture callback not received", mRawPictureCallbackResult);
assertTrue("Jpeg picture callback not recieved", mJpegPictureCallbackResult);
@@ -808,12 +810,13 @@
int nCameras = Camera.getNumberOfCameras();
for (int id = 0; id < nCameras; id++) {
Log.v(TAG, "Camera id=" + id);
- testJpegThumbnailSizeByCamera(id);
+ initializeMessageLooper(id);
+ testJpegThumbnailSizeByCamera(false);
+ terminateMessageLooper();
}
}
- private void testJpegThumbnailSizeByCamera(int cameraId) throws Exception {
- initializeMessageLooper(cameraId);
+ private void testJpegThumbnailSizeByCamera(boolean recording) throws Exception {
// Thumbnail size parameters should have valid values.
Parameters p = mCamera.getParameters();
Size size = p.getJpegThumbnailSize();
@@ -824,7 +827,7 @@
assertTrue(sizes.contains(mCamera.new Size(0, 0)));
// Test if the thumbnail size matches the setting.
- mCamera.startPreview();
+ if (!recording) mCamera.startPreview();
mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
waitForSnapshotDone();
assertTrue(mJpegPictureCallbackResult);
@@ -843,14 +846,12 @@
Size actual = mCamera.getParameters().getJpegThumbnailSize();
assertEquals(0, actual.width);
assertEquals(0, actual.height);
- mCamera.startPreview();
+ if (!recording) mCamera.startPreview();
mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
waitForSnapshotDone();
assertTrue(mJpegPictureCallbackResult);
exif = new ExifInterface(JPEG_PATH);
assertFalse(exif.hasThumbnail());
-
- terminateMessageLooper();
}
@UiThreadTest
@@ -858,15 +859,16 @@
int nCameras = Camera.getNumberOfCameras();
for (int id = 0; id < nCameras; id++) {
Log.v(TAG, "Camera id=" + id);
- testJpegExifByCamera(id);
+ initializeMessageLooper(id);
+ testJpegExifByCamera(false);
+ terminateMessageLooper();
}
}
- private void testJpegExifByCamera(int cameraId) throws Exception {
- initializeMessageLooper(cameraId);
+ private void testJpegExifByCamera(boolean recording) throws Exception {
Camera.Parameters parameters = mCamera.getParameters();
- mCamera.startPreview();
- double focalLength = (double)parameters.getFocalLength();
+ if (!recording) mCamera.startPreview();
+ double focalLength = parameters.getFocalLength();
mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
waitForSnapshotDone();
ExifInterface exif = new ExifInterface(JPEG_PATH);
@@ -876,8 +878,7 @@
assertTrue(exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0) != 0);
assertTrue(exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0) != 0);
checkGpsDataNull(exif);
- double exifFocalLength = (double)exif.getAttributeDouble(
- ExifInterface.TAG_FOCAL_LENGTH, -1);
+ double exifFocalLength = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, -1);
assertEquals(focalLength, exifFocalLength, 0.001);
// Test gps exif tags.
@@ -887,14 +888,13 @@
testGpsExifValues(parameters, -89.736071, -179.441983, 100000, 1199145602, "NETWORK");
// Test gps tags do not exist after calling removeGpsData.
- mCamera.startPreview();
+ if (!recording) mCamera.startPreview();
parameters.removeGpsData();
mCamera.setParameters(parameters);
mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
waitForSnapshotDone();
exif = new ExifInterface(JPEG_PATH);
checkGpsDataNull(exif);
- terminateMessageLooper();
}
private void testGpsExifValues(Parameters parameters, double latitude,
@@ -1386,11 +1386,42 @@
assertEquals(focusMode, parameters.getFocusMode());
checkFocusDistances(parameters);
if (Parameters.FOCUS_MODE_AUTO.equals(focusMode)
- || Parameters.FOCUS_MODE_MACRO.equals(focusMode)) {
+ || Parameters.FOCUS_MODE_MACRO.equals(focusMode)
+ || Parameters.FOCUS_MODE_CONTINUOUS_VIDEO.equals(focusMode)
+ || Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(focusMode)) {
+ Log.v(TAG, "Focus mode=" + focusMode);
mCamera.autoFocus(mAutoFocusCallback);
assertTrue(waitForFocusDone());
parameters = mCamera.getParameters();
checkFocusDistances(parameters);
+ float[] initialFocusDistances = new float[3];
+ parameters.getFocusDistances(initialFocusDistances);
+
+ // Focus position should not change after autoFocus call.
+ // Continuous autofocus should have stopped. Sleep some time and
+ // check. Make sure continuous autofocus is not working. If the
+ // focus mode is auto or macro, it is no harm to do the extra
+ // test.
+ Thread.sleep(500);
+ parameters = mCamera.getParameters();
+ float[] currentFocusDistances = new float[3];
+ parameters.getFocusDistances(currentFocusDistances);
+ assertEquals(initialFocusDistances, currentFocusDistances);
+
+ // Focus position should not change after stopping preview.
+ mCamera.stopPreview();
+ parameters = mCamera.getParameters();
+ parameters.getFocusDistances(currentFocusDistances);
+ assertEquals(initialFocusDistances, currentFocusDistances);
+
+ // Focus position should not change after taking a picture.
+ mCamera.startPreview();
+ mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+ waitForSnapshotDone();
+ parameters = mCamera.getParameters();
+ parameters.getFocusDistances(currentFocusDistances);
+ assertEquals(initialFocusDistances, currentFocusDistances);
+ mCamera.startPreview();
}
}
@@ -1865,6 +1896,13 @@
assertEquals(expected.height, actual.height);
}
+ private void assertEquals(float[] expected, float[] actual) {
+ assertEquals(expected.length, actual.length);
+ for (int i = 0; i < expected.length; i++) {
+ assertEquals(expected[i], actual[i], 0.000001f);
+ }
+ }
+
private void assertNoLetters(String value, String key) {
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
@@ -2675,4 +2713,171 @@
mCamera.setParameters(parameters);
}
+ @UiThreadTest
+ public void testFaceDetection() throws Exception {
+ int nCameras = Camera.getNumberOfCameras();
+ for (int id = 0; id < nCameras; id++) {
+ Log.v(TAG, "Camera id=" + id);
+ testFaceDetectionByCamera(id);
+ }
+ }
+
+ private void testFaceDetectionByCamera(int cameraId) throws Exception {
+ final int FACE_DETECTION_TEST_DURATION = 3000;
+ initializeMessageLooper(cameraId);
+ mCamera.startPreview();
+ Parameters parameters = mCamera.getParameters();
+ int maxNumOfFaces = parameters.getMaxNumDetectedFaces();
+ assertTrue(maxNumOfFaces >= 0);
+ if (maxNumOfFaces == 0) {
+ try {
+ mCamera.startFaceDetection();
+ fail("Should throw an exception if face detection is not supported.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ terminateMessageLooper();
+ return;
+ }
+
+ mCamera.startFaceDetection();
+ try {
+ mCamera.startFaceDetection();
+ fail("Starting face detection twice should throw an exception");
+ } catch (RuntimeException e) {
+ // expected
+ }
+ FaceListener listener = new FaceListener();
+ mCamera.setFaceDetectionListener(listener);
+ // Sleep some time so the camera has chances to detect faces.
+ Thread.sleep(FACE_DETECTION_TEST_DURATION);
+ // The face callback runs in another thread. Release the camera and stop
+ // the looper. So we do not access the face array from two threads at
+ // the same time.
+ terminateMessageLooper();
+
+ // Check if the optional fields are supported.
+ boolean optionalFieldSupported = false;
+ Face firstFace = null;
+ for (Face[] faces: listener.mFacesArray) {
+ for (Face face: faces) {
+ if (face != null) firstFace = face;
+ }
+ }
+ if (firstFace != null) {
+ if (firstFace.id != -1 || firstFace.leftEye != null
+ || firstFace.rightEye != null || firstFace.mouth != null) {
+ optionalFieldSupported = true;
+ }
+ }
+
+ // Verify the faces array.
+ for (Face[] faces: listener.mFacesArray) {
+ testFaces(faces, maxNumOfFaces, optionalFieldSupported);
+ }
+ }
+
+ private class FaceListener implements FaceDetectionListener {
+ public ArrayList<Face[]> mFacesArray = new ArrayList<Face[]>();
+
+ @Override
+ public void onFaceDetection(Face[] faces, Camera camera) {
+ mFacesArray.add(faces);
+ }
+ }
+
+ private void testFaces(Face[] faces, int maxNumOfFaces,
+ boolean optionalFieldSupported) {
+ Rect bounds = new Rect(-1000, -1000, 1000, 1000);
+ assertNotNull(faces);
+ assertTrue(faces.length <= maxNumOfFaces);
+ for (int i = 0; i < faces.length; i++) {
+ Face face = faces[i];
+ Rect rect = face.rect;
+ // Check the bounds.
+ assertNotNull(rect);
+ assertTrue(rect.width() > 0);
+ assertTrue(rect.height() > 0);
+ assertTrue("Coordinates out of bounds. rect=" + rect,
+ bounds.contains(rect) || Rect.intersects(bounds, rect));
+
+ // Check the score.
+ assertTrue(face.score >= 1 && face.score <= 100);
+
+ // Check id, left eye, right eye, and the mouth.
+ // Optional fields should be all valid or none of them.
+ if (!optionalFieldSupported) {
+ assertEquals(-1, face.id);
+ assertNull(face.leftEye);
+ assertNull(face.rightEye);
+ assertNull(face.mouth);
+ } else {
+ assertTrue(face.id != -1);
+ assertNotNull(face.leftEye);
+ assertNotNull(face.rightEye);
+ assertNotNull(face.mouth);
+ assertTrue(bounds.contains(face.leftEye.x, face.leftEye.y));
+ assertTrue(bounds.contains(face.rightEye.x, face.rightEye.y));
+ assertTrue(bounds.contains(face.mouth.x, face.mouth.y));
+ // ID should be unique.
+ if (i != faces.length - 1) {
+ assertTrue(face.id != faces[i + 1].id);
+ }
+ }
+ }
+ }
+
+ @UiThreadTest
+ public void testVideoSnapshot() throws Exception {
+ int nCameras = Camera.getNumberOfCameras();
+ for (int id = 0; id < nCameras; id++) {
+ Log.v(TAG, "Camera id=" + id);
+ testVideoSnapshotByCamera(id);
+ }
+ }
+
+ private void testVideoSnapshotByCamera(int cameraId) throws Exception {
+ initializeMessageLooper(cameraId);
+ Camera.Parameters parameters = mCamera.getParameters();
+ if (!parameters.isVideoSnapshotSupported()) return;
+
+ SurfaceHolder holder = getActivity().getSurfaceView().getHolder();
+
+ // Set the preview size.
+ CamcorderProfile profile = CamcorderProfile.get(cameraId,
+ CamcorderProfile.QUALITY_LOW);
+ setPreviewSizeByProfile(parameters, profile);
+
+ // Set the biggest picture size.
+ Size biggestSize = mCamera.new Size(-1, -1);
+ for (Size size: parameters.getSupportedPictureSizes()) {
+ if (biggestSize.width < size.width) {
+ biggestSize = size;
+ }
+ }
+ parameters.setPictureSize(biggestSize.width, biggestSize.height);
+
+ mCamera.setParameters(parameters);
+ mCamera.startPreview();
+ mCamera.unlock();
+ MediaRecorder recorder = new MediaRecorder();
+ try {
+ recorder.setCamera(mCamera);
+ recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+ recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ recorder.setProfile(profile);
+ recorder.setOutputFile("/dev/null");
+ recorder.setPreviewDisplay(holder.getSurface());
+ recorder.prepare();
+ recorder.start();
+ testTakePictureByCamera();
+ testJpegExifByCamera(true);
+ testJpegThumbnailSizeByCamera(true);
+ recorder.stop();
+ } finally {
+ recorder.release();
+ mCamera.lock();
+ }
+ terminateMessageLooper();
+ }
}