1b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde/* 2b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Copyright (C) 2015 The Android Open Source Project 3b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * 4b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Licensed under the Apache License, Version 2.0 (the "License"); 5b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * you may not use this file except in compliance with the License. 6b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * You may obtain a copy of the License at 7b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * 8b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * http://www.apache.org/licenses/LICENSE-2.0 9b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * 10b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Unless required by applicable law or agreed to in writing, software 11b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * distributed under the License is distributed on an "AS IS" BASIS, 12b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * See the License for the specific language governing permissions and 14b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * limitations under the License. 15b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 16b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 17b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdepackage com.android.camera.device; 18b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 19b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport android.content.Context; 20b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport android.os.Handler; 21b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 22b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.camera.async.HandlerFactory; 23b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.camera.async.Lifetime; 24b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.camera.async.SafeCloseable; 25b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.camera.debug.Log.Tag; 26b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.camera.debug.Logger; 27b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.ex.camera2.portability.CameraAgent; 28b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.ex.camera2.portability.CameraAgent.CameraOpenCallback; 29b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.ex.camera2.portability.CameraAgent.CameraProxy; 30b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.ex.camera2.portability.CameraAgentFactory; 31b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport com.android.ex.camera2.portability.CameraAgentFactory.CameraApi; 32b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 33b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport java.util.concurrent.ExecutorService; 34b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdeimport java.util.concurrent.atomic.AtomicBoolean; 35b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 36d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohdeimport javax.annotation.ParametersAreNonnullByDefault; 37d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde 38b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde/** 39b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Set of device actions for opening and closing a single portability 40b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * layer camera device. 41b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 42d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde@ParametersAreNonnullByDefault 43b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdepublic class PortabilityCameraActions implements SingleDeviceActions<CameraProxy> { 44d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde private static final Tag TAG = new Tag("PortCamAct"); 45b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 461d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private final CameraDeviceKey mId; 47b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final HandlerFactory mHandlerFactory; 48b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final ExecutorService mBackgroundRunner; 49b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final Context mContext; 50b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final CameraApi mApiVersion; 51b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final Logger mLogger; 52b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 53b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public PortabilityCameraActions( 541d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde CameraDeviceKey id, 55b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde Context context, 56b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde CameraApi apiVersion, 57b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde ExecutorService backgroundRunner, 58b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde HandlerFactory handlerFactory, 59b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde Logger.Factory logFactory) { 60b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mId = id; 61b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mContext = context; 62b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mApiVersion = apiVersion; 63b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mBackgroundRunner = backgroundRunner; 64b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mHandlerFactory = handlerFactory; 65b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLogger = logFactory.create(TAG); 66b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 67b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLogger.d("Created Camera2Request"); 68b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 69b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 70b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 71b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void executeOpen(SingleDeviceOpenListener<CameraProxy> openListener, 721d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Lifetime deviceLifetime) throws UnsupportedOperationException { 73d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.i("executeOpen(id: " + mId.getCameraId() + ")"); 74e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin try { 75e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin CameraAgent agent = CameraAgentFactory.getAndroidCameraAgent(mContext, mApiVersion); 76e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin deviceLifetime.add(new CameraAgentRecycler(mApiVersion, mLogger)); 77b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 78e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin mBackgroundRunner.execute(new OpenCameraRunnable(agent, mId.getCameraId().getLegacyValue(), 79e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin mHandlerFactory.create(deviceLifetime, "Camera2 Lifetime"), 80e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin openListener, mLogger)); 81e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin } catch (AssertionError e) { 82e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin openListener.onDeviceOpenException(e); 83e3ba951d640316c598f0e690422879e8d4ba0a62Pengchong Jin } 84b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 85b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 86b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 87b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void executeClose(SingleDeviceCloseListener closeListener, CameraProxy device) { 88d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.i("executeClose(" + device.getCameraId() + ")"); 89b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mBackgroundRunner.execute(new CloseCameraRunnable(device, device.getAgent(), 90b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde closeListener, mLogger)); 91b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 92b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 93b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde /** 94b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Recycles camera agents and ensures that recycle is only called 95b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * once per instance. 96b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 97b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private static class CameraAgentRecycler implements SafeCloseable { 98b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final CameraApi mCameraApi; 99b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final Logger mLogger; 100b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final AtomicBoolean mIsClosed; 101b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 102b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public CameraAgentRecycler(CameraApi cameraApi, Logger logger) { 103b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCameraApi = cameraApi; 104b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLogger = logger; 105b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mIsClosed = new AtomicBoolean(false); 106b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 107b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 108b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 109b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void close() { 110b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!mIsClosed.getAndSet(true)) { 111b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLogger.d("Recycling CameraAgentFactory for CameraApi: " + mCameraApi); 112b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde CameraAgentFactory.recycle(mCameraApi); 113b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 114b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 115b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 116b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 117b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde /** 118b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Internal runnable that executes a CameraManager openCamera call. 119b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 120b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private static class OpenCameraRunnable implements Runnable { 121b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final SingleDeviceOpenListener<CameraProxy> mOpenListener; 122b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final int mCameraId; 123b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final Handler mHandler; 124b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final CameraAgent mCameraAgent; 125b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final Logger mLogger; 126b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 127b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public OpenCameraRunnable(CameraAgent cameraAgent, int cameraId, 128b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde Handler handler, SingleDeviceOpenListener<CameraProxy> openListener, 129b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde Logger logger) { 130b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCameraAgent = cameraAgent; 131b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCameraId = cameraId; 132b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mHandler = handler; 133b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mOpenListener = openListener; 134b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLogger = logger; 135b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 136b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 137b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 138b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void run() { 139b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde try { 140d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.i("mCameraAgent.openCamera(id: " + mCameraId + ")"); 141b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCameraAgent.openCamera(mHandler, mCameraId, 142b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde new OpenCameraStateCallback(mOpenListener, mLogger)); 143b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } catch (SecurityException e) { 144b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mOpenListener.onDeviceOpenException(e); 145b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 146b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 147b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 148b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 149b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde /** 150b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Internal runnable that executes a close on a cameraDevice. 151b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 152b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private static class CloseCameraRunnable implements Runnable { 153b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final SingleDeviceCloseListener mCloseListener; 154b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final CameraProxy mCameraDevice; 155b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final CameraAgent mCameraAgent; 156b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final Logger mLogger; 157b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 158b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public CloseCameraRunnable(CameraProxy cameraDevice, CameraAgent cameraAgent, 159b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde SingleDeviceCloseListener closeListener, Logger logger) { 160b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCameraDevice = cameraDevice; 161b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCameraAgent = cameraAgent; 162b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCloseListener = closeListener; 163b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLogger = logger; 164b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 165b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 166b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 167b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void run() { 168b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde try { 169d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.i("mCameraAgent.closeCamera(id: " + mCameraDevice.getCameraId() + ")"); 170b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCameraAgent.closeCamera(mCameraDevice, true /* synchronous */); 171b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCloseListener.onDeviceClosed(); 172b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } catch (Exception e) { 173b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mCloseListener.onDeviceClosingException(e); 174b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 175b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 176b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 177b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 178b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde /** 179b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Internal callback that provides a camera device to a future. 180b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */ 181b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private static class OpenCameraStateCallback implements CameraOpenCallback { 182b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final SingleDeviceOpenListener<CameraProxy> mOpenListener; 183b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private final Logger mLogger; 184b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde private boolean mHasBeenCalled = false; 185b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 186b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public OpenCameraStateCallback(SingleDeviceOpenListener<CameraProxy> openListener, 187b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde Logger logger) { 188b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mOpenListener = openListener; 189b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mLogger = logger; 190b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 191b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 192b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 193b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void onCameraOpened(CameraProxy camera) { 194b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!called()) { 195d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.i("onCameraOpened(id: " + camera.getCameraId() + ")"); 196b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mOpenListener.onDeviceOpened(camera); 197b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 198b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 199b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 200b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 201b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void onCameraDisabled(int cameraId) { 202b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!called()) { 203d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.w("onCameraDisabled(id: " + cameraId + ")"); 204b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mOpenListener.onDeviceOpenException(new CameraOpenException(-1)); 205b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 206b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 207b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 208b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 209b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void onDeviceOpenFailure(int cameraId, String info) { 210b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!called()) { 211d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.e("onDeviceOpenFailure(id: " + cameraId 212b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde + ", info: " + info + ")"); 213b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mOpenListener.onDeviceOpenException(new CameraOpenException(-1)); 214b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 215b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 216b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 217b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 218b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void onDeviceOpenedAlready(int cameraId, String info) { 219b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!called()) { 220d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.w("onDeviceOpenedAlready(id: " + cameraId 221b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde + ", info: " + info + ")"); 222b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mOpenListener.onDeviceOpenException(new CameraOpenException(-1)); 223b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 224b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 225b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde 226b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde @Override 227b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde public void onReconnectionFailure(CameraAgent mgr, String info) { 228b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde if (!called()) { 229d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.w("onReconnectionFailure(info: " + info + ")"); 230b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde mOpenListener.onDeviceOpenException(new CameraOpenException(-1)); 231b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 232b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 233d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde 234d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde private boolean called() { 235d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde boolean result = mHasBeenCalled; 236d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde if (!mHasBeenCalled) { 237d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mHasBeenCalled = true; 238d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde } else { 239d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde mLogger.v("Callback was re-executed."); 240d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde } 241d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde 242d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde return result; 243d552f16540c59b28073e526e99fbcfe7dfa5ef09Paul Rohde } 244b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde } 245b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde} 246