1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18package com.android.camera.one.v2;
19
20import android.annotation.TargetApi;
21import android.hardware.camera2.CameraAccessException;
22import android.hardware.camera2.CameraCharacteristics;
23import android.hardware.camera2.CameraManager;
24import android.os.Build.VERSION_CODES;
25
26import com.android.camera.debug.Log;
27import com.android.camera.debug.Log.Tag;
28import com.android.camera.device.CameraId;
29import com.android.camera.one.OneCamera.Facing;
30import com.android.camera.one.OneCameraAccessException;
31import com.android.camera.one.OneCameraCharacteristics;
32import com.android.camera.one.OneCameraManager;
33import com.android.camera.util.AndroidServices;
34import com.android.camera.util.ApiHelper;
35import com.google.common.base.Optional;
36
37import javax.annotation.Nonnull;
38
39/**
40 * Pick camera ids from a list of devices based on defined characteristics.
41 */
42@TargetApi(VERSION_CODES.LOLLIPOP)
43public class Camera2OneCameraManagerImpl implements OneCameraManager {
44    private static final Tag TAG = new Tag("Camera2OneCamMgr");
45    /**
46     * Create a new camera2 api hardware manager.
47     */
48    public static Optional<Camera2OneCameraManagerImpl> create() {
49        if (!ApiHelper.HAS_CAMERA_2_API) {
50            return Optional.absent();
51        }
52        CameraManager cameraManager;
53        try {
54            cameraManager = AndroidServices.instance().provideCameraManager();
55        } catch (IllegalStateException ex) {
56            Log.e(TAG, "camera2.CameraManager is not available.");
57            return Optional.absent();
58        }
59        Camera2OneCameraManagerImpl hardwareManager =
60              new Camera2OneCameraManagerImpl(cameraManager);
61        return Optional.of(hardwareManager);
62    }
63
64    private final CameraManager mCameraManager;
65
66    public Camera2OneCameraManagerImpl(CameraManager cameraManger) {
67        mCameraManager = cameraManger;
68    }
69
70    @Override
71    public boolean hasCamera() {
72        try {
73            String[] ids = mCameraManager.getCameraIdList();
74            return ids != null && ids.length > 0;
75        } catch (CameraAccessException ex) {
76            Log.e(TAG, "Unable to read camera list.", ex);
77            return false;
78        }
79    }
80
81    @Override
82    public boolean hasCameraFacing(@Nonnull Facing direction) {
83        return findCameraId(direction) != null;
84    }
85
86    @Override
87    public CameraId findFirstCamera() {
88        try {
89            String[] ids = mCameraManager.getCameraIdList();
90            if(ids != null && ids.length > 0) {
91                return CameraId.from(ids[0]);
92            }
93        } catch (CameraAccessException ex) {
94            Log.e(TAG, "Unable to read camera list.", ex);
95        }
96
97        return null;
98    }
99
100    @Override
101    public CameraId findFirstCameraFacing(@Nonnull Facing facing) {
102        String cameraId = findCameraId(facing);
103        return (cameraId != null) ? CameraId.from(cameraId) : null;
104    }
105
106    @Override
107    public OneCameraCharacteristics getOneCameraCharacteristics(
108          @Nonnull CameraId key)
109          throws OneCameraAccessException {
110        return new OneCameraCharacteristicsImpl(getCameraCharacteristics(key));
111    }
112
113    public CameraCharacteristics getCameraCharacteristics(
114          @Nonnull CameraId key)
115          throws OneCameraAccessException {
116        try {
117            return mCameraManager.getCameraCharacteristics(key.getValue());
118        } catch (CameraAccessException ex) {
119            throw new OneCameraAccessException("Unable to get camera characteristics", ex);
120        }
121    }
122
123    /** Returns the ID of the first camera facing the given direction. */
124    private String findCameraId(Facing facing) {
125        if (facing == Facing.FRONT) {
126            return findFirstFrontCameraId();
127        } else {
128            return findFirstBackCameraId();
129        }
130    }
131
132    /** Returns the ID of the first back-facing camera. */
133    private String findFirstBackCameraId() {
134        Log.d(TAG, "Getting First BACK Camera");
135        String cameraId = findFirstCameraIdFacing(CameraCharacteristics.LENS_FACING_BACK);
136        if (cameraId == null) {
137            Log.w(TAG, "No back-facing camera found.");
138        }
139        return cameraId;
140    }
141
142    /** Returns the ID of the first front-facing camera. */
143    private String findFirstFrontCameraId() {
144        Log.d(TAG, "Getting First FRONT Camera");
145        String cameraId = findFirstCameraIdFacing(CameraCharacteristics.LENS_FACING_FRONT);
146        if (cameraId == null) {
147            Log.w(TAG, "No front-facing camera found.");
148        }
149        return cameraId;
150    }
151
152
153    /** Returns the ID of the first camera facing the given direction. */
154    private String findFirstCameraIdFacing(int facing) {
155        try {
156            String[] cameraIds = mCameraManager.getCameraIdList();
157            for (String cameraId : cameraIds) {
158                CameraCharacteristics characteristics = mCameraManager
159                      .getCameraCharacteristics(cameraId);
160                if (characteristics.get(CameraCharacteristics.LENS_FACING) == facing) {
161                    return cameraId;
162                }
163            }
164        } catch (CameraAccessException ex) {
165            Log.w(TAG, "Unable to get camera ID", ex);
166        }
167        return null;
168    }
169
170}