Merge "camera3: Pass vendor tags through binder."
This commit is contained in:
@@ -61,4 +61,12 @@ interface ICameraService
|
||||
int removeListener(ICameraServiceListener listener);
|
||||
|
||||
int getCameraCharacteristics(int cameraId, out CameraMetadataNative info);
|
||||
|
||||
/**
|
||||
* The java stubs for this method are not intended to be used. Please use
|
||||
* the native stub in frameworks/av/include/camera/ICameraService.h instead.
|
||||
* The BinderHolder output is being used as a placeholder, and will not be
|
||||
* well-formatted in the generated java method.
|
||||
*/
|
||||
int getCameraVendorTagDescriptor(out BinderHolder desc);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public final class CameraManager {
|
||||
|
||||
private static final String TAG = "CameraManager";
|
||||
|
||||
/**
|
||||
* This should match the ICameraService definition
|
||||
*/
|
||||
@@ -78,6 +80,19 @@ public final class CameraManager {
|
||||
*/
|
||||
mCameraService = CameraBinderDecorator.newInstance(cameraServiceRaw);
|
||||
|
||||
try {
|
||||
int err = CameraMetadataNative.nativeSetupGlobalVendorTagDescriptor();
|
||||
if (err == CameraBinderDecorator.EOPNOTSUPP) {
|
||||
Log.w(TAG, "HAL version doesn't vendor tags.");
|
||||
} else {
|
||||
CameraBinderDecorator.throwOnError(CameraMetadataNative.
|
||||
nativeSetupGlobalVendorTagDescriptor());
|
||||
}
|
||||
} catch(CameraRuntimeException e) {
|
||||
throw new IllegalStateException("Failed to setup camera vendor tags",
|
||||
e.asChecked());
|
||||
}
|
||||
|
||||
try {
|
||||
mCameraService.addListener(new CameraServiceListener());
|
||||
} catch(CameraRuntimeException e) {
|
||||
|
||||
@@ -104,6 +104,18 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable {
|
||||
nativeReadFromParcel(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the global client-side vendor tag descriptor to allow use of vendor
|
||||
* tags in camera applications.
|
||||
*
|
||||
* @return int A native status_t value corresponding to one of the
|
||||
* {@link CameraBinderDecorator} integer constants.
|
||||
* @see CameraBinderDecorator#throwOnError
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static native int nativeSetupGlobalVendorTagDescriptor();
|
||||
|
||||
/**
|
||||
* Set a camera metadata field to a value. The field definitions can be
|
||||
* found in {@link CameraCharacteristics}, {@link CaptureResult}, and
|
||||
|
||||
@@ -64,47 +64,7 @@ public class CameraBinderDecorator {
|
||||
// int return type => status_t => convert to exception
|
||||
if (m.getReturnType() == Integer.TYPE) {
|
||||
int returnValue = (Integer) result;
|
||||
|
||||
switch (returnValue) {
|
||||
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:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_DISCONNECTED));
|
||||
case EACCES:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_DISABLED));
|
||||
case EBUSY:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_IN_USE));
|
||||
case EUSERS:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
MAX_CAMERAS_IN_USE));
|
||||
case ENODEV:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_DISCONNECTED));
|
||||
case EOPNOTSUPP:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_DEPRECATED_HAL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Trap the rest of the negative return values. If we have known
|
||||
* error codes i.e. ALREADY_EXISTS that aren't really runtime
|
||||
* errors, then add them to the top switch statement
|
||||
*/
|
||||
if (returnValue < 0) {
|
||||
throw new UnsupportedOperationException(String.format("Unknown error %d",
|
||||
returnValue));
|
||||
}
|
||||
throwOnError(returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +90,54 @@ public class CameraBinderDecorator {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw error codes returned by the camera service as exceptions.
|
||||
*
|
||||
* @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:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_DISCONNECTED));
|
||||
case EACCES:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_DISABLED));
|
||||
case EBUSY:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_IN_USE));
|
||||
case EUSERS:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
MAX_CAMERAS_IN_USE));
|
||||
case ENODEV:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_DISCONNECTED));
|
||||
case EOPNOTSUPP:
|
||||
UncheckedThrow.throwAnyException(new CameraRuntimeException(
|
||||
CAMERA_DEPRECATED_HAL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Trap the rest of the negative return values. If we have known
|
||||
* error codes i.e. ALREADY_EXISTS that aren't really runtime
|
||||
* errors, then add them to the top switch statement
|
||||
*/
|
||||
if (errorFlag < 0) {
|
||||
throw new UnsupportedOperationException(String.format("Unknown error %d",
|
||||
errorFlag));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Wraps the type T with a proxy that will check 'status_t' return codes
|
||||
|
||||
@@ -19,13 +19,18 @@
|
||||
// #define LOG_NNDEBUG 0
|
||||
#define LOG_TAG "CameraMetadata-JNI"
|
||||
#include <utils/Log.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "JNIHelp.h"
|
||||
#include "android_os_Parcel.h"
|
||||
#include "android_runtime/AndroidRuntime.h"
|
||||
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <camera/CameraMetadata.h>
|
||||
#include <camera/ICameraService.h>
|
||||
#include <camera/VendorTagDescriptor.h>
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
#include <nativehelper/ScopedPrimitiveArray.h>
|
||||
|
||||
@@ -112,6 +117,7 @@ extern "C" {
|
||||
static void CameraMetadata_classInit(JNIEnv *env, jobject thiz);
|
||||
static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName);
|
||||
static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag);
|
||||
static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz);
|
||||
|
||||
// Less safe access to native pointer. Does NOT throw any Java exceptions if NULL.
|
||||
static CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) {
|
||||
@@ -372,6 +378,9 @@ static JNINativeMethod gCameraMetadataMethods[] = {
|
||||
{ "nativeGetTypeFromTag",
|
||||
"(I)I",
|
||||
(void *)CameraMetadata_getTypeFromTag },
|
||||
{ "nativeSetupGlobalVendorTagDescriptor",
|
||||
"()I",
|
||||
(void*)CameraMetadata_setupGlobalVendorTagDescriptor },
|
||||
// instance methods
|
||||
{ "nativeAllocate",
|
||||
"()J",
|
||||
@@ -556,4 +565,29 @@ static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag) {
|
||||
return tagType;
|
||||
}
|
||||
|
||||
static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz) {
|
||||
const String16 NAME("media.camera");
|
||||
sp<ICameraService> cameraService;
|
||||
status_t err = getService(NAME, /*out*/&cameraService);
|
||||
|
||||
if (err != OK) {
|
||||
ALOGE("%s: Failed to get camera service, received error %s (%d)", __FUNCTION__,
|
||||
strerror(-err), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
sp<VendorTagDescriptor> desc;
|
||||
err = cameraService->getCameraVendorTagDescriptor(/*out*/desc);
|
||||
|
||||
if (err != OK) {
|
||||
ALOGE("%s: Failed to setup vendor tag descriptors, received error %s (%d)", __FUNCTION__,
|
||||
strerror(-err), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user