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 { 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 @Override
public IBinder asBinder() { public IBinder asBinder() {
@@ -1675,11 +1640,14 @@ public class CameraDeviceImpl extends CameraDevice
case ERROR_CAMERA_DEVICE: case ERROR_CAMERA_DEVICE:
case ERROR_CAMERA_SERVICE: case ERROR_CAMERA_SERVICE:
mInError = true; mInError = true;
final int publicErrorCode = (errorCode == ERROR_CAMERA_DEVICE) ?
StateCallback.ERROR_CAMERA_DEVICE :
StateCallback.ERROR_CAMERA_SERVICE;
Runnable r = new Runnable() { Runnable r = new Runnable() {
@Override @Override
public void run() { public void run() {
if (!CameraDeviceImpl.this.isClosed()) { 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() { public void run() {
if (!isClosed()) { if (!isClosed()) {
mDeviceCallback.onError(CameraDeviceImpl.this, 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} * @param queryable a non-{@code null} marshal queryable that supports marshaling {@code T}
*/ */
public static <T> void registerMarshalQueryable(MarshalQueryable<T> queryable) { 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") @SuppressWarnings("unchecked")
public static <T> Marshaler<T> getMarshaler(TypeReference<T> typeToken, int nativeType) { public static <T> Marshaler<T> getMarshaler(TypeReference<T> typeToken, int nativeType) {
// TODO: can avoid making a new token each time by code-genning synchronized(sMarshalLock) {
// the list of type tokens and native types from the keys (at the call sites) // TODO: can avoid making a new token each time by code-genning
MarshalToken<T> marshalToken = new MarshalToken<T>(typeToken, nativeType); // 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 * Marshalers are instantiated lazily once they are looked up; successive lookups
* will not instantiate new marshalers. * will not instantiate new marshalers.
*/ */
Marshaler<T> marshaler = Marshaler<T> marshaler =
(Marshaler<T>) sMarshalerMap.get(marshalToken); (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;
}
}
if (marshaler == null) { 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 " + "Could not find marshaler that matches the requested " +
"combination of type reference " + "combination of type reference " +
typeToken + " and native type " + typeToken + " and native type " +
MarshalHelpers.toStringNativeType(nativeType)); 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. return marshaler;
sMarshalerMap.put(marshalToken, marshaler);
} }
return marshaler;
} }
private static class MarshalToken<T> { 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<?>>(); new ArrayList<MarshalQueryable<?>>();
private static HashMap<MarshalToken<?>, Marshaler<?>> sMarshalerMap = private static final HashMap<MarshalToken<?>, Marshaler<?>> sMarshalerMap =
new HashMap<MarshalToken<?>, Marshaler<?>>(); new HashMap<MarshalToken<?>, Marshaler<?>>();
private MarshalRegistry() { private MarshalRegistry() {