CameraDeviceUserShim.java revision 5398a676809faaf3c6c2875edc1907ad6b8e1c89
1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/* 2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project 3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License. 6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at 7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software 11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and 14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License. 15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpackage android.hardware.camera2.legacy; 18feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.Camera; 20a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.hardware.Camera.CameraInfo; 21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.CameraAccessException; 22a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.hardware.camera2.CameraCharacteristics; 23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.CaptureRequest; 24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.ICameraDeviceCallbacks; 25feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.ICameraDeviceUser; 26feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.LongParcelable; 27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.impl.CameraMetadataNative; 282f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvalaimport android.hardware.camera2.impl.CaptureResultExtras; 29bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yehimport android.hardware.camera2.params.OutputConfiguration; 30feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.CameraBinderDecorator; 31feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.CameraRuntimeException; 32a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.os.ConditionVariable; 33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.IBinder; 34a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.os.Looper; 352f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvalaimport android.os.Handler; 362f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvalaimport android.os.HandlerThread; 372f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvalaimport android.os.Message; 38feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.RemoteException; 39feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.Log; 40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.SparseArray; 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.view.Surface; 42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.ArrayList; 44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.List; 45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 46feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Compatibility implementation of the Camera2 API binder interface. 48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 50feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * This is intended to be called from the same process as client 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.hardware.camera2.CameraDevice}, and wraps a 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.hardware.camera2.legacy.LegacyCameraDevice} that emulates Camera2 service using 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * the Camera1 API. 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Keep up to date with ICameraDeviceUser.aidl. 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 606653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin@SuppressWarnings("deprecation") 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpublic class CameraDeviceUserShim implements ICameraDeviceUser { 62feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final String TAG = "CameraDeviceUserShim"; 63feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG); 65a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private static final int OPEN_CAMERA_TIMEOUT_MS = 5000; // 5 sec (same as api1 cts timeout) 66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final LegacyCameraDevice mLegacyDevice; 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 69feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final Object mConfigureLock = new Object(); 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private int mSurfaceIdCounter; 71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private boolean mConfiguring; 72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final SparseArray<Surface> mSurfaces; 73a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final CameraCharacteristics mCameraCharacteristics; 74a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final CameraLooper mCameraInit; 752f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final CameraCallbackThread mCameraCallbacks; 762f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 78a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin protected CameraDeviceUserShim(int cameraId, LegacyCameraDevice legacyCamera, 792f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCharacteristics characteristics, CameraLooper cameraInit, 802f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCallbackThread cameraCallbacks) { 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mLegacyDevice = legacyCamera; 82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = false; 83feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaces = new SparseArray<Surface>(); 84a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraCharacteristics = characteristics; 85a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraInit = cameraInit; 862f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCameraCallbacks = cameraCallbacks; 87feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 88feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaceIdCounter = 0; 89feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 913084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk private static int translateErrorsFromCamera1(int errorCode) { 923084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk switch (errorCode) { 933084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk case CameraBinderDecorator.EACCES: 943084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk return CameraBinderDecorator.PERMISSION_DENIED; 953084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk default: 963084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk return errorCode; 973084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk } 983084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk } 993084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk 100a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 101a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Create a separate looper/thread for the camera to run on; open the camera. 102a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 103a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * <p>Since the camera automatically latches on to the current thread's looper, 104a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * it's important that we have our own thread with our own looper to guarantee 105a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * that the camera callbacks get correctly posted to our own thread.</p> 106a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 107a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private static class CameraLooper implements Runnable, AutoCloseable { 108a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final int mCameraId; 109a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private Looper mLooper; 110a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private volatile int mInitErrors; 111a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final Camera mCamera = Camera.openUninitialized(); 112a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final ConditionVariable mStartDone = new ConditionVariable(); 113a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final Thread mThread; 114a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 115a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 116a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Spin up a new thread, immediately open the camera in the background. 117a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 118a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * <p>Use {@link #waitForOpen} to block until the camera is finished opening.</p> 119a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 120a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @param cameraId numeric camera Id 121a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 122a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @see #waitForOpen 123a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 124a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public CameraLooper(int cameraId) { 125a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraId = cameraId; 126a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 127a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread = new Thread(this); 128a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread.start(); 129a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 130a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 131a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public Camera getCamera() { 132a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return mCamera; 133a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 134a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 135a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin @Override 136a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public void run() { 137a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Set up a looper to be used by camera. 138a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Looper.prepare(); 139a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 140a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Save the looper so that we can terminate this thread 141a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // after we are done with it. 142a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper = Looper.myLooper(); 1433084c2f5191e560c10a0011f2f77e6d0e3396f92Ruben Brunk mInitErrors = translateErrorsFromCamera1(mCamera.cameraInitUnspecified(mCameraId)); 144a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mStartDone.open(); 145a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Looper.loop(); // Blocks forever until #close is called. 146a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 147a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 148a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 149a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Quit the looper safely; then join until the thread shuts down. 150a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 151a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin @Override 152a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public void close() { 153a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin if (mLooper == null) { 154a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return; 155a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 156a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 157a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper.quitSafely(); 158a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 159a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread.join(); 160a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (InterruptedException e) { 161a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin throw new AssertionError(e); 162a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 163a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 164a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper = null; 165a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 166a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 167a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 168a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Block until the camera opens; then return its initialization error code (if any). 169a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 170a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @param timeoutMs timeout in milliseconds 171a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 172a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @return int error code 173a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 174a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @throws CameraRuntimeException if the camera open times out with ({@code CAMERA_ERROR}) 175a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 176a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public int waitForOpen(int timeoutMs) { 177a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Block until the camera is open asynchronously 178a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin if (!mStartDone.block(timeoutMs)) { 179a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Log.e(TAG, "waitForOpen - Camera failed to open after timeout of " 180a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin + OPEN_CAMERA_TIMEOUT_MS + " ms"); 181a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 182a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCamera.release(); 183a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (RuntimeException e) { 184a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Log.e(TAG, "connectBinderShim - Failed to release camera after timeout ", e); 185a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 186a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 187a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR); 188a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 189a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 190a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return mInitErrors; 191a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 192a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 193a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 1942f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /** 1952f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * A thread to process callbacks to send back to the camera client. 1962f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * 1972f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * <p>This effectively emulates one-way binder semantics when in the same process as the 1982f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * callee.</p> 1992f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala */ 2002f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static class CameraCallbackThread implements ICameraDeviceCallbacks { 2012f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAMERA_ERROR = 0; 2022f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAMERA_IDLE = 1; 2032f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAPTURE_STARTED = 2; 2042f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int RESULT_RECEIVED = 3; 2052f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2062f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final HandlerThread mHandlerThread; 2072f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private Handler mHandler; 2082f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2092f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final ICameraDeviceCallbacks mCallbacks; 2102f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2112f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public CameraCallbackThread(ICameraDeviceCallbacks callbacks) { 2122f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks = callbacks; 2132f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2142f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread = new HandlerThread("LegacyCameraCallback"); 2152f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread.start(); 2162f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2172f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2182f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void close() { 2192f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread.quitSafely(); 2202f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2212f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2222f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 223acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala public void onDeviceError(final int errorCode, final CaptureResultExtras resultExtras) { 2242f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAMERA_ERROR, 2252f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg1*/ errorCode, /*arg2*/ 0, 2262f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultExtras); 2272f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2282f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2292f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2302f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 231acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala public void onDeviceIdle() { 2322f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAMERA_IDLE); 2332f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2342f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2352f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2362f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2372f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) { 2382f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAPTURE_STARTED, 2392f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg1*/ (int) (timestamp & 0xFFFFFFFFL), 2402f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg2*/ (int) ( (timestamp >> 32) & 0xFFFFFFFFL), 2412f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultExtras); 2422f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2432f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2442f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2452f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2462f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void onResultReceived(final CameraMetadataNative result, 2472f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala final CaptureResultExtras resultExtras) { 2482f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Object[] resultArray = new Object[] { result, resultExtras }; 2492f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(RESULT_RECEIVED, 2502f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultArray); 2512f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2522f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2532f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2542f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2552f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public IBinder asBinder() { 2562f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala // This is solely intended to be used for in-process binding. 2572f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return null; 2582f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2592f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2602f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private Handler getHandler() { 2612f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala if (mHandler == null) { 2622f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandler = new CallbackHandler(mHandlerThread.getLooper()); 2632f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2642f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return mHandler; 2652f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2662f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2672f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private class CallbackHandler extends Handler { 2682f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public CallbackHandler(Looper l) { 2692f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala super(l); 2702f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2712f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2726653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin @Override 2732f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void handleMessage(Message msg) { 2742f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala try { 2752f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala switch (msg.what) { 2762f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAMERA_ERROR: { 2772f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala int errorCode = msg.arg1; 2782f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj; 279acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala mCallbacks.onDeviceError(errorCode, resultExtras); 2802f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2812f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2822f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAMERA_IDLE: 283acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala mCallbacks.onDeviceIdle(); 2842f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2852f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAPTURE_STARTED: { 2862f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala long timestamp = msg.arg2 & 0xFFFFFFFFL; 2872f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala timestamp = (timestamp << 32) | (msg.arg1 & 0xFFFFFFFFL); 2882f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj; 2892f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks.onCaptureStarted(resultExtras, timestamp); 2902f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2912f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2922f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case RESULT_RECEIVED: { 2932f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Object[] resultArray = (Object[]) msg.obj; 2942f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraMetadataNative result = (CameraMetadataNative) resultArray[0]; 2952f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) resultArray[1]; 2962f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks.onResultReceived(result, resultExtras); 2972f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2982f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2992f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala default: 3002f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala throw new IllegalArgumentException( 3012f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala "Unknown callback message " + msg.what); 3022f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3032f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } catch (RemoteException e) { 3042f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala throw new IllegalStateException( 3052f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala "Received remote exception during camera callback " + msg.what, e); 3062f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3072f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3082f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3092f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3102f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 311feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public static CameraDeviceUserShim connectBinderShim(ICameraDeviceCallbacks callbacks, 312feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int cameraId) { 313feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 314feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "Opening shim Camera device"); 315feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 316a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 317a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /* 318a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Put the camera open on a separate thread with its own looper; otherwise 319a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * if the main thread is used then the callbacks might never get delivered 320a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * (e.g. in CTS which run its own default looper only after tests) 321a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 322a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 323a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraLooper init = new CameraLooper(cameraId); 324a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 3252f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCallbackThread threadCallbacks = new CameraCallbackThread(callbacks); 3262f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 327a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // TODO: Make this async instead of blocking 328a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin int initErrors = init.waitForOpen(OPEN_CAMERA_TIMEOUT_MS); 329a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Camera legacyCamera = init.getCamera(); 330a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin 331feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Check errors old HAL initialization 332a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin CameraBinderDecorator.throwOnError(initErrors); 333a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin 3346653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin // Disable shutter sounds (this will work unconditionally) for api2 clients 3356653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin legacyCamera.disableShutterSound(); 3366653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin 337a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraInfo info = new CameraInfo(); 338a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Camera.getCameraInfo(cameraId, info); 339a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 340eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala Camera.Parameters legacyParameters = null; 341eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala try { 342eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala legacyParameters = legacyCamera.getParameters(); 343eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala } catch (RuntimeException e) { 344eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR, 345eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala "Unable to get initial parameters", e); 346eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala } 347eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala 348a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraCharacteristics characteristics = 349eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala LegacyMetadataMapper.createCharacteristics(legacyParameters, info); 350df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin LegacyCameraDevice device = new LegacyCameraDevice( 3512f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala cameraId, legacyCamera, characteristics, threadCallbacks); 3522f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return new CameraDeviceUserShim(cameraId, device, characteristics, init, threadCallbacks); 353feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 354feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 356feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void disconnect() { 357feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 358feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "disconnect called."); 359feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 360a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 361e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 362e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.w(TAG, "Cannot disconnect, device has already been closed."); 363e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 364e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 365a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 366a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLegacyDevice.close(); 367a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } finally { 368a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraInit.close(); 3692f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCameraCallbacks.close(); 370a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 371feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 373feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int submitRequest(CaptureRequest request, boolean streaming, 375feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /*out*/LongParcelable lastFrameNumber) { 376feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 377feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "submitRequest called."); 378feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 379e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 380e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot submit request, device has been closed."); 381e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 382e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 383e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 384feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 385feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 386feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot submit request, configuration change in progress."); 387feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 388feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 389feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 390feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mLegacyDevice.submitRequest(request, streaming, lastFrameNumber); 391feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 392feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 393feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 394feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int submitRequestList(List<CaptureRequest> request, boolean streaming, 395feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /*out*/LongParcelable lastFrameNumber) { 396feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 397feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "submitRequestList called."); 398feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 399e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 400e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot submit request list, device has been closed."); 401e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 402e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 403e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 404feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 405feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 406feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot submit request, configuration change in progress."); 407feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 408feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 409feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 410feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mLegacyDevice.submitRequestList(request, streaming, lastFrameNumber); 411feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 412feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 413feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 414feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int cancelRequest(int requestId, /*out*/LongParcelable lastFrameNumber) { 415feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 416feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "cancelRequest called."); 417feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 418e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 419e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot cancel request, device has been closed."); 420e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 421e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 422e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 423feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 424feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 425feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot cancel request, configuration change in progress."); 426feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 427feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 428feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 429feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk long lastFrame = mLegacyDevice.cancelRequest(requestId); 430feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk lastFrameNumber.setNumber(lastFrame); 431feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 432feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 433feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 434feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 435feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int beginConfigure() { 436feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 437feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "beginConfigure called."); 438feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 439e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 440e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot begin configure, device has been closed."); 441e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 442e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 443e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 444feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 445feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 446feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot begin configure, configuration change already in progress."); 447feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 448feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 449feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = true; 450feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 451feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 452feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 453feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 454feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 455feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int endConfigure() { 456feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 457feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "endConfigure called."); 458feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 459e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 460e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot end configure, device has been closed."); 461e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 462e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 463e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 464feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ArrayList<Surface> surfaces = null; 465feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 466feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 467feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot end configure, no configuration change in progress."); 468feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 469feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 470feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int numSurfaces = mSurfaces.size(); 471feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (numSurfaces > 0) { 4725776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk surfaces = new ArrayList<>(); 473feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk for (int i = 0; i < numSurfaces; ++i) { 474feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk surfaces.add(mSurfaces.valueAt(i)); 475feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 476feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 477feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = false; 478feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 479feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mLegacyDevice.configureOutputs(surfaces); 480feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 481feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 482feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 483feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int deleteStream(int streamId) { 484feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 485feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "deleteStream called."); 486feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 487e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 488e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot delete stream, device has been closed."); 489e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 490e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 491e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 492feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 493feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 494feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot delete stream, beginConfigure hasn't been called yet."); 495feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 496feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 497feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int index = mSurfaces.indexOfKey(streamId); 498feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (index < 0) { 499feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot delete stream, stream id " + streamId + " doesn't exist."); 500feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.BAD_VALUE; 501feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 502feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaces.removeAt(index); 503feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 504feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 505feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 506feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 507feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 508bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh public int createStream(OutputConfiguration outputConfiguration) { 509feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 510feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "createStream called."); 511feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 512e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 513e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot create stream, device has been closed."); 514e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 515e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 516e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 517feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 518feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 519feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot create stream, beginConfigure hasn't been called yet."); 520feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 521feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 522bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh if (outputConfiguration.getRotation() != OutputConfiguration.ROTATION_0) { 523bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh Log.e(TAG, "Cannot create stream, stream rotation is not supported."); 524bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh return CameraBinderDecorator.INVALID_OPERATION; 525bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh } 526feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int id = ++mSurfaceIdCounter; 527bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh mSurfaces.put(id, outputConfiguration.getSurface()); 528feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return id; 529feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 530feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 531feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 532feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 5335398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen public int createInputStream(int width, int height, int format) { 5345398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen Log.e(TAG, "creating input stream is not supported on legacy devices"); 5355398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen return CameraBinderDecorator.INVALID_OPERATION; 5365398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen } 5375398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen 5385398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen @Override 5395398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen public int getInputSurface(/*out*/ Surface surface) { 5405398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen Log.e(TAG, "getting input surface is not supported on legacy devices"); 5415398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen return CameraBinderDecorator.INVALID_OPERATION; 5425398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen } 5435398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen 5445398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen @Override 545feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int createDefaultRequest(int templateId, /*out*/CameraMetadataNative request) { 546feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 547feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "createDefaultRequest called."); 548feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 549e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 550e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot create default request, device has been closed."); 551e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 552e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 553a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 554a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraMetadataNative template; 555a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 556a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin template = 557a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin LegacyMetadataMapper.createRequestTemplate(mCameraCharacteristics, templateId); 558a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (IllegalArgumentException e) { 559a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Log.e(TAG, "createDefaultRequest - invalid templateId specified"); 560a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return CameraBinderDecorator.BAD_VALUE; 561a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 562a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 563a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin request.swap(template); 564feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 565feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 566feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 567feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 568feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int getCameraInfo(/*out*/CameraMetadataNative info) { 569feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 570feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "getCameraInfo called."); 571feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 572feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: implement getCameraInfo. 573feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "getCameraInfo unimplemented."); 574feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 575feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 576feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 577feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 578feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int waitUntilIdle() throws RemoteException { 579feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 580feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "waitUntilIdle called."); 581feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 582e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 583e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot wait until idle, device has been closed."); 584e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 585e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 586e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 587feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 588feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 589feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot wait until idle, configuration change in progress."); 590feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 591feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 592feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 593feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mLegacyDevice.waitUntilIdle(); 594feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 595feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 596feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 597feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 598feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int flush(/*out*/LongParcelable lastFrameNumber) { 599feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 600feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "flush called."); 601feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 602e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 603e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.e(TAG, "Cannot flush, device has been closed."); 604e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk return CameraBinderDecorator.ENODEV; 605e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 606e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 607feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 608feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 609feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot flush, configuration change in progress."); 610feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 611feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 612feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 613e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk long lastFrame = mLegacyDevice.flush(); 614e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (lastFrameNumber != null) { 615e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk lastFrameNumber.setNumber(lastFrame); 616e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 617feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 618feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 619feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 620feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 621feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public IBinder asBinder() { 622feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // This is solely intended to be used for in-process binding. 623feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return null; 624feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 625feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 626