CameraDeviceUserShim.java revision 032331578c78886d2b0a6012dc2a083837c5e79f
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;
2082da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen        private static final int REPEATING_REQUEST_ERROR = 5;
20988f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang        private static final int REQUEST_QUEUE_EMPTY = 6;
2102f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2112f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        private final HandlerThread mHandlerThread;
2122f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        private Handler mHandler;
2132f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2142f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        private final ICameraDeviceCallbacks mCallbacks;
2152f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2162f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        public CameraCallbackThread(ICameraDeviceCallbacks callbacks) {
2172f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            mCallbacks = callbacks;
2182f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2192f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            mHandlerThread = new HandlerThread("LegacyCameraCallback");
2202f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            mHandlerThread.start();
2212f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
2222f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2232f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        public void close() {
2242f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            mHandlerThread.quitSafely();
2252f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
2262f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2272f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        @Override
228acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala        public void onDeviceError(final int errorCode, final CaptureResultExtras resultExtras) {
2292f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            Message msg = getHandler().obtainMessage(CAMERA_ERROR,
2302f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                /*arg1*/ errorCode, /*arg2*/ 0,
2312f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                /*obj*/ resultExtras);
2322f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            getHandler().sendMessage(msg);
2332f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
2342f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2352f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        @Override
236acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala        public void onDeviceIdle() {
2372f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            Message msg = getHandler().obtainMessage(CAMERA_IDLE);
2382f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            getHandler().sendMessage(msg);
2392f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
2402f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2412f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        @Override
2422f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
2432f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            Message msg = getHandler().obtainMessage(CAPTURE_STARTED,
2442f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                    /*arg1*/ (int) (timestamp & 0xFFFFFFFFL),
2452f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                    /*arg2*/ (int) ( (timestamp >> 32) & 0xFFFFFFFFL),
2462f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                    /*obj*/ resultExtras);
2472f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            getHandler().sendMessage(msg);
2482f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
2492f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2502f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        @Override
2512f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        public void onResultReceived(final CameraMetadataNative result,
2522f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                final CaptureResultExtras resultExtras) {
2532f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            Object[] resultArray = new Object[] { result, resultExtras };
2542f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            Message msg = getHandler().obtainMessage(RESULT_RECEIVED,
2552f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                    /*obj*/ resultArray);
2562f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            getHandler().sendMessage(msg);
2572f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
2582f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2592f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        @Override
260ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala        public void onPrepared(int streamId) {
261be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala            Message msg = getHandler().obtainMessage(PREPARED,
262be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala                    /*arg1*/ streamId, /*arg2*/ 0);
263be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala            getHandler().sendMessage(msg);
264ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala        }
265ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala
2662da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen        @Override
2678cd12e9b7cc73b1bbe5e478acdf463c5381f33efYin-Chia Yeh        public void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId) {
2688cd12e9b7cc73b1bbe5e478acdf463c5381f33efYin-Chia Yeh            Object[] objArray = new Object[] { lastFrameNumber, repeatingRequestId };
2692da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen            Message msg = getHandler().obtainMessage(REPEATING_REQUEST_ERROR,
2708cd12e9b7cc73b1bbe5e478acdf463c5381f33efYin-Chia Yeh                    /*obj*/ objArray);
2712da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen            getHandler().sendMessage(msg);
2722da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen        }
2732da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen
274ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala        @Override
27588f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang        public void onRequestQueueEmpty() {
27688f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang            Message msg = getHandler().obtainMessage(REQUEST_QUEUE_EMPTY,
27788f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang                    /* arg1 */ 0, /* arg2 */ 0);
27888f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang            getHandler().sendMessage(msg);
27988f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang        }
28088f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang
28188f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang        @Override
2822f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        public IBinder asBinder() {
2832f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            // This is solely intended to be used for in-process binding.
2842f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            return null;
2852f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
2862f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2872f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        private Handler getHandler() {
2882f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            if (mHandler == null) {
2892f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                mHandler = new CallbackHandler(mHandlerThread.getLooper());
2902f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            }
2912f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            return mHandler;
2922f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
2932f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2942f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        private class CallbackHandler extends Handler {
2952f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            public CallbackHandler(Looper l) {
2962f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                super(l);
2972f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            }
2982f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
2996653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin            @Override
3002f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            public void handleMessage(Message msg) {
3012f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                try {
3022f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                    switch (msg.what) {
3032f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        case CAMERA_ERROR: {
3042f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            int errorCode = msg.arg1;
3052f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj;
306acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala                            mCallbacks.onDeviceError(errorCode, resultExtras);
3072f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            break;
3082f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        }
3092f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        case CAMERA_IDLE:
310acc0095bc84914d3ce41ad8298f698c37935b8a8Eino-Ville Talvala                            mCallbacks.onDeviceIdle();
3112f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            break;
3122f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        case CAPTURE_STARTED: {
3132f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            long timestamp = msg.arg2 & 0xFFFFFFFFL;
3142f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            timestamp = (timestamp << 32) | (msg.arg1 & 0xFFFFFFFFL);
3152f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj;
3162f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            mCallbacks.onCaptureStarted(resultExtras, timestamp);
3172f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            break;
3182f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        }
3192f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        case RESULT_RECEIVED: {
3202f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            Object[] resultArray = (Object[]) msg.obj;
3212f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            CameraMetadataNative result = (CameraMetadataNative) resultArray[0];
3222f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            CaptureResultExtras resultExtras = (CaptureResultExtras) resultArray[1];
3232f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            mCallbacks.onResultReceived(result, resultExtras);
3242f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            break;
3252f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        }
326be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala                        case PREPARED: {
327be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala                            int streamId = msg.arg1;
328be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala                            mCallbacks.onPrepared(streamId);
329be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala                            break;
330be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala                        }
3312da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen                        case REPEATING_REQUEST_ERROR: {
3328cd12e9b7cc73b1bbe5e478acdf463c5381f33efYin-Chia Yeh                            Object[] objArray = (Object[]) msg.obj;
3338cd12e9b7cc73b1bbe5e478acdf463c5381f33efYin-Chia Yeh                            long lastFrameNumber = (Long) objArray[0];
3348cd12e9b7cc73b1bbe5e478acdf463c5381f33efYin-Chia Yeh                            int repeatingRequestId = (Integer) objArray[1];
3358cd12e9b7cc73b1bbe5e478acdf463c5381f33efYin-Chia Yeh                            mCallbacks.onRepeatingRequestError(lastFrameNumber, repeatingRequestId);
3362da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen                            break;
3372da496f1ce63548486fe28e074f6af90c970db8cChien-Yu Chen                        }
33888f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang                        case REQUEST_QUEUE_EMPTY: {
33988f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang                            mCallbacks.onRequestQueueEmpty();
34088f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang                            break;
34188f1af241045d446358c692e183e5ecb152bad91Shuzhen Wang                        }
3422f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        default:
3432f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                            throw new IllegalArgumentException(
3442f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                                "Unknown callback message " + msg.what);
3452f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                    }
3462f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                } catch (RemoteException e) {
3472f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                    throw new IllegalStateException(
3482f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                        "Received remote exception during camera callback " + msg.what, e);
3492f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                }
3502f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            }
3512f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        }
3522f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala    }
3532f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
354feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public static CameraDeviceUserShim connectBinderShim(ICameraDeviceCallbacks callbacks,
355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                                                         int cameraId) {
356feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
357feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "Opening shim Camera device");
358feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
359a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
360a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        /*
361a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * Put the camera open on a separate thread with its own looper; otherwise
362a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * if the main thread is used then the callbacks might never get delivered
363a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         * (e.g. in CTS which run its own default looper only after tests)
364a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin         */
365a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
366a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        CameraLooper init = new CameraLooper(cameraId);
367a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
3682f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        CameraCallbackThread threadCallbacks = new CameraCallbackThread(callbacks);
3692f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala
370a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        // TODO: Make this async instead of blocking
371a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        int initErrors = init.waitForOpen(OPEN_CAMERA_TIMEOUT_MS);
372a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        Camera legacyCamera = init.getCamera();
373a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin
374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // Check errors old HAL initialization
3755d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        LegacyExceptionUtils.throwOnServiceError(initErrors);
376a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin
3776653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin        // Disable shutter sounds (this will work unconditionally) for api2 clients
3786653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin        legacyCamera.disableShutterSound();
3796653362f6b5c5854bd88244bcecad72d11bf9404Igor Murashkin
380a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        CameraInfo info = new CameraInfo();
381a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        Camera.getCameraInfo(cameraId, info);
382a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
383eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala        Camera.Parameters legacyParameters = null;
384eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala        try {
385eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala            legacyParameters = legacyCamera.getParameters();
386eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala        } catch (RuntimeException e) {
3875d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION,
3885d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                    "Unable to get initial parameters: " + e.getMessage());
389eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala        }
390eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala
391a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        CameraCharacteristics characteristics =
392eecc904f13e7a105f5548c953e4caa306fe06f0dEino-Ville Talvala                LegacyMetadataMapper.createCharacteristics(legacyParameters, info);
393df6242e374b81e802a38cb891477f05d3e4b3cbcIgor Murashkin        LegacyCameraDevice device = new LegacyCameraDevice(
3942f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala                cameraId, legacyCamera, characteristics, threadCallbacks);
3952f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala        return new CameraDeviceUserShim(cameraId, device, characteristics, init, threadCallbacks);
396feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
397feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
398feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
399feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public void disconnect() {
400feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
401feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "disconnect called.");
402feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
403a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
404e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
405e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk            Log.w(TAG, "Cannot disconnect, device has already been closed.");
406e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
407e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
408a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        try {
409a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            mLegacyDevice.close();
410a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        } finally {
411a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            mCameraInit.close();
4122f75e7d7ef2ef29ac4b1287dc44cf62cfbaf50b3Eino-Ville Talvala            mCameraCallbacks.close();
413a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
414feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
415feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
416feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
4175d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public SubmitInfo submitRequest(CaptureRequest request, boolean streaming) {
418feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
419feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "submitRequest called.");
420feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
421e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
4225d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot submit request, device has been closed.";
4235d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
4245d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
425e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
426e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
427feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
428feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
4295d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot submit request, configuration change in progress.";
4305d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
4315d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
432feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
433feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
4345d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        return mLegacyDevice.submitRequest(request, streaming);
435feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
436feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
437feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
4385d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public SubmitInfo submitRequestList(CaptureRequest[] request, boolean streaming) {
439feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
440feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "submitRequestList called.");
441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
442e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
4435d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot submit request list, device has been closed.";
4445d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
4455d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
446e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
447e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
448feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
449feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
4505d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot submit request, configuration change in progress.";
4515d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
4525d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
453feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
454feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
4555d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        return mLegacyDevice.submitRequestList(request, streaming);
456feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
457feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
458feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
4595d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public long cancelRequest(int requestId) {
460feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
461feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "cancelRequest called.");
462feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
463e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
4645d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot cancel request, device has been closed.";
4655d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
4665d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
467e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
468e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
469feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
470feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
4715d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot cancel request, configuration change in progress.";
4725d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
4735d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
474feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
475feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
4765d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        return mLegacyDevice.cancelRequest(requestId);
477feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
478feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
479feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
4805d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public void beginConfigure() {
481feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
482feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "beginConfigure called.");
483feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
484e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
4855d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot begin configure, device has been closed.";
4865d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
4875d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
488e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
489e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
490feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
491feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
4925d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot begin configure, configuration change already in progress.";
4935d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
4945d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
495feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
496feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            mConfiguring = true;
497feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
498feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
499feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
500feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
5010e04e910a6b0d8a7464df9721535dfba21527c37Eino-Ville Talvala    public void endConfigure(int operatingMode) {
502feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
503feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "endConfigure called.");
504feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
505e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
5065d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot end configure, device has been closed.";
5075d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
508daf20731ca75b829302ad3dc81fc6df431959475Yin-Chia Yeh            synchronized(mConfigureLock) {
509daf20731ca75b829302ad3dc81fc6df431959475Yin-Chia Yeh                mConfiguring = false;
510daf20731ca75b829302ad3dc81fc6df431959475Yin-Chia Yeh            }
5115d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
512e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
513e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
5140e04e910a6b0d8a7464df9721535dfba21527c37Eino-Ville Talvala        if (operatingMode != ICameraDeviceUser.NORMAL_MODE) {
5150e04e910a6b0d8a7464df9721535dfba21527c37Eino-Ville Talvala            String err = "LEGACY devices do not support this operating mode";
5160e04e910a6b0d8a7464df9721535dfba21527c37Eino-Ville Talvala            Log.e(TAG, err);
517daf20731ca75b829302ad3dc81fc6df431959475Yin-Chia Yeh            synchronized(mConfigureLock) {
518daf20731ca75b829302ad3dc81fc6df431959475Yin-Chia Yeh                mConfiguring = false;
519daf20731ca75b829302ad3dc81fc6df431959475Yin-Chia Yeh            }
5200e04e910a6b0d8a7464df9721535dfba21527c37Eino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
5210e04e910a6b0d8a7464df9721535dfba21527c37Eino-Ville Talvala        }
5220e04e910a6b0d8a7464df9721535dfba21527c37Eino-Ville Talvala
523385f9e2146d2600ae9fd20053aab8ee5abcac9a6Eino-Ville Talvala        SparseArray<Surface> surfaces = null;
524feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
525feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (!mConfiguring) {
5265d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot end configure, no configuration change in progress.";
5275d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
5285d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
529feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
530385f9e2146d2600ae9fd20053aab8ee5abcac9a6Eino-Ville Talvala            if (mSurfaces != null) {
531385f9e2146d2600ae9fd20053aab8ee5abcac9a6Eino-Ville Talvala                surfaces = mSurfaces.clone();
532feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
533feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            mConfiguring = false;
534feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
5355d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        mLegacyDevice.configureOutputs(surfaces);
536feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
537feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
538feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
5395d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public void deleteStream(int streamId) {
540feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
541feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "deleteStream called.");
542feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
543e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
5445d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot delete stream, device has been closed.";
5455d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
5465d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
547e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
548e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
549feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
550feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (!mConfiguring) {
5515d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot delete stream, no configuration change in progress.";
5525d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
5535d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
554feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
555feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            int index = mSurfaces.indexOfKey(streamId);
556feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (index < 0) {
5575d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot delete stream, stream id " + streamId + " doesn't exist.";
5585d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
5595d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
560feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
561feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            mSurfaces.removeAt(index);
562feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
563feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
564feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
565feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
566bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh    public int createStream(OutputConfiguration outputConfiguration) {
567feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
568feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "createStream called.");
569feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
570e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
5715d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot create stream, device has been closed.";
5725d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
5735d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
574e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
575e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
576feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
577feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (!mConfiguring) {
5785d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot create stream, beginConfigure hasn't been called yet.";
5795d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
5805d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
581feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
582bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh            if (outputConfiguration.getRotation() != OutputConfiguration.ROTATION_0) {
5835d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot create stream, stream rotation is not supported.";
5845d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
5855d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
586bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh            }
587feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            int id = ++mSurfaceIdCounter;
588bfbbee756663aeeb38706bb1bd4841dcd050f91bYin-Chia Yeh            mSurfaces.put(id, outputConfiguration.getSurface());
589feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            return id;
590feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
591feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
592feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
593feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
5944bd7abe72a647ceb2175a4fe66aa640815c116f8Shuzhen Wang    public void finalizeOutputConfigurations(int steamId, OutputConfiguration config) {
5954bd7abe72a647ceb2175a4fe66aa640815c116f8Shuzhen Wang        String err = "Finalizing output configuration is not supported on legacy devices";
596c8b181e95d17c00f9fe4a8338c4cdd0eeac3a0dcZhijun He        Log.e(TAG, err);
597c8b181e95d17c00f9fe4a8338c4cdd0eeac3a0dcZhijun He        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
598c8b181e95d17c00f9fe4a8338c4cdd0eeac3a0dcZhijun He    }
599c8b181e95d17c00f9fe4a8338c4cdd0eeac3a0dcZhijun He
600c8b181e95d17c00f9fe4a8338c4cdd0eeac3a0dcZhijun He    @Override
6015398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen    public int createInputStream(int width, int height, int format) {
6025d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        String err = "Creating input stream is not supported on legacy devices";
6035d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        Log.e(TAG, err);
6045d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
6055398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen    }
6065398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen
6075398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen    @Override
6085d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public Surface getInputSurface() {
6095d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        String err = "Getting input surface is not supported on legacy devices";
6105d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        Log.e(TAG, err);
6115d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
6125398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen    }
6135398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen
6145398a676809faaf3c6c2875edc1907ad6b8e1c89Chien-Yu Chen    @Override
6155d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public CameraMetadataNative createDefaultRequest(int templateId) {
616feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
617feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "createDefaultRequest called.");
618feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
619e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
6205d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot create default request, device has been closed.";
6215d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
6225d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
623e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
624a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
625a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        CameraMetadataNative template;
626a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        try {
627a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin            template =
628a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin                    LegacyMetadataMapper.createRequestTemplate(mCameraCharacteristics, templateId);
629a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        } catch (IllegalArgumentException e) {
6305d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "createDefaultRequest - invalid templateId specified";
6315d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
6325d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
633a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin        }
634a296fece2b974a11bc624fd67b275863f17df867Igor Murashkin
6355d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        return template;
636feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
637feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
638feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
6395d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public CameraMetadataNative getCameraInfo() {
640feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
641feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "getCameraInfo called.");
642feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
643feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // TODO: implement getCameraInfo.
644feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        Log.e(TAG, "getCameraInfo unimplemented.");
6455d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        return null;
646feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
647feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
648feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
649032331578c78886d2b0a6012dc2a083837c5e79fEmilian Peev    public void updateOutputConfiguration(int streamId, OutputConfiguration config) {
650032331578c78886d2b0a6012dc2a083837c5e79fEmilian Peev        // TODO: b/63912484 implement updateOutputConfiguration.
651032331578c78886d2b0a6012dc2a083837c5e79fEmilian Peev    }
652032331578c78886d2b0a6012dc2a083837c5e79fEmilian Peev
653032331578c78886d2b0a6012dc2a083837c5e79fEmilian Peev    @Override
6545d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public void waitUntilIdle() throws RemoteException {
655feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
656feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "waitUntilIdle called.");
657feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
658e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
6595d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot wait until idle, device has been closed.";
6605d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
6615d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
662e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
663e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
664feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
665feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
6665d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot wait until idle, configuration change in progress.";
6675d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
6685d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
669feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
670feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
671feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        mLegacyDevice.waitUntilIdle();
672feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
673feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
674feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
6755d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public long flush() {
676feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
677feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "flush called.");
678feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
679e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        if (mLegacyDevice.isClosed()) {
6805d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot flush, device has been closed.";
6815d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
6825d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
683e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk        }
684e663cb77281c4c76241b820f6126543f1c2d859fRuben Brunk
685feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
686feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
6875d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                String err = "Cannot flush, configuration change in progress.";
6885d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                Log.e(TAG, err);
6895d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
690feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
691feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
6925d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        return mLegacyDevice.flush();
693feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
694feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
6955d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public void prepare(int streamId) {
696ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala        if (DEBUG) {
697ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala            Log.d(TAG, "prepare called.");
698ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala        }
699ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala        if (mLegacyDevice.isClosed()) {
7005d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot prepare stream, device has been closed.";
7015d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
7025d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
703ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala        }
704ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala
705be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala        // LEGACY doesn't support actual prepare, just signal success right away
706be6d98526988f914365a2999b8d3ca11e24e5aebEino-Ville Talvala        mCameraCallbacks.onPrepared(streamId);
707ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala    }
708ad916f7fd3fbb202f2993fea04b0bdad3dcd6de6Eino-Ville Talvala
7095d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public void prepare2(int maxCount, int streamId) {
7107ed1aaa369b6a459c776a9a6e96c33014b30f278Ruben Brunk        // We don't support this in LEGACY mode.
7115d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        prepare(streamId);
7127ed1aaa369b6a459c776a9a6e96c33014b30f278Ruben Brunk    }
7137ed1aaa369b6a459c776a9a6e96c33014b30f278Ruben Brunk
7145d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public void tearDown(int streamId) {
71514c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala        if (DEBUG) {
71614c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala            Log.d(TAG, "tearDown called.");
71714c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala        }
71814c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala        if (mLegacyDevice.isClosed()) {
7195d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            String err = "Cannot tear down stream, device has been closed.";
7205d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            Log.e(TAG, err);
7215d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
72214c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala        }
72314c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala
72414c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala        // LEGACY doesn't support actual teardown, so just a no-op
72514c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala    }
72614c09fa3c5371b977c77e5813eabb81941040627Eino-Ville Talvala
727feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
728feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public IBinder asBinder() {
729feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // This is solely intended to be used for in-process binding.
730feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return null;
731feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
732feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
733