17c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala/*
27c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * Copyright (C) 2014 The Android Open Source Project
37c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *
47c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
57c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * you may not use this file except in compliance with the License.
67c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * You may obtain a copy of the License at
77c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *
87c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
97c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *
107c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
117c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
127c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * See the License for the specific language governing permissions and
147c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * limitations under the License.
157c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala */
167c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
177c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalapackage com.android.testingcamera2;
187c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
197c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport java.util.HashSet;
207c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport java.util.Set;
217c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
227c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.content.Context;
237c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.hardware.camera2.CameraCharacteristics;
247c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.hardware.camera2.CameraDevice;
257c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.hardware.camera2.CameraManager;
267c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvalaimport android.hardware.camera2.CameraAccessException;
277c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
287c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala/**
297c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala * A central manager of camera devices and current clients for them.
307c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala *
317c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala */
32b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvalapublic class CameraOps2 extends CameraManager.AvailabilityCallback {
337c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
347c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    private final CameraManager mCameraManager;
357c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
3661791ada457c5282a583ac869e0f1ba0e8d1e9f4Igor Murashkin    private final Set<CameraDevice> mOpenCameras = new HashSet<CameraDevice>();
377c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
387c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public CameraOps2(Context context) {
397c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
407c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        if (mCameraManager == null) {
4161791ada457c5282a583ac869e0f1ba0e8d1e9f4Igor Murashkin            throw new AssertionError("Can't connect to camera manager!");
427c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
437c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        try {
447c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            String[] cameraIds = mCameraManager.getCameraIdList();
457c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            TLog.i("Camera count: %d", cameraIds.length);
467c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            for (String cameraId : cameraIds) {
477c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                TLog.i("  Camera %s", cameraId);
487c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            }
497c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        } catch (CameraAccessException e) {
507c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            TLog.e("Unable to get camera list: %s", e);
517c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
527c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
53b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala        mCameraManager.registerAvailabilityCallback(this, /*handler*/null);
547c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
557c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
567c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    /**
577c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * Add a listener for new camera addition events, and retrieve the list of
587c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * current cameras
597c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     *
607c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * @param listener
617c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     *            A listener to notify on changes to camera availability
627c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * @return the current list of available cameras
637c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * @throws CameraAccessException
647c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     *             if the camera manager cannot be queried
657c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     */
66b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala    public String[] getCamerasAndListen(CameraManager.AvailabilityCallback listener)
677c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            throws CameraAccessException {
687c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
69b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala        mCameraManager.registerAvailabilityCallback(listener, /*handler*/null);
707c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
717c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        return mCameraManager.getCameraIdList();
727c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
737c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
74b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala    public void removeAvailabilityCallback(CameraManager.AvailabilityCallback listener) {
75b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala        mCameraManager.unregisterAvailabilityCallback(listener);
767c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
777c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
787c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    @Override
797c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public void onCameraAvailable(String cameraId) {
807c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        TLog.i("Camera %s is now available", cameraId);
817c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
827c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
837c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    @Override
847c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public void onCameraUnavailable(String cameraId) {
857c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        TLog.i("Camera %s is now unavailable", cameraId);
867c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
877c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
887c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    /**
897c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * Attempt to open a camera device. Returns false if the open call cannot be
907c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * made or the device is already open
917c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     *
927c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * @param cameraId id of the camera to open
937c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * @param listener listener to notify of camera device state changes
947c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     * @return true if open call was sent successfully. The client needs to wait
957c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     *         for its listener to be called to determine if open will succeed.
967c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala     */
97b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala    public boolean openCamera(String cameraId, CameraDevice.StateCallback listener) {
987c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        for (CameraDevice camera : mOpenCameras) {
997c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            if (camera.getId() == cameraId) {
1007c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                TLog.e("Camera %s is already open", cameraId);
1017c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala                return false;
1027c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            }
1037c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1047c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        try {
105b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala            DeviceStateCallback proxyListener = new DeviceStateCallback(listener);
1067c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mCameraManager.openCamera(cameraId, proxyListener, null);
1077c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        } catch (CameraAccessException e) {
1087c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            TLog.e("Unable to open camera %s.", e, cameraId);
1097c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            return false;
1107c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1117c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1127c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        return true;
1137c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1147c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1157c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    public CameraCharacteristics getCameraInfo(String cameraId) {
1167c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        try {
1177c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            return mCameraManager.getCameraCharacteristics(cameraId);
1187c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        } catch (CameraAccessException e) {
1197c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            TLog.e("Unable to get camera characteristics for camera %s.", e, cameraId);
1207c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1217c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        return null;
1227c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1237c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
124b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala    private class DeviceStateCallback extends CameraDevice.StateCallback {
1257c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
126b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala        private final CameraDevice.StateCallback mClientListener;
1277c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
128b6dca4d979f37748eeb53184a3c3184dbe04d123Eino-Ville Talvala        public DeviceStateCallback(CameraDevice.StateCallback clientListener) {
1297c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mClientListener = clientListener;
1307c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1317c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1327c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        @Override
1337c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        public void onClosed(CameraDevice camera) {
1347c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mOpenCameras.remove(camera);
1357c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            TLog.i("Camera %s now closed", camera.getId());
1367c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mClientListener.onClosed(camera);
1377c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1387c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1397c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        @Override
1407c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        public void onDisconnected(CameraDevice camera) {
1417c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            TLog.i("Camera %s now disconnected", camera.getId());
1427c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mClientListener.onDisconnected(camera);
1437c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1447c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1457c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        @Override
1467c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        public void onError(CameraDevice camera, int error) {
1477c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            TLog.i("Camera %s encountered error: %d", camera.getId(), error);
1487c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mClientListener.onError(camera, error);
1497c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1507c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1517c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        @Override
1527c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        public void onOpened(CameraDevice camera) {
1537c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mOpenCameras.add(camera);
1547c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            TLog.i("Camera %s now open", camera.getId());
1557c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala            mClientListener.onOpened(camera);
1567c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala        }
1577c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala
1587c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala    }
1597c5f2935442e974ce30158e35d142f7e2c3ee1a2Eino-Ville Talvala}
160