CameraDeviceUserShim.java revision 5d2d7788f1759b0f3d2c057af0b3ea61b0354fee
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 195d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvalaimport android.hardware.ICameraService; 20feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.Camera; 21a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.hardware.Camera.CameraInfo; 22feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.CameraAccessException; 23a296fece2b974a11bc624fd67b275863f17df867Igor Murashkinimport android.hardware.camera2.CameraCharacteristics; 24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.CaptureRequest; 25feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.ICameraDeviceCallbacks; 26feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.ICameraDeviceUser; 27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.impl.CameraMetadataNative; 282f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvalaimport android.hardware.camera2.impl.CaptureResultExtras; 29bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yehimport android.hardware.camera2.params.OutputConfiguration; 305d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvalaimport android.hardware.camera2.utils.SubmitInfo; 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; 385d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvalaimport android.os.ServiceSpecificException; 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 468ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsicimport static android.system.OsConstants.EACCES; 478ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsicimport static android.system.OsConstants.ENODEV; 488ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic 49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/** 50feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Compatibility implementation of the Camera2 API binder interface. 51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * This is intended to be called from the same process as client 54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.hardware.camera2.CameraDevice}, and wraps a 55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.hardware.camera2.legacy.LegacyCameraDevice} that emulates Camera2 service using 56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * the Camera1 API. 57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * 59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p> 60feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Keep up to date with ICameraDeviceUser.aidl. 61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p> 62feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */ 636653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin@SuppressWarnings("deprecation") 64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpublic class CameraDeviceUserShim implements ICameraDeviceUser { 65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private static final String TAG = "CameraDeviceUserShim"; 66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 67a78791f22af6c6985d186494737468bb19b69540Eino-Ville Talvala private static final boolean DEBUG = false; 68a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private static final int OPEN_CAMERA_TIMEOUT_MS = 5000; // 5 sec (same as api1 cts timeout) 69feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final LegacyCameraDevice mLegacyDevice; 71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final Object mConfigureLock = new Object(); 73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private int mSurfaceIdCounter; 74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private boolean mConfiguring; 75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk private final SparseArray<Surface> mSurfaces; 76a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final CameraCharacteristics mCameraCharacteristics; 77a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final CameraLooper mCameraInit; 782f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final CameraCallbackThread mCameraCallbacks; 792f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 80feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 81a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin protected CameraDeviceUserShim(int cameraId, LegacyCameraDevice legacyCamera, 822f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCharacteristics characteristics, CameraLooper cameraInit, 832f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCallbackThread cameraCallbacks) { 84feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mLegacyDevice = legacyCamera; 85feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = false; 86feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaces = new SparseArray<Surface>(); 87a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraCharacteristics = characteristics; 88a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraInit = cameraInit; 892f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCameraCallbacks = cameraCallbacks; 90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaceIdCounter = 0; 92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 948ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic private static int translateErrorsFromCamera1(int errorCode) { 958ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic if (errorCode == -EACCES) { 965d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala return ICameraService.ERROR_PERMISSION_DENIED; 978ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic } 988ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic 998ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic return errorCode; 1008ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic } 1018ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic 102a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 103a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Create a separate looper/thread for the camera to run on; open the camera. 104a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 105a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * <p>Since the camera automatically latches on to the current thread's looper, 106a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * it's important that we have our own thread with our own looper to guarantee 107a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * that the camera callbacks get correctly posted to our own thread.</p> 108a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 109a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private static class CameraLooper implements Runnable, AutoCloseable { 110a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final int mCameraId; 111a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private Looper mLooper; 112a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private volatile int mInitErrors; 113a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final Camera mCamera = Camera.openUninitialized(); 114a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final ConditionVariable mStartDone = new ConditionVariable(); 115a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin private final Thread mThread; 116a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 117a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 118a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Spin up a new thread, immediately open the camera in the background. 119a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 120a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * <p>Use {@link #waitForOpen} to block until the camera is finished opening.</p> 121a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 122a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @param cameraId numeric camera Id 123a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 124a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @see #waitForOpen 125a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 126a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public CameraLooper(int cameraId) { 127a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraId = cameraId; 128a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 129a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread = new Thread(this); 130a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread.start(); 131a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 132a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 133a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public Camera getCamera() { 134a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return mCamera; 135a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 136a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 137a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin @Override 138a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public void run() { 139a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Set up a looper to be used by camera. 140a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Looper.prepare(); 141a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 142a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Save the looper so that we can terminate this thread 143a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // after we are done with it. 144a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper = Looper.myLooper(); 145db70a9785315a29c1d0d1233d883062b8d07c46fEino-Ville Talvala mInitErrors = mCamera.cameraInitUnspecified(mCameraId); 146a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mStartDone.open(); 147a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Looper.loop(); // Blocks forever until #close is called. 148a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 149a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 150a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 151a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Quit the looper safely; then join until the thread shuts down. 152a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 153a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin @Override 154a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public void close() { 155a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin if (mLooper == null) { 156a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return; 157a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 158a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 159a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper.quitSafely(); 160a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 161a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mThread.join(); 162a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (InterruptedException e) { 163a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin throw new AssertionError(e); 164a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 165a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 166a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLooper = null; 167a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 168a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 169a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /** 170a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Block until the camera opens; then return its initialization error code (if any). 171a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 172a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @param timeoutMs timeout in milliseconds 173a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 174a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * @return int error code 175a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * 1765d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala * @throws ServiceSpecificException if the camera open times out with ({@code CAMERA_ERROR}) 177a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 178a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin public int waitForOpen(int timeoutMs) { 179a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // Block until the camera is open asynchronously 180a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin if (!mStartDone.block(timeoutMs)) { 181a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Log.e(TAG, "waitForOpen - Camera failed to open after timeout of " 182a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin + OPEN_CAMERA_TIMEOUT_MS + " ms"); 183a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 184a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCamera.release(); 185a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (RuntimeException e) { 186a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Log.e(TAG, "connectBinderShim - Failed to release camera after timeout ", e); 187a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 188a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 1895d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION); 190a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 191a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 192a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin return mInitErrors; 193a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 194a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 195a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 1962f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /** 1972f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * A thread to process callbacks to send back to the camera client. 1982f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * 1992f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * <p>This effectively emulates one-way binder semantics when in the same process as the 2002f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala * callee.</p> 2012f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala */ 2022f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static class CameraCallbackThread implements ICameraDeviceCallbacks { 2032f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAMERA_ERROR = 0; 2042f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAMERA_IDLE = 1; 2052f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int CAPTURE_STARTED = 2; 2062f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private static final int RESULT_RECEIVED = 3; 207be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala private static final int PREPARED = 4; 2082f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2092f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final HandlerThread mHandlerThread; 2102f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private Handler mHandler; 2112f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2122f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private final ICameraDeviceCallbacks mCallbacks; 2132f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2142f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public CameraCallbackThread(ICameraDeviceCallbacks callbacks) { 2152f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks = callbacks; 2162f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2172f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread = new HandlerThread("LegacyCameraCallback"); 2182f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread.start(); 2192f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2202f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2212f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void close() { 2222f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandlerThread.quitSafely(); 2232f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2242f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2252f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 226acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala public void onDeviceError(final int errorCode, final CaptureResultExtras resultExtras) { 2272f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAMERA_ERROR, 2282f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg1*/ errorCode, /*arg2*/ 0, 2292f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultExtras); 2302f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2312f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2322f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2332f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 234acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala public void onDeviceIdle() { 2352f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAMERA_IDLE); 2362f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2372f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2382f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2392f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2402f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) { 2412f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(CAPTURE_STARTED, 2422f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg1*/ (int) (timestamp & 0xFFFFFFFFL), 2432f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*arg2*/ (int) ( (timestamp >> 32) & 0xFFFFFFFFL), 2442f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultExtras); 2452f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2462f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2472f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2482f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 2492f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void onResultReceived(final CameraMetadataNative result, 2502f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala final CaptureResultExtras resultExtras) { 2512f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Object[] resultArray = new Object[] { result, resultExtras }; 2522f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Message msg = getHandler().obtainMessage(RESULT_RECEIVED, 2532f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala /*obj*/ resultArray); 2542f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala getHandler().sendMessage(msg); 2552f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2562f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2572f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala @Override 258ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala public void onPrepared(int streamId) { 259be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala Message msg = getHandler().obtainMessage(PREPARED, 260be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala /*arg1*/ streamId, /*arg2*/ 0); 261be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala getHandler().sendMessage(msg); 262ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala } 263ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala 264ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala @Override 2652f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public IBinder asBinder() { 2662f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala // This is solely intended to be used for in-process binding. 2672f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return null; 2682f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2692f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2702f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private Handler getHandler() { 2712f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala if (mHandler == null) { 2722f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mHandler = new CallbackHandler(mHandlerThread.getLooper()); 2732f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2742f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return mHandler; 2752f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2762f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2772f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala private class CallbackHandler extends Handler { 2782f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public CallbackHandler(Looper l) { 2792f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala super(l); 2802f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2812f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 2826653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin @Override 2832f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala public void handleMessage(Message msg) { 2842f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala try { 2852f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala switch (msg.what) { 2862f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAMERA_ERROR: { 2872f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala int errorCode = msg.arg1; 2882f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj; 289acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala mCallbacks.onDeviceError(errorCode, resultExtras); 2902f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2912f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 2922f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAMERA_IDLE: 293acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala mCallbacks.onDeviceIdle(); 2942f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 2952f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case CAPTURE_STARTED: { 2962f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala long timestamp = msg.arg2 & 0xFFFFFFFFL; 2972f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala timestamp = (timestamp << 32) | (msg.arg1 & 0xFFFFFFFFL); 2982f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj; 2992f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks.onCaptureStarted(resultExtras, timestamp); 3002f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 3012f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3022f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala case RESULT_RECEIVED: { 3032f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala Object[] resultArray = (Object[]) msg.obj; 3042f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraMetadataNative result = (CameraMetadataNative) resultArray[0]; 3052f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CaptureResultExtras resultExtras = (CaptureResultExtras) resultArray[1]; 3062f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCallbacks.onResultReceived(result, resultExtras); 3072f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala break; 3082f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 309be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala case PREPARED: { 310be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala int streamId = msg.arg1; 311be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala mCallbacks.onPrepared(streamId); 312be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala break; 313be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala } 3142f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala default: 3152f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala throw new IllegalArgumentException( 3162f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala "Unknown callback message " + msg.what); 3172f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3182f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } catch (RemoteException e) { 3192f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala throw new IllegalStateException( 3202f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala "Received remote exception during camera callback " + msg.what, e); 3212f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3222f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3232f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3242f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala } 3252f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 326feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public static CameraDeviceUserShim connectBinderShim(ICameraDeviceCallbacks callbacks, 327feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int cameraId) { 328feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 329feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "Opening shim Camera device"); 330feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 331a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 332a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin /* 333a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * Put the camera open on a separate thread with its own looper; otherwise 334a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * if the main thread is used then the callbacks might never get delivered 335a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin * (e.g. in CTS which run its own default looper only after tests) 336a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin */ 337a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 338a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraLooper init = new CameraLooper(cameraId); 339a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 3402f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala CameraCallbackThread threadCallbacks = new CameraCallbackThread(callbacks); 3412f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala 342a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin // TODO: Make this async instead of blocking 343a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin int initErrors = init.waitForOpen(OPEN_CAMERA_TIMEOUT_MS); 344a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Camera legacyCamera = init.getCamera(); 345a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin 346feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // Check errors old HAL initialization 3475d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala LegacyExceptionUtils.throwOnServiceError(initErrors); 348a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin 3496653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin // Disable shutter sounds (this will work unconditionally) for api2 clients 3506653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin legacyCamera.disableShutterSound(); 3516653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin 352a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraInfo info = new CameraInfo(); 353a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin Camera.getCameraInfo(cameraId, info); 354a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 355eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala Camera.Parameters legacyParameters = null; 356eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala try { 357eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala legacyParameters = legacyCamera.getParameters(); 358eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala } catch (RuntimeException e) { 3595d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, 3605d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala "Unable to get initial parameters: " + e.getMessage()); 361eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala } 362eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala 363a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraCharacteristics characteristics = 364eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala LegacyMetadataMapper.createCharacteristics(legacyParameters, info); 365df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin LegacyCameraDevice device = new LegacyCameraDevice( 3662f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala cameraId, legacyCamera, characteristics, threadCallbacks); 3672f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala return new CameraDeviceUserShim(cameraId, device, characteristics, init, threadCallbacks); 368feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 369feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 370feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 371feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public void disconnect() { 372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 373feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "disconnect called."); 374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 375a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 376e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 377e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk Log.w(TAG, "Cannot disconnect, device has already been closed."); 378e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 379e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 380a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 381a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mLegacyDevice.close(); 382a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } finally { 383a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin mCameraInit.close(); 3842f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala mCameraCallbacks.close(); 385a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 386feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 387feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 388feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 3895d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public SubmitInfo submitRequest(CaptureRequest request, boolean streaming) { 390feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 391feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "submitRequest called."); 392feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 393e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 3945d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot submit request, device has been closed."; 3955d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 3965d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 397e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 398e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 399feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 400feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 4015d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot submit request, configuration change in progress."; 4025d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4035d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 404feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 405feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 4065d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala return mLegacyDevice.submitRequest(request, streaming); 407feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 408feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 409feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 4105d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public SubmitInfo submitRequestList(CaptureRequest[] request, boolean streaming) { 411feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 412feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "submitRequestList called."); 413feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 414e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 4155d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot submit request list, device has been closed."; 4165d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4175d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 418e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 419e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 420feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 421feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 4225d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot submit request, configuration change in progress."; 4235d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4245d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 425feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 426feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 4275d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala return mLegacyDevice.submitRequestList(request, streaming); 428feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 429feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 430feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 4315d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public long cancelRequest(int requestId) { 432feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 433feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "cancelRequest called."); 434feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 435e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 4365d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot cancel request, device has been closed."; 4375d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4385d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 439e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 440e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 442feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 4435d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot cancel request, configuration change in progress."; 4445d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4455d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 446feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 447feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 4485d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala return mLegacyDevice.cancelRequest(requestId); 449feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 450feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 451feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 4525d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public void beginConfigure() { 453feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 454feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "beginConfigure called."); 455feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 456e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 4575d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot begin configure, device has been closed."; 4585d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4595d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 460e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 461e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 462feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 463feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 4645d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot begin configure, configuration change already in progress."; 4655d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4665d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 467feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 468feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = true; 469feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 470feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 471feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 472feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 4735d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public void endConfigure(boolean isConstrainedHighSpeed) { 474feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 475feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "endConfigure called."); 476feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 477e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 4785d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot end configure, device has been closed."; 4795d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4805d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 481e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 482e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 483feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk ArrayList<Surface> surfaces = null; 484feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 485feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 4865d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot end configure, no configuration change in progress."; 4875d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 4885d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 489feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 490feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int numSurfaces = mSurfaces.size(); 491feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (numSurfaces > 0) { 4925776aafc7e70c0b79c4bee2bc50f44121b37c962Ruben Brunk surfaces = new ArrayList<>(); 493feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk for (int i = 0; i < numSurfaces; ++i) { 494feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk surfaces.add(mSurfaces.valueAt(i)); 495feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 496feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 497feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mConfiguring = false; 498feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 4995d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala mLegacyDevice.configureOutputs(surfaces); 500feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 501feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 502feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 5035d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public void deleteStream(int streamId) { 504feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 505feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "deleteStream called."); 506feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 507e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 5085d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot delete stream, device has been closed."; 5095d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5105d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 511e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 512e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 513feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 514feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 5155d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot delete stream, no configuration change in progress."; 5165d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5175d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 518feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 519feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int index = mSurfaces.indexOfKey(streamId); 520feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (index < 0) { 5215d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot delete stream, stream id " + streamId + " doesn't exist."; 5225d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5235d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err); 524feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 525feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mSurfaces.removeAt(index); 526feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 527feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 528feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 529feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 530bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh public int createStream(OutputConfiguration outputConfiguration) { 531feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 532feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "createStream called."); 533feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 534e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 5355d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot create stream, device has been closed."; 5365d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5375d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 538e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 539e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 540feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 541feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (!mConfiguring) { 5425d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot create stream, beginConfigure hasn't been called yet."; 5435d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5445d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 545feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 546bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh if (outputConfiguration.getRotation() != OutputConfiguration.ROTATION_0) { 5475d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot create stream, stream rotation is not supported."; 5485d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5495d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err); 550bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh } 551feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk int id = ++mSurfaceIdCounter; 552bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh mSurfaces.put(id, outputConfiguration.getSurface()); 553feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return id; 554feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 555feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 556feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 557feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 5585398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen public int createInputStream(int width, int height, int format) { 5595d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Creating input stream is not supported on legacy devices"; 5605d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5615d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 5625398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen } 5635398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen 5645398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen @Override 5655d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public Surface getInputSurface() { 5665d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Getting input surface is not supported on legacy devices"; 5675d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5685d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 5695398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen } 5705398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen 5715398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen @Override 5725d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public CameraMetadataNative createDefaultRequest(int templateId) { 573feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 574feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "createDefaultRequest called."); 575feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 576e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 5775d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot create default request, device has been closed."; 5785d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5795d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 580e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 581a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 582a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin CameraMetadataNative template; 583a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin try { 584a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin template = 585a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin LegacyMetadataMapper.createRequestTemplate(mCameraCharacteristics, templateId); 586a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } catch (IllegalArgumentException e) { 5875d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "createDefaultRequest - invalid templateId specified"; 5885d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 5895d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err); 590a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin } 591a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin 5925d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala return template; 593feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 594feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 595feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 5965d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public CameraMetadataNative getCameraInfo() { 597feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 598feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "getCameraInfo called."); 599feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 600feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // TODO: implement getCameraInfo. 601feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.e(TAG, "getCameraInfo unimplemented."); 6025d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala return null; 603feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 604feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 605feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 6065d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public void waitUntilIdle() throws RemoteException { 607feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 608feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "waitUntilIdle called."); 609feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 610e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 6115d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot wait until idle, device has been closed."; 6125d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 6135d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 614e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 615e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 616feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 617feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 6185d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot wait until idle, configuration change in progress."; 6195d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 6205d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 621feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 622feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 623feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk mLegacyDevice.waitUntilIdle(); 624feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 625feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 626feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 6275d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public long flush() { 628feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (DEBUG) { 629feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk Log.d(TAG, "flush called."); 630feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 631e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk if (mLegacyDevice.isClosed()) { 6325d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot flush, device has been closed."; 6335d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 6345d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 635e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk } 636e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk 637feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk synchronized(mConfigureLock) { 638feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk if (mConfiguring) { 6395d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot flush, configuration change in progress."; 6405d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 6415d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); 642feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 643feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 6445d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala return mLegacyDevice.flush(); 645feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 646feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk 6475d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public void prepare(int streamId) { 648ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala if (DEBUG) { 649ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala Log.d(TAG, "prepare called."); 650ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala } 651ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala if (mLegacyDevice.isClosed()) { 6525d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot prepare stream, device has been closed."; 6535d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 6545d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 655ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala } 656ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala 657be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala // LEGACY doesn't support actual prepare, just signal success right away 658be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala mCameraCallbacks.onPrepared(streamId); 659ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala } 660ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala 6615d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public void prepare2(int maxCount, int streamId) { 6627ed1aaa369b6a459c776a9a6e96c33014b30f278Ruben Brunk // We don't support this in LEGACY mode. 6635d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala prepare(streamId); 6647ed1aaa369b6a459c776a9a6e96c33014b30f278Ruben Brunk } 6657ed1aaa369b6a459c776a9a6e96c33014b30f278Ruben Brunk 6665d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala public void tearDown(int streamId) { 66714c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala if (DEBUG) { 66814c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala Log.d(TAG, "tearDown called."); 66914c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala } 67014c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala if (mLegacyDevice.isClosed()) { 6715d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala String err = "Cannot tear down stream, device has been closed."; 6725d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala Log.e(TAG, err); 6735d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); 67414c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala } 67514c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala 67614c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala // LEGACY doesn't support actual teardown, so just a no-op 67714c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala } 67814c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala 679feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk @Override 680feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk public IBinder asBinder() { 681feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk // This is solely intended to be used for in-process binding. 682feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk return null; 683feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk } 684feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} 685