170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin/* 270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * Copyright (C) 2013 The Android Open Source Project 370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * 470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License"); 570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * you may not use this file except in compliance with the License. 670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * You may obtain a copy of the License at 770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * 870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * http://www.apache.org/licenses/LICENSE-2.0 970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * 1070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * Unless required by applicable law or agreed to in writing, software 1170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS, 1270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * See the License for the specific language governing permissions and 1470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin * limitations under the License. 1570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin */ 1670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 172f1a2e423e0fbb64467d6fcfa4e82c6384f31210Eino-Ville Talvalapackage android.hardware.camera2.impl; 1870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 1957ea59b376c6b72206b5b339733ee5874b181762Igor Murashkinimport static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE; 2057ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin 212f1a2e423e0fbb64467d6fcfa4e82c6384f31210Eino-Ville Talvalaimport android.hardware.camera2.CameraAccessException; 222f1a2e423e0fbb64467d6fcfa4e82c6384f31210Eino-Ville Talvalaimport android.hardware.camera2.CaptureRequest; 2357ea59b376c6b72206b5b339733ee5874b181762Igor Murashkinimport android.hardware.camera2.CaptureResult; 2457ea59b376c6b72206b5b339733ee5874b181762Igor Murashkinimport android.hardware.camera2.ICameraDeviceCallbacks; 2557ea59b376c6b72206b5b339733ee5874b181762Igor Murashkinimport android.hardware.camera2.ICameraDeviceUser; 265afd3e91b8e785b1b3a42e40b0a3ca11eba2d7ccEino-Ville Talvalaimport android.hardware.camera2.utils.CameraBinderDecorator; 2757ea59b376c6b72206b5b339733ee5874b181762Igor Murashkinimport android.hardware.camera2.utils.CameraRuntimeException; 284af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvalaimport android.os.Handler; 29decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunkimport android.os.IBinder; 304af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvalaimport android.os.Looper; 31decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunkimport android.os.RemoteException; 3270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinimport android.util.Log; 3357ea59b376c6b72206b5b339733ee5874b181762Igor Murashkinimport android.util.SparseArray; 3470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinimport android.view.Surface; 3570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 3657ea59b376c6b72206b5b339733ee5874b181762Igor Murashkinimport java.util.ArrayList; 3757ea59b376c6b72206b5b339733ee5874b181762Igor Murashkinimport java.util.HashSet; 38decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunkimport java.util.Iterator; 3970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkinimport java.util.List; 4070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin/** 4270c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate 4370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin */ 442f1a2e423e0fbb64467d6fcfa4e82c6384f31210Eino-Ville Talvalapublic class CameraDevice implements android.hardware.camera2.CameraDevice { 4570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin private final String TAG; 47ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He private final boolean DEBUG; 4870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 49decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk private static final int REQUEST_ID_NONE = -1; 50decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk 5170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // TODO: guard every function with if (!mRemoteDevice) check (if it was closed) 5270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin private ICameraDeviceUser mRemoteDevice; 5370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 5470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin private final Object mLock = new Object(); 5570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks(); 5670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 57868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final StateListener mDeviceListener; 58868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final Handler mDeviceHandler; 59868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 60868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private boolean mIdle = true; 614af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala 624af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala private final SparseArray<CaptureListenerHolder> mCaptureListenerMap = 634af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala new SparseArray<CaptureListenerHolder>(); 6470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 65decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk private int mRepeatingRequestId = REQUEST_ID_NONE; 66decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk private final ArrayList<Integer> mRepeatingRequestIdDeletedList = new ArrayList<Integer>(); 6757ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin // Map stream IDs to Surfaces 6857ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin private final SparseArray<Surface> mConfiguredOutputs = new SparseArray<Surface>(); 6970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 7070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin private final String mCameraId; 7170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 72868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala // Runnables for all state transitions, except error, which needs the 73868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala // error code argument 74868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 75868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final Runnable mCallOnOpened = new Runnable() { 76868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala public void run() { 77868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 78868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener.onOpened(CameraDevice.this); 79868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 80868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 81868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala }; 82868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 83868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final Runnable mCallOnUnconfigured = new Runnable() { 84868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala public void run() { 85868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 86868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener.onUnconfigured(CameraDevice.this); 87868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 88868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 89868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala }; 90868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 91868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final Runnable mCallOnActive = new Runnable() { 92868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala public void run() { 93868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 94868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener.onActive(CameraDevice.this); 95868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 96868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 97868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala }; 98868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 99868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final Runnable mCallOnBusy = new Runnable() { 100868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala public void run() { 101868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 102868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener.onBusy(CameraDevice.this); 103868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 104868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 105868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala }; 106868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 107868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final Runnable mCallOnClosed = new Runnable() { 108868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala public void run() { 109868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 110868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener.onClosed(CameraDevice.this); 111868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 112868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 113868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala }; 114868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 115868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final Runnable mCallOnIdle = new Runnable() { 116868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala public void run() { 117868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 118868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener.onIdle(CameraDevice.this); 119868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 120868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 121868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala }; 122868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 123868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private final Runnable mCallOnDisconnected = new Runnable() { 124868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala public void run() { 125868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 126868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener.onDisconnected(CameraDevice.this); 127868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 128868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 129868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala }; 130868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 131868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala public CameraDevice(String cameraId, StateListener listener, Handler handler) { 132868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (cameraId == null || listener == null || handler == null) { 133868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala throw new IllegalArgumentException("Null argument given"); 134868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 13570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin mCameraId = cameraId; 136868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener = listener; 137868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler = handler; 13870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin TAG = String.format("CameraDevice-%s-JV", mCameraId); 139ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He DEBUG = Log.isLoggable(TAG, Log.DEBUG); 14070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 14170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 14270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public CameraDeviceCallbacks getCallbacks() { 14370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return mCallbacks; 14470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 14570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 14670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public void setRemoteDevice(ICameraDeviceUser remoteDevice) { 1475afd3e91b8e785b1b3a42e40b0a3ca11eba2d7ccEino-Ville Talvala // TODO: Move from decorator to direct binder-mediated exceptions 148868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala synchronized(mLock) { 149868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mRemoteDevice = CameraBinderDecorator.newInstance(remoteDevice); 150868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 151868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler.post(mCallOnOpened); 152868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler.post(mCallOnUnconfigured); 153868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 15470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 15570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 15670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 1574af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala public String getId() { 1584af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala return mCameraId; 1594af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala } 1604af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala 1614af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala @Override 16270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public void configureOutputs(List<Surface> outputs) throws CameraAccessException { 163868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala // Treat a null input the same an empty list 164868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (outputs == null) { 165868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala outputs = new ArrayList<Surface>(); 166868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 16770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin synchronized (mLock) { 168868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala checkIfCameraClosed(); 169868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 17057ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin HashSet<Surface> addSet = new HashSet<Surface>(outputs); // Streams to create 17157ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin List<Integer> deleteList = new ArrayList<Integer>(); // Streams to delete 17257ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin 17357ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin // Determine which streams need to be created, which to be deleted 17457ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin for (int i = 0; i < mConfiguredOutputs.size(); ++i) { 17557ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin int streamId = mConfiguredOutputs.keyAt(i); 17657ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin Surface s = mConfiguredOutputs.valueAt(i); 17757ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin 17857ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin if (!outputs.contains(s)) { 17957ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin deleteList.add(streamId); 18057ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin } else { 18157ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin addSet.remove(s); // Don't create a stream previously created 18257ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin } 18357ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin } 18457ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin 185868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler.post(mCallOnBusy); 186868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala stopRepeating(); 187868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 18857ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin try { 189decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk waitUntilIdle(); 19057ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin 191868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala // TODO: mRemoteDevice.beginConfigure 19257ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin // Delete all streams first (to free up HW resources) 19357ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin for (Integer streamId : deleteList) { 19457ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin mRemoteDevice.deleteStream(streamId); 19557ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin mConfiguredOutputs.delete(streamId); 19657ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin } 19757ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin 19857ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin // Add all new streams 19957ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin for (Surface s : addSet) { 20070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // TODO: remove width,height,format since we are ignoring 20170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // it. 20257ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin int streamId = mRemoteDevice.createStream(0, 0, 0, s); 20357ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin mConfiguredOutputs.put(streamId, s); 20470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 20557ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin 20657ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin // TODO: mRemoteDevice.endConfigure 20757ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin } catch (CameraRuntimeException e) { 20857ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin if (e.getReason() == CAMERA_IN_USE) { 20957ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin throw new IllegalStateException("The camera is currently busy." + 210868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala " You must wait until the previous operation completes."); 21157ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin } 21257ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin 21357ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin throw e.asChecked(); 21457ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin } catch (RemoteException e) { 21557ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin // impossible 21657ea59b376c6b72206b5b339733ee5874b181762Igor Murashkin return; 21770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 218868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 219868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (outputs.size() > 0) { 220868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler.post(mCallOnIdle); 221868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } else { 222868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler.post(mCallOnUnconfigured); 223868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 22470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 22570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 22670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 22770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 22870c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala public CaptureRequest.Builder createCaptureRequest(int templateType) 22970c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala throws CameraAccessException { 23070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin synchronized (mLock) { 231868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala checkIfCameraClosed(); 23270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 23370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala CameraMetadataNative templatedRequest = new CameraMetadataNative(); 23470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 23570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin try { 23670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin mRemoteDevice.createDefaultRequest(templateType, /* out */templatedRequest); 23770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } catch (CameraRuntimeException e) { 23870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin throw e.asChecked(); 23970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } catch (RemoteException e) { 24070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // impossible 24170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return null; 24270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 24370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 24470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala CaptureRequest.Builder builder = 24570c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala new CaptureRequest.Builder(templatedRequest); 24670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 24770c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala return builder; 24870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 24970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 25070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 25170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 2526bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin public int capture(CaptureRequest request, CaptureListener listener, Handler handler) 25370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin throws CameraAccessException { 2546bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin return submitCaptureRequest(request, listener, handler, /*streaming*/false); 25570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 25670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 25770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 2586bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin public int captureBurst(List<CaptureRequest> requests, CaptureListener listener, 2594af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala Handler handler) throws CameraAccessException { 260fc19e2cfe5bd0bc5f5be8a216ef5ee398a86b048Zhijun He if (requests.isEmpty()) { 261fc19e2cfe5bd0bc5f5be8a216ef5ee398a86b048Zhijun He Log.w(TAG, "Capture burst request list is empty, do nothing!"); 2626bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin return -1; 263fc19e2cfe5bd0bc5f5be8a216ef5ee398a86b048Zhijun He } 26470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // TODO 26570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin throw new UnsupportedOperationException("Burst capture implemented yet"); 26670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 26770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 26870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 2696bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin private int submitCaptureRequest(CaptureRequest request, CaptureListener listener, 2704af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala Handler handler, boolean repeating) throws CameraAccessException { 2714af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala 2724af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala // Need a valid handler, or current thread needs to have a looper, if 2734af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala // listener is valid 274e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala if (listener != null) { 275e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala handler = checkHandler(handler); 2764af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala } 27770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 27870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin synchronized (mLock) { 279868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala checkIfCameraClosed(); 28070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin int requestId; 28170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 282e73b41b27f16b160cfe49bdcac3091dce94229aeRuben Brunk if (repeating) { 283e73b41b27f16b160cfe49bdcac3091dce94229aeRuben Brunk stopRepeating(); 284e73b41b27f16b160cfe49bdcac3091dce94229aeRuben Brunk } 285e73b41b27f16b160cfe49bdcac3091dce94229aeRuben Brunk 28670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin try { 28770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin requestId = mRemoteDevice.submitRequest(request, repeating); 28870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } catch (CameraRuntimeException e) { 28970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin throw e.asChecked(); 29070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } catch (RemoteException e) { 29170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // impossible 2926bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin return -1; 29370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 2944af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala if (listener != null) { 2954af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala mCaptureListenerMap.put(requestId, new CaptureListenerHolder(listener, request, 2964af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala handler, repeating)); 2974af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala } 29870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 29970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (repeating) { 300decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk mRepeatingRequestId = requestId; 30170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 30270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 303868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (mIdle) { 304868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler.post(mCallOnActive); 305868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 306868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mIdle = false; 307868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 3086bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin return requestId; 30970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 31070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 31170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 31270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 3136bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin public int setRepeatingRequest(CaptureRequest request, CaptureListener listener, 3144af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala Handler handler) throws CameraAccessException { 3156bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin return submitCaptureRequest(request, listener, handler, /*streaming*/true); 31670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 31770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 31870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 3196bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin public int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener, 3204af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala Handler handler) throws CameraAccessException { 321fc19e2cfe5bd0bc5f5be8a216ef5ee398a86b048Zhijun He if (requests.isEmpty()) { 322fc19e2cfe5bd0bc5f5be8a216ef5ee398a86b048Zhijun He Log.w(TAG, "Set Repeating burst request list is empty, do nothing!"); 3236bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin return -1; 324fc19e2cfe5bd0bc5f5be8a216ef5ee398a86b048Zhijun He } 32570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // TODO 32670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin throw new UnsupportedOperationException("Burst capture implemented yet"); 32770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 32870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 32970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 33070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public void stopRepeating() throws CameraAccessException { 33170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 33270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin synchronized (mLock) { 333868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala checkIfCameraClosed(); 334decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk if (mRepeatingRequestId != REQUEST_ID_NONE) { 335decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk 336decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk int requestId = mRepeatingRequestId; 337decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk mRepeatingRequestId = REQUEST_ID_NONE; 338decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk 339decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk // Queue for deletion after in-flight requests finish 340decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk mRepeatingRequestIdDeletedList.add(requestId); 34170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 34270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin try { 34370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin mRemoteDevice.cancelRequest(requestId); 34470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } catch (CameraRuntimeException e) { 34570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin throw e.asChecked(); 34670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } catch (RemoteException e) { 34770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // impossible 34870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 34970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 35070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 35170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 35270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 35370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 35470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 35570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public void waitUntilIdle() throws CameraAccessException { 3567f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He 3577f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He synchronized (mLock) { 3587f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He checkIfCameraClosed(); 359decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk if (mRepeatingRequestId != REQUEST_ID_NONE) { 3607f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He throw new IllegalStateException("Active repeating request ongoing"); 3617f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He } 3627f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He 3637f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He try { 3647f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He mRemoteDevice.waitUntilIdle(); 3657f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He } catch (CameraRuntimeException e) { 3667f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He throw e.asChecked(); 3677f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He } catch (RemoteException e) { 3687f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He // impossible 3697f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He return; 3707f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He } 371decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk 372decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk mRepeatingRequestId = REQUEST_ID_NONE; 373decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk mRepeatingRequestIdDeletedList.clear(); 374decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk mCaptureListenerMap.clear(); 375e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 37670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 37770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 37870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 3798ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala public void flush() throws CameraAccessException { 3808ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala synchronized (mLock) { 381868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala checkIfCameraClosed(); 382868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 383868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler.post(mCallOnBusy); 3848ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala try { 3858ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala mRemoteDevice.flush(); 3868ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala } catch (CameraRuntimeException e) { 3878ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala throw e.asChecked(); 3888ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala } catch (RemoteException e) { 3898ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala // impossible 3908ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala return; 3918ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala } 3928ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala } 3938ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala } 3948ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala 3958ebd52bf4166a5ef8b7e91c9e3ecce2ce27cff12Eino-Ville Talvala @Override 3965c9eaf6796a4c972710dd5cd23cdfa334fa8ad2eIgor Murashkin public void close() { 39770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin synchronized (mLock) { 39870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 39970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin try { 4002a3eced15eddc322b946462b9018285997396a99Igor Murashkin if (mRemoteDevice != null) { 4012a3eced15eddc322b946462b9018285997396a99Igor Murashkin mRemoteDevice.disconnect(); 4022a3eced15eddc322b946462b9018285997396a99Igor Murashkin } 40370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } catch (CameraRuntimeException e) { 4045c9eaf6796a4c972710dd5cd23cdfa334fa8ad2eIgor Murashkin Log.e(TAG, "Exception while closing: ", e.asChecked()); 40570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } catch (RemoteException e) { 40670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // impossible 40770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 40870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 409868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (mRemoteDevice != null) { 410868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceHandler.post(mCallOnClosed); 411868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 41270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 413868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mRemoteDevice = null; 41470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 41570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 41670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 41770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 41870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin protected void finalize() throws Throwable { 41970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin try { 42070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin close(); 42170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 42270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin finally { 42370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin super.finalize(); 42470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 42570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 42670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 42770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin static class CaptureListenerHolder { 42870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 42970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin private final boolean mRepeating; 43070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin private final CaptureListener mListener; 43170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin private final CaptureRequest mRequest; 4324af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala private final Handler mHandler; 43370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 4344af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala CaptureListenerHolder(CaptureListener listener, CaptureRequest request, Handler handler, 4354af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala boolean repeating) { 4364af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala if (listener == null || handler == null) { 4374af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala throw new UnsupportedOperationException( 4384af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala "Must have a valid handler and a valid listener"); 4394af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala } 44070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin mRepeating = repeating; 4414af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala mHandler = handler; 44270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin mRequest = request; 44370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin mListener = listener; 44470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 44570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 44670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public boolean isRepeating() { 44770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return mRepeating; 44870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 44970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 45070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public CaptureListener getListener() { 45170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return mListener; 45270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 45370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 45470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public CaptureRequest getRequest() { 45570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return mRequest; 45670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 4574af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala 4584af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala public Handler getHandler() { 4594af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala return mHandler; 4604af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala } 4614af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala 46270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 46370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 464ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub { 46570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 466e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // 467e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // Constants below need to be kept up-to-date with 468e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h 469e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // 470e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 471e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // 472e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // Error codes for onCameraError 473e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // 474e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 475e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala /** 476e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala * Camera has been disconnected 477e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala */ 478e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala static final int ERROR_CAMERA_DISCONNECTED = 0; 479e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 480e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala /** 481e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala * Camera has encountered a device-level error 482e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala * Matches CameraDevice.StateListener#ERROR_CAMERA_DEVICE 483e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala */ 484e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala static final int ERROR_CAMERA_DEVICE = 1; 485e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 486e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala /** 487e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala * Camera has encountered a service-level error 488e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala * Matches CameraDevice.StateListener#ERROR_CAMERA_SERVICE 489e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala */ 490e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala static final int ERROR_CAMERA_SERVICE = 2; 491e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 49270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 49370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin public IBinder asBinder() { 49470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return this; 49570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 49670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 49770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 498e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala public void onCameraError(final int errorCode) { 499868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala Runnable r = null; 500868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (isClosed()) return; 501868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 502868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala synchronized(mLock) { 503e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala switch (errorCode) { 504e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala case ERROR_CAMERA_DISCONNECTED: 505868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala r = mCallOnDisconnected; 506e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala break; 507868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala default: 508868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala Log.e(TAG, "Unknown error from camera device: " + errorCode); 509868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala // no break 510e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala case ERROR_CAMERA_DEVICE: 511e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala case ERROR_CAMERA_SERVICE: 512e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala r = new Runnable() { 513e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala public void run() { 514868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 515868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala mDeviceListener.onError(CameraDevice.this, errorCode); 516868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 517e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 518e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala }; 519e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala break; 520e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 521868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala CameraDevice.this.mDeviceHandler.post(r); 522e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 523e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 524e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 525e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala @Override 526e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala public void onCameraIdle() { 527868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (isClosed()) return; 528868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 529e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala if (DEBUG) { 530e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala Log.d(TAG, "Camera now idle"); 531e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 532e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala synchronized (mLock) { 533868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.mIdle) { 534868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala CameraDevice.this.mDeviceHandler.post(mCallOnIdle); 535868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 536868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala CameraDevice.this.mIdle = true; 537e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 538e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 539e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 540e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala @Override 541e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala public void onCaptureStarted(int requestId, final long timestamp) { 542ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He if (DEBUG) { 543e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala Log.d(TAG, "Capture started for id " + requestId); 544e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 545e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala final CaptureListenerHolder holder; 546e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 547e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // Get the listener for this frame ID, if there is one 548e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala synchronized (mLock) { 549e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala holder = CameraDevice.this.mCaptureListenerMap.get(requestId); 550ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He } 551e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 552e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala if (holder == null) { 553e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala return; 554e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 555e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 556868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (isClosed()) return; 557868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 558e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala // Dispatch capture start notice 559e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala holder.getHandler().post( 560e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala new Runnable() { 561e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala public void run() { 562868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()) { 563868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala holder.getListener().onCaptureStarted( 564868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala CameraDevice.this, 565868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala holder.getRequest(), 566868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala timestamp); 567868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 568e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 569e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala }); 57070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 57170725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 57270725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin @Override 57370c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala public void onResultReceived(int requestId, CameraMetadataNative result) 57470c2207c34cf0e6b3b383b1b1500ff5385aa51a6Eino-Ville Talvala throws RemoteException { 575ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He if (DEBUG) { 576ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He Log.d(TAG, "Received result for id " + requestId); 577ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He } 5784af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala final CaptureListenerHolder holder; 57970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 5807a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala Boolean quirkPartial = result.get(CaptureResult.QUIRKS_PARTIAL_RESULT); 5817a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala boolean quirkIsPartialResult = (quirkPartial != null && quirkPartial); 5827a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala 58370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin synchronized (mLock) { 58470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // TODO: move this whole map into this class to make it more testable, 58570725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // exposing the methods necessary like subscribeToRequest, unsubscribe.. 58670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // TODO: make class static class 58770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 588ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He holder = CameraDevice.this.mCaptureListenerMap.get(requestId); 58970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 59070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin // Clean up listener once we no longer expect to see it. 5917a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala if (holder != null && !holder.isRepeating() && !quirkIsPartialResult) { 592ecb323e3ce94f62411b6799f9a0aa42b052de30dZhijun He CameraDevice.this.mCaptureListenerMap.remove(requestId); 59370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 594decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk 595decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk // TODO: add 'capture sequence completed' callback to the 596decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk // service, and clean up repeating requests there instead. 597decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk 598decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk // If we received a result for a repeating request and have 599decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk // prior repeating requests queued for deletion, remove those 600decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk // requests from mCaptureListenerMap. 6017a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala if (holder != null && holder.isRepeating() && !quirkIsPartialResult 602decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk && mRepeatingRequestIdDeletedList.size() > 0) { 603decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk Iterator<Integer> iter = mRepeatingRequestIdDeletedList.iterator(); 604decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk while (iter.hasNext()) { 605decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk int deletedRequestId = iter.next(); 606decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk if (deletedRequestId < requestId) { 607decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk CameraDevice.this.mCaptureListenerMap.remove(deletedRequestId); 608decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk iter.remove(); 609decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk } 610decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk } 611decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk } 612decfe95fce05627fe6ff5d6fa5801864fb30dc6bRuben Brunk 61370725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 61470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 6154af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala // Check if we have a listener for this 61670725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin if (holder == null) { 61770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin return; 61870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 61970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 620868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (isClosed()) return; 621868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 6226bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin final CaptureRequest request = holder.getRequest(); 6236bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin final CaptureResult resultAsCapture = new CaptureResult(result, request, requestId); 62470725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 6257a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala Runnable resultDispatch = null; 6267a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala 6277a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala // Either send a partial result or the final capture completed result 6287a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala if (quirkIsPartialResult) { 6297a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala // Partial result 6307a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala resultDispatch = new Runnable() { 6317a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala @Override 6327a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala public void run() { 6337a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala if (!CameraDevice.this.isClosed()){ 6347a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala holder.getListener().onCapturePartial( 6357a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala CameraDevice.this, 6367a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala request, 6377a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala resultAsCapture); 6387a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala } 6397a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala } 6407a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala }; 6417a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala } else { 6427a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala // Final capture result 6437a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala resultDispatch = new Runnable() { 6446bbf9dc5ae7ebc85991dcfe3e18e837b12d3f333Igor Murashkin @Override 6454af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala public void run() { 646868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala if (!CameraDevice.this.isClosed()){ 647868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala holder.getListener().onCaptureCompleted( 648868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala CameraDevice.this, 649868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala request, 650868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala resultAsCapture); 651868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 6524af73c2153747d0624ccc75dfa001cb91982957fEino-Ville Talvala } 6537a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala }; 6547a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala } 6557a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala 6567a31310439b8ac6a9dca9e81dd3366221bbb1057Eino-Ville Talvala holder.getHandler().post(resultDispatch); 65770725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 65870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 65970725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin } 66070725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin 661e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala /** 662e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala * Default handler management. If handler is null, get the current thread's 663e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala * Looper to create a Handler with. If no looper exists, throw exception. 664e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala */ 665e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala private Handler checkHandler(Handler handler) { 666e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala if (handler == null) { 667e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala Looper looper = Looper.myLooper(); 668e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala if (looper == null) { 669e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala throw new IllegalArgumentException( 670e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala "No handler given, and current thread has no looper!"); 671e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 672e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala handler = new Handler(looper); 673e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 674e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala return handler; 675e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala } 676e841d4e16526a2e466f662305682aa3459d07c15Eino-Ville Talvala 6777f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He private void checkIfCameraClosed() { 6787f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He if (mRemoteDevice == null) { 6797f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He throw new IllegalStateException("CameraDevice was already closed"); 6807f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He } 6817f4d3147d1851d2f0c544e45390c139bda9fd9aaZhijun He } 682868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala 683868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala private boolean isClosed() { 684868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala synchronized(mLock) { 685868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala return (mRemoteDevice == null); 686868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 687868d904306c6a96d94fa0da03515c51c86eefc63Eino-Ville Talvala } 68870725500dcf3b666b43d50563d64705aab58d2d3Igor Murashkin} 689