Replace hard-coded errno values with OsConstants
Errno values have been hard-coded inside java code. On the native side however, bionic's errno.h is used (through utils/Errors.h). Some of the numbers are architecture dependent (EOPNOTSUPP, ETIMEDOUT...). This causes Camera app to crash on MIPS devices. There is a check for expected errors, in CameraBinderDecorator.throwOnError, but the error (EOPNOTSUPP) is not recognized and an exception is thrown. Change-Id: I8bcac8f1ced50c76614f566a6e624967a18a25e1
This commit is contained in:
@@ -47,6 +47,8 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static android.system.OsConstants.*;
|
||||
|
||||
/**
|
||||
* The Camera class is used to set image capture settings, start/stop preview,
|
||||
* snap pictures, and retrieve frames for encoding for video. This class is a
|
||||
@@ -173,13 +175,6 @@ public class Camera {
|
||||
private final Object mAutoFocusCallbackLock = new Object();
|
||||
|
||||
private static final int NO_ERROR = 0;
|
||||
private static final int EACCESS = -13;
|
||||
private static final int ENODEV = -19;
|
||||
private static final int EBUSY = -16;
|
||||
private static final int EINVAL = -22;
|
||||
private static final int ENOSYS = -38;
|
||||
private static final int EUSERS = -87;
|
||||
private static final int EOPNOTSUPP = -95;
|
||||
|
||||
/**
|
||||
* Broadcast Action: A new picture is taken by the camera, and the entry of
|
||||
@@ -415,30 +410,28 @@ public class Camera {
|
||||
private Camera(int cameraId, int halVersion) {
|
||||
int err = cameraInitVersion(cameraId, halVersion);
|
||||
if (checkInitErrors(err)) {
|
||||
switch(err) {
|
||||
case EACCESS:
|
||||
throw new RuntimeException("Fail to connect to camera service");
|
||||
case ENODEV:
|
||||
throw new RuntimeException("Camera initialization failed");
|
||||
case ENOSYS:
|
||||
throw new RuntimeException("Camera initialization failed because some methods"
|
||||
+ " are not implemented");
|
||||
case EOPNOTSUPP:
|
||||
throw new RuntimeException("Camera initialization failed because the hal"
|
||||
+ " version is not supported by this device");
|
||||
case EINVAL:
|
||||
throw new RuntimeException("Camera initialization failed because the input"
|
||||
+ " arugments are invalid");
|
||||
case EBUSY:
|
||||
throw new RuntimeException("Camera initialization failed because the camera"
|
||||
+ " device was already opened");
|
||||
case EUSERS:
|
||||
throw new RuntimeException("Camera initialization failed because the max"
|
||||
+ " number of camera devices were already opened");
|
||||
default:
|
||||
// Should never hit this.
|
||||
throw new RuntimeException("Unknown camera error");
|
||||
if (err == -EACCES) {
|
||||
throw new RuntimeException("Fail to connect to camera service");
|
||||
} else if (err == -ENODEV) {
|
||||
throw new RuntimeException("Camera initialization failed");
|
||||
} else if (err == -ENOSYS) {
|
||||
throw new RuntimeException("Camera initialization failed because some methods"
|
||||
+ " are not implemented");
|
||||
} else if (err == -EOPNOTSUPP) {
|
||||
throw new RuntimeException("Camera initialization failed because the hal"
|
||||
+ " version is not supported by this device");
|
||||
} else if (err == -EINVAL) {
|
||||
throw new RuntimeException("Camera initialization failed because the input"
|
||||
+ " arugments are invalid");
|
||||
} else if (err == -EBUSY) {
|
||||
throw new RuntimeException("Camera initialization failed because the camera"
|
||||
+ " device was already opened");
|
||||
} else if (err == -EUSERS) {
|
||||
throw new RuntimeException("Camera initialization failed because the max"
|
||||
+ " number of camera devices were already opened");
|
||||
}
|
||||
// Should never hit this.
|
||||
throw new RuntimeException("Unknown camera error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,15 +483,13 @@ public class Camera {
|
||||
Camera(int cameraId) {
|
||||
int err = cameraInitNormal(cameraId);
|
||||
if (checkInitErrors(err)) {
|
||||
switch(err) {
|
||||
case EACCESS:
|
||||
throw new RuntimeException("Fail to connect to camera service");
|
||||
case ENODEV:
|
||||
throw new RuntimeException("Camera initialization failed");
|
||||
default:
|
||||
// Should never hit this.
|
||||
throw new RuntimeException("Unknown camera error");
|
||||
if (err == -EACCES) {
|
||||
throw new RuntimeException("Fail to connect to camera service");
|
||||
} else if (err == -ENODEV) {
|
||||
throw new RuntimeException("Camera initialization failed");
|
||||
}
|
||||
// Should never hit this.
|
||||
throw new RuntimeException("Unknown camera error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ import android.view.Surface;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.system.OsConstants.EACCES;
|
||||
import static android.system.OsConstants.ENODEV;
|
||||
|
||||
/**
|
||||
* Compatibility implementation of the Camera2 API binder interface.
|
||||
*
|
||||
@@ -88,6 +91,14 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
mSurfaceIdCounter = 0;
|
||||
}
|
||||
|
||||
private static int translateErrorsFromCamera1(int errorCode) {
|
||||
if (errorCode == -EACCES) {
|
||||
return CameraBinderDecorator.PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a separate looper/thread for the camera to run on; open the camera.
|
||||
*
|
||||
@@ -382,7 +393,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot submit request, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
synchronized(mConfigureLock) {
|
||||
@@ -402,7 +413,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot submit request list, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
synchronized(mConfigureLock) {
|
||||
@@ -421,7 +432,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot cancel request, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
synchronized(mConfigureLock) {
|
||||
@@ -442,7 +453,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot begin configure, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
synchronized(mConfigureLock) {
|
||||
@@ -462,7 +473,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot end configure, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ArrayList<Surface> surfaces = null;
|
||||
@@ -490,7 +501,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot delete stream, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
synchronized(mConfigureLock) {
|
||||
@@ -515,7 +526,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot create stream, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
synchronized(mConfigureLock) {
|
||||
@@ -552,7 +563,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot create default request, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
CameraMetadataNative template;
|
||||
@@ -585,7 +596,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot wait until idle, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
synchronized(mConfigureLock) {
|
||||
@@ -605,7 +616,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot flush, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
synchronized(mConfigureLock) {
|
||||
@@ -627,7 +638,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot prepare stream, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
// LEGACY doesn't support actual prepare, just signal success right away
|
||||
@@ -647,7 +658,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
|
||||
}
|
||||
if (mLegacyDevice.isClosed()) {
|
||||
Log.e(TAG, "Cannot tear down stream, device has been closed.");
|
||||
return CameraBinderDecorator.ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
// LEGACY doesn't support actual teardown, so just a no-op
|
||||
|
||||
@@ -19,6 +19,8 @@ package android.hardware.camera2.legacy;
|
||||
import android.hardware.camera2.utils.CameraBinderDecorator;
|
||||
import android.util.AndroidException;
|
||||
|
||||
import static android.system.OsConstants.ENODEV;
|
||||
|
||||
/**
|
||||
* Utility class containing exception handling used solely by the compatibility mode shim.
|
||||
*/
|
||||
@@ -51,18 +53,15 @@ public class LegacyExceptionUtils {
|
||||
* exceptions.</p>
|
||||
*
|
||||
* @param errorFlag error to throw as an exception.
|
||||
* @throws {@link BufferQueueAbandonedException} for {@link CameraBinderDecorator#ENODEV}.
|
||||
* @throws {@link BufferQueueAbandonedException} for -ENODEV.
|
||||
* @throws {@link UnsupportedOperationException} for an unknown negative error code.
|
||||
* @return {@code errorFlag} if the value was non-negative, throws otherwise.
|
||||
*/
|
||||
public static int throwOnError(int errorFlag) throws BufferQueueAbandonedException {
|
||||
switch (errorFlag) {
|
||||
case CameraBinderDecorator.NO_ERROR: {
|
||||
return CameraBinderDecorator.NO_ERROR;
|
||||
}
|
||||
case CameraBinderDecorator.BAD_VALUE: {
|
||||
throw new BufferQueueAbandonedException();
|
||||
}
|
||||
if (errorFlag == CameraBinderDecorator.NO_ERROR) {
|
||||
return CameraBinderDecorator.NO_ERROR;
|
||||
} else if (errorFlag == -ENODEV) {
|
||||
throw new BufferQueueAbandonedException();
|
||||
}
|
||||
|
||||
if (errorFlag < 0) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
|
||||
import static android.hardware.camera2.CameraAccessException.CAMERA_ERROR;
|
||||
import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
|
||||
import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
|
||||
import static android.system.OsConstants.*;
|
||||
|
||||
import android.os.DeadObjectException;
|
||||
import android.os.RemoteException;
|
||||
@@ -37,12 +38,12 @@ import java.lang.reflect.Method;
|
||||
public class CameraBinderDecorator {
|
||||
|
||||
public static final int NO_ERROR = 0;
|
||||
public static final int PERMISSION_DENIED = -1;
|
||||
public static final int ALREADY_EXISTS = -17;
|
||||
public static final int BAD_VALUE = -22;
|
||||
public static final int DEAD_OBJECT = -32;
|
||||
public static final int INVALID_OPERATION = -38;
|
||||
public static final int TIMED_OUT = -110;
|
||||
public static final int PERMISSION_DENIED = -EPERM;
|
||||
public static final int ALREADY_EXISTS = -EEXIST;
|
||||
public static final int BAD_VALUE = -EINVAL;
|
||||
public static final int DEAD_OBJECT = -ENOSYS;
|
||||
public static final int INVALID_OPERATION = -EPIPE;
|
||||
public static final int TIMED_OUT = -ETIMEDOUT;
|
||||
|
||||
/**
|
||||
* TODO: add as error codes in Errors.h
|
||||
@@ -52,12 +53,6 @@ public class CameraBinderDecorator {
|
||||
* - NOT_SUPPORTED
|
||||
* - TOO_MANY_USERS
|
||||
*/
|
||||
public static final int EACCES = -13;
|
||||
public static final int EBUSY = -16;
|
||||
public static final int ENODEV = -19;
|
||||
public static final int EOPNOTSUPP = -95;
|
||||
public static final int EUSERS = -87;
|
||||
|
||||
|
||||
static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
|
||||
|
||||
@@ -101,35 +96,34 @@ public class CameraBinderDecorator {
|
||||
* @param errorFlag error to throw as an exception.
|
||||
*/
|
||||
public static void throwOnError(int errorFlag) {
|
||||
switch (errorFlag) {
|
||||
case NO_ERROR:
|
||||
return;
|
||||
case PERMISSION_DENIED:
|
||||
throw new SecurityException("Lacking privileges to access camera service");
|
||||
case ALREADY_EXISTS:
|
||||
// This should be handled at the call site. Typically this isn't bad,
|
||||
// just means we tried to do an operation that already completed.
|
||||
return;
|
||||
case BAD_VALUE:
|
||||
throw new IllegalArgumentException("Bad argument passed to camera service");
|
||||
case DEAD_OBJECT:
|
||||
throw new CameraRuntimeException(CAMERA_DISCONNECTED);
|
||||
case TIMED_OUT:
|
||||
throw new CameraRuntimeException(CAMERA_ERROR,
|
||||
"Operation timed out in camera service");
|
||||
case EACCES:
|
||||
throw new CameraRuntimeException(CAMERA_DISABLED);
|
||||
case EBUSY:
|
||||
throw new CameraRuntimeException(CAMERA_IN_USE);
|
||||
case EUSERS:
|
||||
throw new CameraRuntimeException(MAX_CAMERAS_IN_USE);
|
||||
case ENODEV:
|
||||
throw new CameraRuntimeException(CAMERA_DISCONNECTED);
|
||||
case EOPNOTSUPP:
|
||||
throw new CameraRuntimeException(CAMERA_DEPRECATED_HAL);
|
||||
case INVALID_OPERATION:
|
||||
throw new CameraRuntimeException(CAMERA_ERROR,
|
||||
"Illegal state encountered in camera service.");
|
||||
if (errorFlag == NO_ERROR) {
|
||||
return;
|
||||
} else if (errorFlag == PERMISSION_DENIED) {
|
||||
throw new SecurityException("Lacking privileges to access camera service");
|
||||
} else if (errorFlag == ALREADY_EXISTS) {
|
||||
// This should be handled at the call site. Typically this isn't bad,
|
||||
// just means we tried to do an operation that already completed.
|
||||
return;
|
||||
} else if (errorFlag == BAD_VALUE) {
|
||||
throw new IllegalArgumentException("Bad argument passed to camera service");
|
||||
} else if (errorFlag == DEAD_OBJECT) {
|
||||
throw new CameraRuntimeException(CAMERA_DISCONNECTED);
|
||||
} else if (errorFlag == TIMED_OUT) {
|
||||
throw new CameraRuntimeException(CAMERA_ERROR,
|
||||
"Operation timed out in camera service");
|
||||
} else if (errorFlag == -EACCES) {
|
||||
throw new CameraRuntimeException(CAMERA_DISABLED);
|
||||
} else if (errorFlag == -EBUSY) {
|
||||
throw new CameraRuntimeException(CAMERA_IN_USE);
|
||||
} else if (errorFlag == -EUSERS) {
|
||||
throw new CameraRuntimeException(MAX_CAMERAS_IN_USE);
|
||||
} else if (errorFlag == -ENODEV) {
|
||||
throw new CameraRuntimeException(CAMERA_DISCONNECTED);
|
||||
} else if (errorFlag == -EOPNOTSUPP) {
|
||||
throw new CameraRuntimeException(CAMERA_DEPRECATED_HAL);
|
||||
} else if (errorFlag == INVALID_OPERATION) {
|
||||
throw new CameraRuntimeException(CAMERA_ERROR,
|
||||
"Illegal state encountered in camera service.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
import static android.system.OsConstants.*;
|
||||
|
||||
/**
|
||||
* The SoundTrigger class provides access via JNI to the native service managing
|
||||
* the sound trigger HAL.
|
||||
@@ -35,11 +37,11 @@ public class SoundTrigger {
|
||||
|
||||
public static final int STATUS_OK = 0;
|
||||
public static final int STATUS_ERROR = Integer.MIN_VALUE;
|
||||
public static final int STATUS_PERMISSION_DENIED = -1;
|
||||
public static final int STATUS_NO_INIT = -19;
|
||||
public static final int STATUS_BAD_VALUE = -22;
|
||||
public static final int STATUS_DEAD_OBJECT = -32;
|
||||
public static final int STATUS_INVALID_OPERATION = -38;
|
||||
public static final int STATUS_PERMISSION_DENIED = -EPERM;
|
||||
public static final int STATUS_NO_INIT = -ENODEV;
|
||||
public static final int STATUS_BAD_VALUE = -EINVAL;
|
||||
public static final int STATUS_DEAD_OBJECT = -EPIPE;
|
||||
public static final int STATUS_INVALID_OPERATION = -ENOSYS;
|
||||
|
||||
/*****************************************************************************
|
||||
* A ModuleProperties describes a given sound trigger hardware module
|
||||
|
||||
@@ -129,7 +129,7 @@ public class CameraBinderTest extends AndroidTestCase {
|
||||
|
||||
int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_2);
|
||||
|
||||
if (res != CameraBinderTestUtils.NO_ERROR && res != CameraBinderTestUtils.EOPNOTSUPP) {
|
||||
if (res != CameraBinderTestUtils.NO_ERROR && res != -android.system.OsConstants.EOPNOTSUPP) {
|
||||
fail("Camera service returned bad value when queried if it supports camera2 api: "
|
||||
+ res + " for camera ID " + cameraId);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.android.mediaframeworktest.integration;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static android.system.OsConstants.*;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.FeatureInfo;
|
||||
@@ -18,11 +19,10 @@ public class CameraBinderTestUtils {
|
||||
static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
|
||||
|
||||
protected static final int USE_CALLING_UID = -1;
|
||||
protected static final int BAD_VALUE = -22;
|
||||
protected static final int INVALID_OPERATION = -38;
|
||||
protected static final int ALREADY_EXISTS = -17;
|
||||
protected static final int BAD_VALUE = -EINVAL;
|
||||
protected static final int INVALID_OPERATION = -ENOSYS;
|
||||
protected static final int ALREADY_EXISTS = -EEXIST;
|
||||
public static final int NO_ERROR = 0;
|
||||
public static final int EOPNOTSUPP = -95;
|
||||
private final Context mContext;
|
||||
|
||||
public CameraBinderTestUtils(Context context) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.test.suitebuilder.annotation.SmallTest;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static android.hardware.camera2.utils.CameraBinderDecorator.*;
|
||||
import static android.hardware.camera2.CameraAccessException.*;
|
||||
import static android.system.OsConstants.*;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
@@ -78,9 +79,9 @@ public class CameraUtilsBinderDecoratorTest extends junit.framework.TestCase {
|
||||
when(mock.doSomethingAlreadyExists()).thenReturn(ALREADY_EXISTS);
|
||||
when(mock.doSomethingBadValue()).thenReturn(BAD_VALUE);
|
||||
when(mock.doSomethingDeadObject()).thenReturn(DEAD_OBJECT);
|
||||
when(mock.doSomethingBadPolicy()).thenReturn(EACCES);
|
||||
when(mock.doSomethingDeviceBusy()).thenReturn(EBUSY);
|
||||
when(mock.doSomethingNoSuchDevice()).thenReturn(ENODEV);
|
||||
when(mock.doSomethingBadPolicy()).thenReturn(-EACCES);
|
||||
when(mock.doSomethingDeviceBusy()).thenReturn(-EBUSY);
|
||||
when(mock.doSomethingNoSuchDevice()).thenReturn(-ENODEV);
|
||||
when(mock.doSomethingUnknownErrorCode()).thenReturn(SOME_ARBITRARY_NEGATIVE_INT);
|
||||
when(mock.doSomethingThrowDeadObjectException()).thenThrow(new DeadObjectException());
|
||||
when(mock.doSomethingThrowTransactionTooLargeException()).thenThrow(
|
||||
|
||||
Reference in New Issue
Block a user