PortabilityCameraActions.java revision b6a4d96a310a1dee22ddea89b09130bcda206bb3
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
36b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde/**
37b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * Set of device actions for opening and closing a single portability
38b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde * layer camera device.
39b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde */
40b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohdepublic class PortabilityCameraActions implements SingleDeviceActions<CameraProxy> {
41b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private static final Tag TAG = new Tag("Camera2PReq");
42b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
43b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private final CameraDeviceKey<Integer> mId;
44b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private final HandlerFactory mHandlerFactory;
45b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private final ExecutorService mBackgroundRunner;
46b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private final Context mContext;
47b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private final CameraApi mApiVersion;
48b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private final Logger mLogger;
49b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
50b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    public PortabilityCameraActions(
51b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde          CameraDeviceKey<Integer> id,
52b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde          Context context,
53b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde          CameraApi apiVersion,
54b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde          ExecutorService backgroundRunner,
55b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde          HandlerFactory handlerFactory,
56b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde          Logger.Factory logFactory) {
57b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mId = id;
58b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mContext = context;
59b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mApiVersion = apiVersion;
60b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mBackgroundRunner = backgroundRunner;
61b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mHandlerFactory = handlerFactory;
62b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mLogger = logFactory.create(TAG);
63b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
64b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mLogger.d("Created Camera2Request");
65b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    }
66b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
67b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    @Override
68b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    public void executeOpen(SingleDeviceOpenListener<CameraProxy> openListener,
69b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde          Lifetime deviceLifetime) {
70b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mLogger.d("executeOpen()");
71b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        CameraAgent agent = CameraAgentFactory.getAndroidCameraAgent(mContext, mApiVersion);
72b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        deviceLifetime.add(new CameraAgentRecycler(mApiVersion, mLogger));
73b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
74b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mBackgroundRunner.execute(new OpenCameraRunnable(agent, mId.getCameraId(),
75b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde              mHandlerFactory.create(deviceLifetime, "Camera2 Lifetime"),
76b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde              openListener, mLogger));
77b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    }
78b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
79b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    @Override
80b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    public void executeClose(SingleDeviceCloseListener closeListener, CameraProxy device) {
81b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mLogger.d("executeClose()");
82b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        mBackgroundRunner.execute(new CloseCameraRunnable(device, device.getAgent(),
83b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde              closeListener, mLogger));
84b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    }
85b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
86b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    /**
87b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     * Recycles camera agents and ensures that recycle is only called
88b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     * once per instance.
89b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     */
90b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private static class CameraAgentRecycler implements SafeCloseable {
91b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final CameraApi mCameraApi;
92b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final Logger mLogger;
93b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final AtomicBoolean mIsClosed;
94b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
95b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public CameraAgentRecycler(CameraApi cameraApi, Logger logger) {
96b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mCameraApi = cameraApi;
97b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mLogger = logger;
98b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mIsClosed = new AtomicBoolean(false);
99b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
100b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
101b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        @Override
102b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public void close() {
103b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            if (!mIsClosed.getAndSet(true)) {
104b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("Recycling CameraAgentFactory for CameraApi: " + mCameraApi);
105b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                CameraAgentFactory.recycle(mCameraApi);
106b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
107b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
108b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    }
109b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
110b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    /**
111b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     * Internal runnable that executes a CameraManager openCamera call.
112b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     */
113b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private static class OpenCameraRunnable implements Runnable {
114b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final SingleDeviceOpenListener<CameraProxy> mOpenListener;
115b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final int mCameraId;
116b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final Handler mHandler;
117b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final CameraAgent mCameraAgent;
118b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final Logger mLogger;
119b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
120b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public OpenCameraRunnable(CameraAgent cameraAgent, int cameraId,
121b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde              Handler handler, SingleDeviceOpenListener<CameraProxy> openListener,
122b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde              Logger logger) {
123b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mCameraAgent = cameraAgent;
124b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mCameraId = cameraId;
125b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mHandler = handler;
126b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mOpenListener = openListener;
127b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mLogger = logger;
128b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
129b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
130b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        @Override
131b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public void run() {
132b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            try {
133b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("mCameraAgent.openCamera()");
134b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mCameraAgent.openCamera(mHandler, mCameraId,
135b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                      new OpenCameraStateCallback(mOpenListener, mLogger));
136b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            } catch (SecurityException e) {
137b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mOpenListener.onDeviceOpenException(e);
138b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
139b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
140b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    }
141b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
142b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    /**
143b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     * Internal runnable that executes a close on a cameraDevice.
144b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     */
145b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private static class CloseCameraRunnable implements Runnable {
146b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final SingleDeviceCloseListener mCloseListener;
147b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final CameraProxy mCameraDevice;
148b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final CameraAgent mCameraAgent;
149b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final Logger mLogger;
150b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
151b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public CloseCameraRunnable(CameraProxy cameraDevice, CameraAgent cameraAgent,
152b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde              SingleDeviceCloseListener closeListener, Logger logger) {
153b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mCameraDevice = cameraDevice;
154b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mCameraAgent = cameraAgent;
155b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mCloseListener = closeListener;
156b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mLogger = logger;
157b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
158b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
159b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        @Override
160b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public void run() {
161b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            try {
162b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("mCameraAgent.closeCamera");
163b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mCameraAgent.closeCamera(mCameraDevice, true /* synchronous */);
164b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mCloseListener.onDeviceClosed();
165b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            } catch (Exception e) {
166b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mCloseListener.onDeviceClosingException(e);
167b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
168b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
169b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    }
170b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
171b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    /**
172b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     * Internal callback that provides a camera device to a future.
173b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde     */
174b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    private static class OpenCameraStateCallback implements CameraOpenCallback {
175b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final SingleDeviceOpenListener<CameraProxy> mOpenListener;
176b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private final Logger mLogger;
177b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private boolean mHasBeenCalled = false;
178b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
179b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public OpenCameraStateCallback(SingleDeviceOpenListener<CameraProxy> openListener,
180b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde              Logger logger) {
181b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mOpenListener = openListener;
182b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            mLogger = logger;
183b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
184b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
185b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        private boolean called() {
186b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            boolean result = mHasBeenCalled;
187b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            if (!mHasBeenCalled) {
188b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mHasBeenCalled = true;
189b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            } else {
190b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("Callback was re-executed.");
191b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
192b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
193b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            return result;
194b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
195b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
196b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        @Override
197b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public void onCameraOpened(CameraProxy camera) {
198b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            if (!called()) {
199b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("onOpened(cameraDevice: " + camera.getCameraId() + ")");
200b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mOpenListener.onDeviceOpened(camera);
201b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
202b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
203b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
204b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        @Override
205b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public void onCameraDisabled(int cameraId) {
206b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            if (!called()) {
207b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("onCameraDisabled(cameraId: " + cameraId + ")");
208b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mOpenListener.onDeviceOpenException(new CameraOpenException(-1));
209b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
210b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
211b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
212b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        @Override
213b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public void onDeviceOpenFailure(int cameraId, String info) {
214b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            if (!called()) {
215b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("onDeviceOpenFailure(cameraId: " + cameraId
216b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                      + ", info: " + info + ")");
217b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mOpenListener.onDeviceOpenException(new CameraOpenException(-1));
218b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
219b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
220b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
221b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        @Override
222b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public void onDeviceOpenedAlready(int cameraId, String info) {
223b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            if (!called()) {
224b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("onDeviceOpenedAlready(cameraId: " + cameraId
225b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                      + ", info: " + info + ")");
226b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mOpenListener.onDeviceOpenException(new CameraOpenException(-1));
227b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
228b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
229b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde
230b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        @Override
231b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        public void onReconnectionFailure(CameraAgent mgr, String info) {
232b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            if (!called()) {
233b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mLogger.d("onReconnectionFailure: " + info);
234b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde                mOpenListener.onDeviceOpenException(new CameraOpenException(-1));
235b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde            }
236b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde        }
237b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde    }
238b6a4d96a310a1dee22ddea89b09130bcda206bb3Paul Rohde}
239