Merge changes I069e2b7e,Ic5e9e58a into nyc-dev

* changes:
  Camera2: Fix error codes for CameraDevice.StateCallback.onError()
  Camera2: Protect MarshalRegistry against concurrent access
This commit is contained in:
Eino-Ville Talvala
2016-06-10 19:44:03 +00:00
committed by Android (Google) Code Review
2 changed files with 50 additions and 74 deletions

View File

@@ -1610,41 +1610,6 @@ public class CameraDeviceImpl extends CameraDevice
}
public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
//
// Constants below need to be kept up-to-date with
// frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h
//
//
// Error codes for onCameraError
//
/**
* Camera has been disconnected
*/
public static final int ERROR_CAMERA_DISCONNECTED = 0;
/**
* Camera has encountered a device-level error
* Matches CameraDevice.StateCallback#ERROR_CAMERA_DEVICE
*/
public static final int ERROR_CAMERA_DEVICE = 1;
/**
* Camera has encountered a service-level error
* Matches CameraDevice.StateCallback#ERROR_CAMERA_SERVICE
*/
public static final int ERROR_CAMERA_SERVICE = 2;
/**
* Camera has encountered an error processing a single request.
*/
public static final int ERROR_CAMERA_REQUEST = 3;
/**
* Camera has encountered an error producing metadata for a single capture
*/
public static final int ERROR_CAMERA_RESULT = 4;
/**
* Camera has encountered an error producing an image buffer for a single capture
*/
public static final int ERROR_CAMERA_BUFFER = 5;
@Override
public IBinder asBinder() {
@@ -1675,11 +1640,14 @@ public class CameraDeviceImpl extends CameraDevice
case ERROR_CAMERA_DEVICE:
case ERROR_CAMERA_SERVICE:
mInError = true;
final int publicErrorCode = (errorCode == ERROR_CAMERA_DEVICE) ?
StateCallback.ERROR_CAMERA_DEVICE :
StateCallback.ERROR_CAMERA_SERVICE;
Runnable r = new Runnable() {
@Override
public void run() {
if (!CameraDeviceImpl.this.isClosed()) {
mDeviceCallback.onError(CameraDeviceImpl.this, errorCode);
mDeviceCallback.onError(CameraDeviceImpl.this, publicErrorCode);
}
}
};
@@ -2050,7 +2018,7 @@ public class CameraDeviceImpl extends CameraDevice
public void run() {
if (!isClosed()) {
mDeviceCallback.onError(CameraDeviceImpl.this,
CameraDeviceCallbacks.ERROR_CAMERA_SERVICE);
StateCallback.ERROR_CAMERA_SERVICE);
}
}
};

View File

@@ -37,7 +37,9 @@ public class MarshalRegistry {
* @param queryable a non-{@code null} marshal queryable that supports marshaling {@code T}
*/
public static <T> void registerMarshalQueryable(MarshalQueryable<T> queryable) {
sRegisteredMarshalQueryables.add(queryable);
synchronized(sMarshalLock) {
sRegisteredMarshalQueryables.add(queryable);
}
}
/**
@@ -54,47 +56,50 @@ public class MarshalRegistry {
*/
@SuppressWarnings("unchecked")
public static <T> Marshaler<T> getMarshaler(TypeReference<T> typeToken, int nativeType) {
// TODO: can avoid making a new token each time by code-genning
// the list of type tokens and native types from the keys (at the call sites)
MarshalToken<T> marshalToken = new MarshalToken<T>(typeToken, nativeType);
synchronized(sMarshalLock) {
// TODO: can avoid making a new token each time by code-genning
// the list of type tokens and native types from the keys (at the call sites)
MarshalToken<T> marshalToken = new MarshalToken<T>(typeToken, nativeType);
/*
* Marshalers are instantiated lazily once they are looked up; successive lookups
* will not instantiate new marshalers.
*/
Marshaler<T> marshaler =
(Marshaler<T>) sMarshalerMap.get(marshalToken);
if (sRegisteredMarshalQueryables.size() == 0) {
throw new AssertionError("No available query marshalers registered");
}
if (marshaler == null) {
// Query each marshaler to see if they support the native/managed type combination
for (MarshalQueryable<?> potentialMarshaler : sRegisteredMarshalQueryables) {
MarshalQueryable<T> castedPotential =
(MarshalQueryable<T>)potentialMarshaler;
if (castedPotential.isTypeMappingSupported(typeToken, nativeType)) {
marshaler = castedPotential.createMarshaler(typeToken, nativeType);
break;
}
}
/*
* Marshalers are instantiated lazily once they are looked up; successive lookups
* will not instantiate new marshalers.
*/
Marshaler<T> marshaler =
(Marshaler<T>) sMarshalerMap.get(marshalToken);
if (marshaler == null) {
throw new UnsupportedOperationException(
if (sRegisteredMarshalQueryables.size() == 0) {
throw new AssertionError("No available query marshalers registered");
}
// Query each marshaler to see if they support the native/managed type combination
for (MarshalQueryable<?> potentialMarshaler : sRegisteredMarshalQueryables) {
MarshalQueryable<T> castedPotential =
(MarshalQueryable<T>)potentialMarshaler;
if (castedPotential.isTypeMappingSupported(typeToken, nativeType)) {
marshaler = castedPotential.createMarshaler(typeToken, nativeType);
break;
}
}
if (marshaler == null) {
throw new UnsupportedOperationException(
"Could not find marshaler that matches the requested " +
"combination of type reference " +
typeToken + " and native type " +
MarshalHelpers.toStringNativeType(nativeType));
"combination of type reference " +
typeToken + " and native type " +
MarshalHelpers.toStringNativeType(nativeType));
}
// Only put when no cached version exists to avoid +0.5ms lookup per call.
sMarshalerMap.put(marshalToken, marshaler);
}
// Only put when no cached version exists to avoid +0.5ms lookup per call.
sMarshalerMap.put(marshalToken, marshaler);
return marshaler;
}
return marshaler;
}
private static class MarshalToken<T> {
@@ -125,9 +130,12 @@ public class MarshalRegistry {
}
}
private static List<MarshalQueryable<?>> sRegisteredMarshalQueryables =
// Control access to the static data structures below
private static final Object sMarshalLock = new Object();
private static final List<MarshalQueryable<?>> sRegisteredMarshalQueryables =
new ArrayList<MarshalQueryable<?>>();
private static HashMap<MarshalToken<?>, Marshaler<?>> sMarshalerMap =
private static final HashMap<MarshalToken<?>, Marshaler<?>> sMarshalerMap =
new HashMap<MarshalToken<?>, Marshaler<?>>();
private MarshalRegistry() {