CameraDeviceUserShim.java revision 2f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3
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; 29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.CameraBinderDecorator; 30feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.CameraRuntimeException; 31a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.os.ConditionVariable; 32feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.IBinder; 33a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.os.Looper; 342f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvalaimport android.os.Handler; 352f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvalaimport android.os.HandlerThread; 362f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvalaimport android.os.Message; 37feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.RemoteException; 38feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.Log; 39feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.SparseArray; 40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.view.Surface; 41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.ArrayList; 43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.List; 44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 46feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Compatibility implementation of the Camera2 API binder interface. 47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * This is intended to be called from the same process as client 50feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.hardware.camera2.CameraDevice}, and wraps a 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.hardware.camera2.legacy.LegacyCameraDevice} that emulates Camera2 service using 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * the Camera1 API. 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Keep up to date with ICameraDeviceUser.aidl. 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpublic class CameraDeviceUserShim implements ICameraDeviceUser { 60feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final String TAG = "CameraDeviceUserShim"; 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 62feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG); 63a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private static final int OPEN_CAMERA_TIMEOUT_MS = 5000; // 5 sec (same as api1 cts timeout) 64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final LegacyCameraDevice mLegacyDevice; 66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final Object mConfigureLock = new Object(); 68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private int mSurfaceIdCounter; 69feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private boolean mConfiguring; 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final SparseArray<Surface> mSurfaces; 71a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final CameraCharacteristics mCameraCharacteristics; 72a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final CameraLooper mCameraInit; 732f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final CameraCallbackThread mCameraCallbacks; 742f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 76a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin protected CameraDeviceUserShim(int cameraId, LegacyCameraDevice legacyCamera, 772f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCharacteristics characteristics, CameraLooper cameraInit, 782f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCallbackThread cameraCallbacks) { 79feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mLegacyDevice = legacyCamera; 80feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = false; 81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaces = new SparseArray<Surface>(); 82a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraCharacteristics = characteristics; 83a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraInit = cameraInit; 842f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCameraCallbacks = cameraCallbacks; 85feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 86feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaceIdCounter = 0; 87feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 88feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 89a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 90a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Create a separate looper/thread for the camera to run on; open the camera. 91a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 92a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * <p>Since the camera automatically latches on to the current thread's looper, 93a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * it's important that we have our own thread with our own looper to guarantee 94a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * that the camera callbacks get correctly posted to our own thread.</p> 95a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 96a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private static class CameraLooper implements Runnable, AutoCloseable { 97a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final int mCameraId; 98a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private Looper mLooper; 99a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private volatile int mInitErrors; 100a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final Camera mCamera = Camera.openUninitialized(); 101a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final ConditionVariable mStartDone = new ConditionVariable(); 102a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final Thread mThread; 103a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 104a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 105a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Spin up a new thread, immediately open the camera in the background. 106a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 107a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * <p>Use {@link #waitForOpen} to block until the camera is finished opening.</p> 108a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 109a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @param cameraId numeric camera Id 110a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 111a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @see #waitForOpen 112a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 113a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public CameraLooper(int cameraId) { 114a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraId = cameraId; 115a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 116a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread = new Thread(this); 117a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread.start(); 118a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 119a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 120a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public Camera getCamera() { 121a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return mCamera; 122a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 123a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 124a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin @Override 125a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public void run() { 126a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Set up a looper to be used by camera. 127a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Looper.prepare(); 128a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 129a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Save the looper so that we can terminate this thread 130a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // after we are done with it. 131a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper = Looper.myLooper(); 132a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mInitErrors = mCamera.cameraInitUnspecified(mCameraId); 133a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 134a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mStartDone.open(); 135a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Looper.loop(); // Blocks forever until #close is called. 136a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 137a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 138a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 139a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Quit the looper safely; then join until the thread shuts down. 140a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 141a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin @Override 142a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public void close() { 143a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin if (mLooper == null) { 144a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return; 145a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 146a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 147a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper.quitSafely(); 148a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 149a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread.join(); 150a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (InterruptedException e) { 151a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin throw new AssertionError(e); 152a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 153a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 154a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper = null; 155a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 156a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 157a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 158a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Block until the camera opens; then return its initialization error code (if any). 159a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 160a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @param timeoutMs timeout in milliseconds 161a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 162a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @return int error code 163a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 164a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @throws CameraRuntimeException if the camera open times out with ({@code CAMERA_ERROR}) 165a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 166a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public int waitForOpen(int timeoutMs) { 167a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Block until the camera is open asynchronously 168a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin if (!mStartDone.block(timeoutMs)) { 169a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Log.e(TAG, "waitForOpen - Camera failed to open after timeout of " 170a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin + OPEN_CAMERA_TIMEOUT_MS + " ms"); 171a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 172a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCamera.release(); 173a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (RuntimeException e) { 174a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Log.e(TAG, "connectBinderShim - Failed to release camera after timeout ", e); 175a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 176a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 177a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR); 178a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 179a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 180a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return mInitErrors; 181a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 182a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 183a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 1842f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /** 1852f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * A thread to process callbacks to send back to the camera client. 1862f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * 1872f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * <p>This effectively emulates one-way binder semantics when in the same process as the 1882f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * callee.</p> 1892f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala */ 1902f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static class CameraCallbackThread implements ICameraDeviceCallbacks { 1912f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAMERA_ERROR = 0; 1922f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAMERA_IDLE = 1; 1932f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAPTURE_STARTED = 2; 1942f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int RESULT_RECEIVED = 3; 1952f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 1962f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final HandlerThread mHandlerThread; 1972f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private Handler mHandler; 1982f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 1992f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final ICameraDeviceCallbacks mCallbacks; 2002f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2012f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public CameraCallbackThread(ICameraDeviceCallbacks callbacks) { 2022f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks = callbacks; 2032f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2042f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread = new HandlerThread("LegacyCameraCallback"); 2052f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread.start(); 2062f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2072f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2082f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void close() { 2092f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread.quitSafely(); 2102f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2112f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2122f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2132f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void onCameraError(final int errorCode, final CaptureResultExtras resultExtras) { 2142f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAMERA_ERROR, 2152f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg1*/ errorCode, /*arg2*/ 0, 2162f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultExtras); 2172f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2182f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2192f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2202f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2212f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void onCameraIdle() { 2222f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAMERA_IDLE); 2232f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2242f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2252f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2262f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2272f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) { 2282f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAPTURE_STARTED, 2292f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg1*/ (int) (timestamp & 0xFFFFFFFFL), 2302f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg2*/ (int) ( (timestamp >> 32) & 0xFFFFFFFFL), 2312f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultExtras); 2322f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2332f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2342f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2352f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2362f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void onResultReceived(final CameraMetadataNative result, 2372f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala final CaptureResultExtras resultExtras) { 2382f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Object[] resultArray = new Object[] { result, resultExtras }; 2392f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(RESULT_RECEIVED, 2402f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultArray); 2412f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2422f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2432f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2442f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2452f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public IBinder asBinder() { 2462f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala // This is solely intended to be used for in-process binding. 2472f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return null; 2482f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2492f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2502f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private Handler getHandler() { 2512f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala if (mHandler == null) { 2522f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandler = new CallbackHandler(mHandlerThread.getLooper()); 2532f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2542f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return mHandler; 2552f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2562f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2572f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private class CallbackHandler extends Handler { 2582f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public CallbackHandler(Looper l) { 2592f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala super(l); 2602f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2612f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2622f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void handleMessage(Message msg) { 2632f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala try { 2642f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala switch (msg.what) { 2652f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAMERA_ERROR: { 2662f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala int errorCode = msg.arg1; 2672f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj; 2682f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks.onCameraError(errorCode, resultExtras); 2692f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2702f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2712f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAMERA_IDLE: 2722f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks.onCameraIdle(); 2732f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2742f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAPTURE_STARTED: { 2752f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala long timestamp = msg.arg2 & 0xFFFFFFFFL; 2762f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala timestamp = (timestamp << 32) | (msg.arg1 & 0xFFFFFFFFL); 2772f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj; 2782f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks.onCaptureStarted(resultExtras, timestamp); 2792f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2802f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2812f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case RESULT_RECEIVED: { 2822f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Object[] resultArray = (Object[]) msg.obj; 2832f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraMetadataNative result = (CameraMetadataNative) resultArray[0]; 2842f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) resultArray[1]; 2852f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks.onResultReceived(result, resultExtras); 2862f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2872f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2882f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala default: 2892f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala throw new IllegalArgumentException( 2902f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala "Unknown callback message " + msg.what); 2912f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2922f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } catch (RemoteException e) { 2932f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala throw new IllegalStateException( 2942f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala "Received remote exception during camera callback " + msg.what, e); 2952f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2962f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2972f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2982f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2992f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 300feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public static CameraDeviceUserShim connectBinderShim(ICameraDeviceCallbacks callbacks, 301feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int cameraId) { 302feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 303feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "Opening shim Camera device"); 304feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 305a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 306a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /* 307a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Put the camera open on a separate thread with its own looper; otherwise 308a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * if the main thread is used then the callbacks might never get delivered 309a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * (e.g. in CTS which run its own default looper only after tests) 310a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 311a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 312a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraLooper init = new CameraLooper(cameraId); 313a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 3142f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCallbackThread threadCallbacks = new CameraCallbackThread(callbacks); 3152f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 316a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // TODO: Make this async instead of blocking 317a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin int initErrors = init.waitForOpen(OPEN_CAMERA_TIMEOUT_MS); 318a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Camera legacyCamera = init.getCamera(); 319a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin 320feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Check errors old HAL initialization 321a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin CameraBinderDecorator.throwOnError(initErrors); 322a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin 323a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraInfo info = new CameraInfo(); 324a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Camera.getCameraInfo(cameraId, info); 325a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 326a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraCharacteristics characteristics = 327a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin LegacyMetadataMapper.createCharacteristics(legacyCamera.getParameters(), info); 328df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin LegacyCameraDevice device = new LegacyCameraDevice( 3292f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala cameraId, legacyCamera, characteristics, threadCallbacks); 3302f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return new CameraDeviceUserShim(cameraId, device, characteristics, init, threadCallbacks); 331feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 332feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 333feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 334feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void disconnect() { 335feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 336feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "disconnect called."); 337feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 338a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 339a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 340a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLegacyDevice.close(); 341a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } finally { 342a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraInit.close(); 3432f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCameraCallbacks.close(); 344a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 345feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 346feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 347feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 348feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int submitRequest(CaptureRequest request, boolean streaming, 349feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /*out*/LongParcelable lastFrameNumber) { 350feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 351feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "submitRequest called."); 352feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 353feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 354feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot submit request, configuration change in progress."); 356feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 357feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 358feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 359feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mLegacyDevice.submitRequest(request, streaming, lastFrameNumber); 360feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 361feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 362feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 363feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int submitRequestList(List<CaptureRequest> request, boolean streaming, 364feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk /*out*/LongParcelable lastFrameNumber) { 365feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 366feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "submitRequestList called."); 367feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 368feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 369feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 370feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot submit request, configuration change in progress."); 371feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 373feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mLegacyDevice.submitRequestList(request, streaming, lastFrameNumber); 375feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 376feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 377feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 378feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int cancelRequest(int requestId, /*out*/LongParcelable lastFrameNumber) { 379feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 380feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "cancelRequest called."); 381feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 382feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 383feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 384feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot cancel request, configuration change in progress."); 385feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 386feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 387feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 388feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk long lastFrame = mLegacyDevice.cancelRequest(requestId); 389feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk lastFrameNumber.setNumber(lastFrame); 390feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 391feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 392feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 393feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 394feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int beginConfigure() { 395feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 396feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "beginConfigure called."); 397feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 398feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 399feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 400feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot begin configure, configuration change already in progress."); 401feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 402feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 403feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = true; 404feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 405feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 406feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 407feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 408feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 409feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int endConfigure() { 410feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 411feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "endConfigure called."); 412feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 413feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ArrayList<Surface> surfaces = null; 414feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 415feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 416feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot end configure, no configuration change in progress."); 417feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 418feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 419feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int numSurfaces = mSurfaces.size(); 420feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (numSurfaces > 0) { 4215776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk surfaces = new ArrayList<>(); 422feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk for (int i = 0; i < numSurfaces; ++i) { 423feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk surfaces.add(mSurfaces.valueAt(i)); 424feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 425feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 426feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = false; 427feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 428feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return mLegacyDevice.configureOutputs(surfaces); 429feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 430feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 431feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 432feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int deleteStream(int streamId) { 433feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 434feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "deleteStream called."); 435feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 436feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 437feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 438feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot delete stream, beginConfigure hasn't been called yet."); 439feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 440feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int index = mSurfaces.indexOfKey(streamId); 442feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (index < 0) { 443feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot delete stream, stream id " + streamId + " doesn't exist."); 444feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.BAD_VALUE; 445feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 446feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaces.removeAt(index); 447feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 448feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 449feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 450feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 451feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 452feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int createStream(int width, int height, int format, Surface surface) { 453feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 454feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "createStream called."); 455feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 456feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 457feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 458feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot create stream, beginConfigure hasn't been called yet."); 459feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 460feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 461feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int id = ++mSurfaceIdCounter; 462feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaces.put(id, surface); 463feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return id; 464feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 465feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 466feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 467feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 468feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int createDefaultRequest(int templateId, /*out*/CameraMetadataNative request) { 469feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 470feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "createDefaultRequest called."); 471feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 472a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 473a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraMetadataNative template; 474a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 475a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin template = 476a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin LegacyMetadataMapper.createRequestTemplate(mCameraCharacteristics, templateId); 477a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (IllegalArgumentException e) { 478a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Log.e(TAG, "createDefaultRequest - invalid templateId specified"); 479a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return CameraBinderDecorator.BAD_VALUE; 480a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 481a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 482a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin request.swap(template); 483feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 484feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 485feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 486feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 487feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int getCameraInfo(/*out*/CameraMetadataNative info) { 488feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 489feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "getCameraInfo called."); 490feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 491feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: implement getCameraInfo. 492feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "getCameraInfo unimplemented."); 493feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 494feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 495feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 496feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 497feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int waitUntilIdle() throws RemoteException { 498feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 499feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "waitUntilIdle called."); 500feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 501feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 502feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 503feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot wait until idle, configuration change in progress."); 504feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 505feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 506feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 507feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mLegacyDevice.waitUntilIdle(); 508feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 509feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 510feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 511feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 512feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public int flush(/*out*/LongParcelable lastFrameNumber) { 513feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 514feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "flush called."); 515feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 516feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 517feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 518feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "Cannot flush, configuration change in progress."); 519feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.INVALID_OPERATION; 520feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 521feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 522feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: implement flush. 523feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return CameraBinderDecorator.NO_ERROR; 524feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 525feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 526feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 527feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public IBinder asBinder() { 528feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // This is solely intended to be used for in-process binding. 529feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return null; 530feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 531feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 532