Merge "Camera: Avoid holding locks during extension initialization"

This commit is contained in:
Treehugger Robot
2023-03-14 16:28:27 +00:00
committed by Gerrit Code Review
2 changed files with 105 additions and 81 deletions

View File

@@ -98,15 +98,15 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
// Lock to synchronize cross-thread access to device public interface // Lock to synchronize cross-thread access to device public interface
final Object mInterfaceLock = new Object(); // access from this class and Session only! final Object mInterfaceLock;
/** /**
* @hide * @hide
*/ */
@RequiresPermission(android.Manifest.permission.CAMERA) @RequiresPermission(android.Manifest.permission.CAMERA)
public static CameraAdvancedExtensionSessionImpl createCameraAdvancedExtensionSession( public static CameraAdvancedExtensionSessionImpl createCameraAdvancedExtensionSession(
@NonNull CameraDevice cameraDevice, @NonNull Context ctx, @NonNull android.hardware.camera2.impl.CameraDeviceImpl cameraDevice,
@NonNull ExtensionSessionConfiguration config, int sessionId) @NonNull Context ctx, @NonNull ExtensionSessionConfiguration config, int sessionId)
throws CameraAccessException, RemoteException { throws CameraAccessException, RemoteException {
long clientId = CameraExtensionCharacteristics.registerClient(ctx); long clientId = CameraExtensionCharacteristics.registerClient(ctx);
if (clientId < 0) { if (clientId < 0) {
@@ -183,7 +183,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
} }
private CameraAdvancedExtensionSessionImpl(long extensionClientId, private CameraAdvancedExtensionSessionImpl(long extensionClientId,
@NonNull IAdvancedExtenderImpl extender, @NonNull CameraDevice cameraDevice, @NonNull IAdvancedExtenderImpl extender,
@NonNull android.hardware.camera2.impl.CameraDeviceImpl cameraDevice,
@Nullable Surface repeatingRequestSurface, @Nullable Surface burstCaptureSurface, @Nullable Surface repeatingRequestSurface, @Nullable Surface burstCaptureSurface,
@NonNull CameraExtensionSession.StateCallback callback, @NonNull Executor executor, @NonNull CameraExtensionSession.StateCallback callback, @NonNull Executor executor,
int sessionId) { int sessionId) {
@@ -200,6 +201,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
mInitialized = false; mInitialized = false;
mInitializeHandler = new InitializeSessionHandler(); mInitializeHandler = new InitializeSessionHandler();
mSessionId = sessionId; mSessionId = sessionId;
mInterfaceLock = cameraDevice.mInterfaceLock;
} }
/** /**
@@ -511,6 +513,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
public void onConfigured(@NonNull CameraCaptureSession session) { public void onConfigured(@NonNull CameraCaptureSession session) {
synchronized (mInterfaceLock) { synchronized (mInterfaceLock) {
mCaptureSession = session; mCaptureSession = session;
}
try { try {
CameraExtensionCharacteristics.initializeSession(mInitializeHandler); CameraExtensionCharacteristics.initializeSession(mInitializeHandler);
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -520,11 +524,13 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
} }
} }
} }
}
private class InitializeSessionHandler extends IInitializeSessionCallback.Stub { private class InitializeSessionHandler extends IInitializeSessionCallback.Stub {
@Override @Override
public void onSuccess() { public void onSuccess() {
mHandler.post(new Runnable() {
@Override
public void run() {
boolean status = true; boolean status = true;
synchronized (mInterfaceLock) { synchronized (mInterfaceLock) {
try { try {
@@ -532,40 +538,47 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
mSessionProcessor.onCaptureSessionStart(mRequestProcessor); mSessionProcessor.onCaptureSessionStart(mRequestProcessor);
mInitialized = true; mInitialized = true;
} else { } else {
Log.v(TAG, "Failed to start capture session, session released before " + Log.v(TAG, "Failed to start capture session, session " +
"extension start!"); " released before extension start!");
status = false; status = false;
mCaptureSession.close();
} }
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Failed to start capture session," Log.e(TAG, "Failed to start capture session,"
+ " extension service does not respond!"); + " extension service does not respond!");
status = false; status = false;
mCaptureSession.close(); mInitialized = false;
} }
} }
if (status) { if (status) {
final long ident = Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity();
try { try {
mExecutor.execute( mExecutor.execute(() -> mCallbacks.onConfigured(
() -> mCallbacks.onConfigured(CameraAdvancedExtensionSessionImpl.this)); CameraAdvancedExtensionSessionImpl.this));
} finally { } finally {
Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident);
} }
} else { } else {
notifyConfigurationFailure(); onFailure();
} }
} }
});
}
@Override @Override
public void onFailure() { public void onFailure() {
mHandler.post(new Runnable() {
@Override
public void run() {
mCaptureSession.close(); mCaptureSession.close();
Log.e(TAG, "Failed to initialize proxy service session!" Log.e(TAG, "Failed to initialize proxy service session!"
+ " This can happen when trying to configure multiple " + " This can happen when trying to configure multiple "
+ "concurrent extension sessions!"); + "concurrent extension sessions!");
notifyConfigurationFailure(); notifyConfigurationFailure();
} }
});
}
} }
private final class RequestCallbackHandler extends ICaptureCallback.Stub { private final class RequestCallbackHandler extends ICaptureCallback.Stub {

View File

@@ -114,7 +114,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
private boolean mInternalRepeatingRequestEnabled = true; private boolean mInternalRepeatingRequestEnabled = true;
// Lock to synchronize cross-thread access to device public interface // Lock to synchronize cross-thread access to device public interface
final Object mInterfaceLock = new Object(); // access from this class and Session only! final Object mInterfaceLock;
private static int nativeGetSurfaceFormat(Surface surface) { private static int nativeGetSurfaceFormat(Surface surface) {
return SurfaceUtils.getSurfaceFormat(surface); return SurfaceUtils.getSurfaceFormat(surface);
@@ -125,7 +125,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
*/ */
@RequiresPermission(android.Manifest.permission.CAMERA) @RequiresPermission(android.Manifest.permission.CAMERA)
public static CameraExtensionSessionImpl createCameraExtensionSession( public static CameraExtensionSessionImpl createCameraExtensionSession(
@NonNull CameraDevice cameraDevice, @NonNull android.hardware.camera2.impl.CameraDeviceImpl cameraDevice,
@NonNull Context ctx, @NonNull Context ctx,
@NonNull ExtensionSessionConfiguration config, @NonNull ExtensionSessionConfiguration config,
int sessionId) int sessionId)
@@ -223,7 +223,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
@NonNull IPreviewExtenderImpl previewExtender, @NonNull IPreviewExtenderImpl previewExtender,
@NonNull List<Size> previewSizes, @NonNull List<Size> previewSizes,
long extensionClientId, long extensionClientId,
@NonNull CameraDevice cameraDevice, @NonNull android.hardware.camera2.impl.CameraDeviceImpl cameraDevice,
@Nullable Surface repeatingRequestSurface, @Nullable Surface repeatingRequestSurface,
@Nullable Surface burstCaptureSurface, @Nullable Surface burstCaptureSurface,
@NonNull StateCallback callback, @NonNull StateCallback callback,
@@ -249,6 +249,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
mSupportedRequestKeys = requestKeys; mSupportedRequestKeys = requestKeys;
mSupportedResultKeys = resultKeys; mSupportedResultKeys = resultKeys;
mCaptureResultsSupported = !resultKeys.isEmpty(); mCaptureResultsSupported = !resultKeys.isEmpty();
mInterfaceLock = cameraDevice.mInterfaceLock;
} }
private void initializeRepeatingRequestPipeline() throws RemoteException { private void initializeRepeatingRequestPipeline() throws RemoteException {
@@ -856,6 +857,9 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
private class InitializeSessionHandler extends IInitializeSessionCallback.Stub { private class InitializeSessionHandler extends IInitializeSessionCallback.Stub {
@Override @Override
public void onSuccess() { public void onSuccess() {
mHandler.post(new Runnable() {
@Override
public void run() {
boolean status = true; boolean status = true;
ArrayList<CaptureStageImpl> initialRequestList = ArrayList<CaptureStageImpl> initialRequestList =
compileInitialRequestList(); compileInitialRequestList();
@@ -888,15 +892,22 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
notifyConfigurationFailure(); notifyConfigurationFailure();
} }
} }
});
}
@Override @Override
public void onFailure() { public void onFailure() {
mHandler.post(new Runnable() {
@Override
public void run() {
mCaptureSession.close(); mCaptureSession.close();
Log.e(TAG, "Failed to initialize proxy service session!" Log.e(TAG, "Failed to initialize proxy service session!"
+ " This can happen when trying to configure multiple " + " This can happen when trying to configure multiple "
+ "concurrent extension sessions!"); + "concurrent extension sessions!");
notifyConfigurationFailure(); notifyConfigurationFailure();
} }
});
}
} }
private class BurstRequestHandler extends CameraCaptureSession.CaptureCallback { private class BurstRequestHandler extends CameraCaptureSession.CaptureCallback {