CameraDeviceUserShim.java revision a1d662716b3da384dfe3a758f079e0cbd089784a
1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/*
2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project
3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License.
6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at
7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software
11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and
14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License.
15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */
16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpackage android.hardware.camera2.legacy;
18feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.Camera;
20feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.CameraAccessException;
21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.CaptureRequest;
22feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.ICameraDeviceCallbacks;
23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.ICameraDeviceUser;
24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.LongParcelable;
25feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.impl.CameraMetadataNative;
26feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.CameraBinderDecorator;
27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.hardware.camera2.utils.CameraRuntimeException;
28feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.IBinder;
29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.os.RemoteException;
30feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.Log;
31feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.util.SparseArray;
32feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport android.view.Surface;
33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
34feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.ArrayList;
35feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.List;
36feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkimport java.util.concurrent.atomic.AtomicInteger;
37feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
38feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/**
39feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Compatibility implementation of the Camera2 API binder interface.
40feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p>
42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * This is intended to be called from the same process as client
43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.hardware.camera2.CameraDevice}, and wraps a
44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * {@link android.hardware.camera2.legacy.LegacyCameraDevice} that emulates Camera2 service using
45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * the Camera1 API.
46feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p>
47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * <p>
49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Keep up to date with ICameraDeviceUser.aidl.
50feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * </p>
51feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */
52feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkpublic class CameraDeviceUserShim implements ICameraDeviceUser {
53feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    private static final String TAG = "CameraDeviceUserShim";
54feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
55feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    private static final boolean DEBUG = Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.DEBUG);
56feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
57feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    private final LegacyCameraDevice mLegacyDevice;
58feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
59feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    private final Object mConfigureLock = new Object();
60feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    private int mSurfaceIdCounter;
61feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    private boolean mConfiguring;
62feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    private final SparseArray<Surface> mSurfaces;
63feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
64feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    protected CameraDeviceUserShim(int cameraId, LegacyCameraDevice legacyCamera) {
65feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        mLegacyDevice = legacyCamera;
66feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        mConfiguring = false;
67feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        mSurfaces = new SparseArray<Surface>();
68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
69feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        mSurfaceIdCounter = 0;
70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
71feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
72feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public static CameraDeviceUserShim connectBinderShim(ICameraDeviceCallbacks callbacks,
73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                                                         int cameraId) {
74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
75feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "Opening shim Camera device");
76feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
77feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // TODO: Move open/init into LegacyCameraDevice thread when API is switched to async.
78feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        Camera legacyCamera = Camera.openUninitialized();
79a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin        int initErrors = legacyCamera.cameraInitUnspecified(cameraId);
80a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin
81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // Check errors old HAL initialization
82a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin        CameraBinderDecorator.throwOnError(initErrors);
83a1d662716b3da384dfe3a758f079e0cbd089784aIgor Murashkin
84feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        LegacyCameraDevice device = new LegacyCameraDevice(cameraId, legacyCamera, callbacks);
85feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return new CameraDeviceUserShim(cameraId, device);
86feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
87feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
88feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
89feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public void disconnect() {
90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "disconnect called.");
92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        mLegacyDevice.close();
94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
95feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
96feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
97feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int submitRequest(CaptureRequest request, boolean streaming,
98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                             /*out*/LongParcelable lastFrameNumber) {
99feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
100feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "submitRequest called.");
101feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
102feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot submit request, configuration change in progress.");
105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
106feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
107feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return mLegacyDevice.submitRequest(request, streaming, lastFrameNumber);
109feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
110feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
111feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
112feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int submitRequestList(List<CaptureRequest> request, boolean streaming,
113feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                                 /*out*/LongParcelable lastFrameNumber) {
114feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
115feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "submitRequestList called.");
116feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
117feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
118feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot submit request, configuration change in progress.");
120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
123feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return mLegacyDevice.submitRequestList(request, streaming, lastFrameNumber);
124feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
125feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
126feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
127feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int cancelRequest(int requestId, /*out*/LongParcelable lastFrameNumber) {
128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "cancelRequest called.");
130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
132feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
133feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot cancel request, configuration change in progress.");
134feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
137feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        long lastFrame = mLegacyDevice.cancelRequest(requestId);
138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        lastFrameNumber.setNumber(lastFrame);
139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return CameraBinderDecorator.NO_ERROR;
140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
141feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
142feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
143feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int beginConfigure() {
144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "beginConfigure called.");
146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
147feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot begin configure, configuration change already in progress.");
150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            mConfiguring = true;
153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return CameraBinderDecorator.NO_ERROR;
155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
158feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int endConfigure() {
159feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
160feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "endConfigure called.");
161feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
162feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ArrayList<Surface> surfaces = null;
163feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
164feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (!mConfiguring) {
165feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot end configure, no configuration change in progress.");
166feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
167feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
168feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            int numSurfaces = mSurfaces.size();
169feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (numSurfaces > 0) {
170feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                for (int i = 0; i < numSurfaces; ++i) {
171feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                    surfaces.add(mSurfaces.valueAt(i));
172feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                }
173feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
174feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            mConfiguring = false;
175feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
176feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return mLegacyDevice.configureOutputs(surfaces);
177feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
178feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
179feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
180feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int deleteStream(int streamId) {
181feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
182feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "deleteStream called.");
183feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
184feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
185feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (!mConfiguring) {
186feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot delete stream, beginConfigure hasn't been called yet.");
187feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
188feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
189feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            int index = mSurfaces.indexOfKey(streamId);
190feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (index < 0) {
191feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot delete stream, stream id " + streamId + " doesn't exist.");
192feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.BAD_VALUE;
193feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
194feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            mSurfaces.removeAt(index);
195feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
196feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return CameraBinderDecorator.NO_ERROR;
197feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
198feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
199feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
200feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int createStream(int width, int height, int format, Surface surface) {
201feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
202feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "createStream called.");
203feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
204feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
205feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (!mConfiguring) {
206feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot create stream, beginConfigure hasn't been called yet.");
207feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
208feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
209feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            int id = ++mSurfaceIdCounter;
210feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            mSurfaces.put(id, surface);
211feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            return id;
212feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
213feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
214feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
215feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
216feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int createDefaultRequest(int templateId, /*out*/CameraMetadataNative request) {
217feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
218feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "createDefaultRequest called.");
219feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
220feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // TODO: implement createDefaultRequest.
221feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        Log.e(TAG, "createDefaultRequest unimplemented.");
222feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return CameraBinderDecorator.NO_ERROR;
223feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
224feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
225feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
226feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int getCameraInfo(/*out*/CameraMetadataNative info) {
227feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
228feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "getCameraInfo called.");
229feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
230feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // TODO: implement getCameraInfo.
231feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        Log.e(TAG, "getCameraInfo unimplemented.");
232feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return CameraBinderDecorator.NO_ERROR;
233feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
234feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
235feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
236feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int waitUntilIdle() throws RemoteException {
237feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
238feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "waitUntilIdle called.");
239feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
240feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
241feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
242feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot wait until idle, configuration change in progress.");
243feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
244feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
245feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
246feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        mLegacyDevice.waitUntilIdle();
247feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return CameraBinderDecorator.NO_ERROR;
248feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
249feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
250feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
251feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public int flush(/*out*/LongParcelable lastFrameNumber) {
252feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (DEBUG) {
253feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            Log.d(TAG, "flush called.");
254feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
255feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        synchronized(mConfigureLock) {
256feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (mConfiguring) {
257feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                Log.e(TAG, "Cannot flush, configuration change in progress.");
258feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return CameraBinderDecorator.INVALID_OPERATION;
259feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
260feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
261feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // TODO: implement flush.
262feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return CameraBinderDecorator.NO_ERROR;
263feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
264feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
265feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    @Override
266feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    public IBinder asBinder() {
267feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        // This is solely intended to be used for in-process binding.
268feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return null;
269feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
270feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
271