diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java index 5b259f71feda0..5cfba3d945cda 100644 --- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java @@ -25,6 +25,7 @@ import android.graphics.ImageFormat; import android.hardware.camera2.extension.IAdvancedExtenderImpl; import android.hardware.camera2.extension.ICameraExtensionsProxyService; import android.hardware.camera2.extension.IImageCaptureExtenderImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; import android.hardware.camera2.extension.IPreviewExtenderImpl; import android.hardware.camera2.extension.LatencyRange; import android.hardware.camera2.extension.SizeList; @@ -357,6 +358,27 @@ public final class CameraExtensionCharacteristics { } } + public void initializeSession(IInitializeSessionCallback cb) throws RemoteException { + synchronized (mLock) { + if (mProxy != null) { + mProxy.initializeSession(cb); + } + } + } + + public void releaseSession() { + synchronized (mLock) { + if (mProxy != null) { + try { + mProxy.releaseSession(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to release session! Extension service does" + + " not respond!"); + } + } + } + } + public boolean areAdvancedExtensionsSupported() { return mSupportsAdvancedExtensions; } @@ -409,6 +431,20 @@ public final class CameraExtensionCharacteristics { CameraExtensionManagerGlobal.get().unregisterClient(clientId); } + /** + * @hide + */ + public static void initializeSession(IInitializeSessionCallback cb) throws RemoteException { + CameraExtensionManagerGlobal.get().initializeSession(cb); + } + + /** + * @hide + */ + public static void releaseSession() { + CameraExtensionManagerGlobal.get().releaseSession(); + } + /** * @hide */ diff --git a/core/java/android/hardware/camera2/CameraExtensionSession.java b/core/java/android/hardware/camera2/CameraExtensionSession.java index e1b817768461a..5892f682dd494 100644 --- a/core/java/android/hardware/camera2/CameraExtensionSession.java +++ b/core/java/android/hardware/camera2/CameraExtensionSession.java @@ -195,8 +195,9 @@ public abstract class CameraExtensionSession implements AutoCloseable { * This method is called if the session cannot be configured as requested. * *
This can happen if the set of requested outputs contains unsupported sizes, - * too many outputs are requested at once or the camera device encounters an - * unrecoverable error during configuration.
+ * too many outputs are requested at once or when trying to initialize multiple + * concurrent extension sessions from two (or more) separate camera devices + * or the camera device encounters an unrecoverable error during configuration. * *The session is considered to be closed, and all methods called on it after this * callback is invoked will throw an IllegalStateException.
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index a1c8d29566bee..5833b3dbef869 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -162,6 +162,9 @@ public final class CameraManager { *The set of combinations may include camera devices that may be in use by other camera API * clients.
* + *Concurrent camera extension sessions {@link CameraExtensionSession} are not currently + * supported.
+ * *The set of combinations doesn't contain physical cameras that can only be used as * part of a logical multi-camera device.
* diff --git a/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl b/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl index bc29e9a481aed..b52c650086f4a 100644 --- a/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl +++ b/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl @@ -18,6 +18,7 @@ package android.hardware.camera2.extension; import android.hardware.camera2.extension.IAdvancedExtenderImpl; import android.hardware.camera2.extension.IPreviewExtenderImpl; import android.hardware.camera2.extension.IImageCaptureExtenderImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; /** @hide */ interface ICameraExtensionsProxyService @@ -25,6 +26,8 @@ interface ICameraExtensionsProxyService long registerClient(); void unregisterClient(long clientId); boolean advancedExtensionsSupported(); + void initializeSession(in IInitializeSessionCallback cb); + void releaseSession(); @nullable IPreviewExtenderImpl initializePreviewExtension(int extensionType); @nullable IImageCaptureExtenderImpl initializeImageExtension(int extensionType); @nullable IAdvancedExtenderImpl initializeAdvancedExtension(int extensionType); diff --git a/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl b/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl new file mode 100644 index 0000000000000..1747760d7d8cc --- /dev/null +++ b/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.camera2.extension; + +/** @hide */ +interface IInitializeSessionCallback +{ + void onSuccess(); + void onFailure(); +} diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java index 5cf50a25de78c..bfc1f2765c3b9 100644 --- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java @@ -35,9 +35,11 @@ import android.hardware.camera2.CaptureResult; import android.hardware.camera2.TotalCaptureResult; import android.hardware.camera2.extension.CameraOutputConfig; import android.hardware.camera2.extension.CameraSessionConfig; +import android.hardware.camera2.extension.CaptureStageImpl; import android.hardware.camera2.extension.IAdvancedExtenderImpl; import android.hardware.camera2.extension.ICaptureCallback; import android.hardware.camera2.extension.IImageProcessorImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; import android.hardware.camera2.extension.IRequestCallback; import android.hardware.camera2.extension.IRequestProcessorImpl; import android.hardware.camera2.extension.ISessionProcessorImpl; @@ -89,6 +91,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private Surface mClientCaptureSurface; private CameraCaptureSession mCaptureSession = null; private ISessionProcessorImpl mSessionProcessor = null; + private final InitializeSessionHandler mInitializeHandler; private boolean mInitialized; @@ -181,6 +184,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mInitialized = false; + mInitializeHandler = new InitializeSessionHandler(); } /** @@ -444,7 +448,6 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes public void release() { synchronized (mInterfaceLock) { - mInitialized = false; mHandlerThread.quitSafely(); if (mSessionProcessor != null) { @@ -459,7 +462,11 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes if (mExtensionClientId >= 0) { CameraExtensionCharacteristics.unregisterClient(mExtensionClientId); + if (mInitialized) { + CameraExtensionCharacteristics.releaseSession(); + } } + mInitialized = false; for (ImageReader reader : mReaderMap.values()) { reader.close(); @@ -512,9 +519,24 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes @Override public void onConfigured(@NonNull CameraCaptureSession session) { - boolean status = true; synchronized (mInterfaceLock) { mCaptureSession = session; + try { + CameraExtensionCharacteristics.initializeSession(mInitializeHandler); + } catch (RemoteException e) { + Log.e(TAG, "Failed to initialize session! Extension service does" + + " not respond!"); + notifyConfigurationFailure(); + } + } + } + } + + private class InitializeSessionHandler extends IInitializeSessionCallback.Stub { + @Override + public void onSuccess() { + boolean status = true; + synchronized (mInterfaceLock) { try { mSessionProcessor.onCaptureSessionStart(mRequestProcessor); mInitialized = true; @@ -522,7 +544,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes Log.e(TAG, "Failed to start capture session," + " extension service does not respond!"); status = false; - session.close(); + mCaptureSession.close(); } } @@ -538,6 +560,15 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes notifyConfigurationFailure(); } } + + @Override + public void onFailure() { + mCaptureSession.close(); + Log.e(TAG, "Failed to initialize proxy service session!" + + " This can happen when trying to configure multiple " + + "concurrent extension sessions!"); + notifyConfigurationFailure(); + } } private final class RequestCallbackHandler extends ICaptureCallback.Stub { diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java index 4bcc4942d8a05..537b894d9a6a6 100644 --- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java @@ -34,6 +34,7 @@ import android.hardware.camera2.extension.CaptureBundle; import android.hardware.camera2.extension.CaptureStageImpl; import android.hardware.camera2.extension.ICaptureProcessorImpl; import android.hardware.camera2.extension.IImageCaptureExtenderImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; import android.hardware.camera2.extension.IPreviewExtenderImpl; import android.hardware.camera2.extension.IRequestUpdateProcessorImpl; import android.hardware.camera2.extension.ParcelImage; @@ -48,6 +49,8 @@ import android.media.ImageWriter; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; +import android.os.IBinder; +import android.os.IInterface; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.annotation.NonNull; @@ -80,6 +83,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { private final HandlerThread mHandlerThread; private final StateCallback mCallbacks; private final List