11d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde/* 21d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * Copyright (C) 2015 The Android Open Source Project 31d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * 41d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * Licensed under the Apache License, Version 2.0 (the "License"); 51d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * you may not use this file except in compliance with the License. 61d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * You may obtain a copy of the License at 71d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * 81d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * http://www.apache.org/licenses/LICENSE-2.0 91d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * 101d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * Unless required by applicable law or agreed to in writing, software 111d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * distributed under the License is distributed on an "AS IS" BASIS, 121d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * See the License for the specific language governing permissions and 141d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * limitations under the License. 151d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde */ 161d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 171d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdepackage com.android.camera.one.v1; 181d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 191d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport android.hardware.Camera; 201d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 211d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.debug.Log; 221d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.debug.Log.Tag; 231d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.device.CameraId; 241d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.one.OneCamera.Facing; 251d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.one.OneCameraAccessException; 261d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.one.OneCameraCharacteristics; 271d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.one.OneCameraManager; 281d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.google.common.base.Optional; 291d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 301d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport javax.annotation.Nonnull; 311d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 321d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde/** 331d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * The {@link com.android.camera.one.OneCameraManager} implementation on top of the Camera API 1. 341d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde */ 351d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdepublic class LegacyOneCameraManagerImpl implements OneCameraManager { 361d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private static final Tag TAG = new Tag("LegacyHM"); 371d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private static final int NO_DEVICE = -1; 381d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private static final long CAMERA_ACCESS_TIMEOUT_MILLIS = 750; 391d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 401d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde // Lazy singleton 411d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private static Optional<LegacyOneCameraManagerImpl> INSTANCE; 421d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 431d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private final CameraId mFirstBackCameraId; 441d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private final CameraId mFirstFrontCameraId; 451d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private final Camera.CameraInfo[] mCameraInfos; 461d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 471d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private OneCameraCharacteristics mBackCameraCharacteristics; 481d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde private OneCameraCharacteristics mFrontCameraCharacteristics; 491d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 501d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde public static Optional<LegacyOneCameraManagerImpl> instance() { 511d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (INSTANCE != null) { 521d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return INSTANCE; 531d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 541d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 551d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde int numberOfCameras; 561d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Camera.CameraInfo[] cameraInfos; 571d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde try { 581d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde numberOfCameras = Camera.getNumberOfCameras(); 591d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde cameraInfos = new Camera.CameraInfo[numberOfCameras]; 601d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde for (int i = 0; i < numberOfCameras; i++) { 611d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde cameraInfos[i] = new Camera.CameraInfo(); 621d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Camera.getCameraInfo(i, cameraInfos[i]); 631d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 641d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } catch (RuntimeException ex) { 651d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.e(TAG, "Exception while creating CameraDeviceInfo", ex); 661d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return Optional.absent(); 671d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 681d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 691d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde int firstFront = NO_DEVICE; 701d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde int firstBack = NO_DEVICE; 711d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde // Get the first (smallest) back and first front camera id. 721d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde for (int i = numberOfCameras - 1; i >= 0; i--) { 731d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 741d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde firstBack = i; 751d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } else { 761d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 771d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde firstFront = i; 781d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 791d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 801d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 811d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 821d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde CameraId frontCameraId = firstFront >= 0 ? CameraId.fromLegacyId(firstFront) : null; 831d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde CameraId backCameraId = firstBack >= 0 ? CameraId.fromLegacyId(firstBack) : null; 841d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 851d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde LegacyOneCameraManagerImpl cameraManager = 861d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde new LegacyOneCameraManagerImpl(backCameraId, frontCameraId, cameraInfos); 871d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde INSTANCE = Optional.of(cameraManager); 881d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return INSTANCE; 891d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 901d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 911d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde /** 921d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde * Instantiates a new {@link com.android.camera.one.OneCameraManager} for Camera1 API. 931d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde */ 941d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde public LegacyOneCameraManagerImpl( 951d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde CameraId firstBackCameraId, 961d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde CameraId firstFrontCameraId, 971d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Camera.CameraInfo[] info) { 981d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde mFirstBackCameraId = firstBackCameraId; 991d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde mFirstFrontCameraId = firstFrontCameraId; 1001d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1011d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde mCameraInfos = info; 1021d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1031d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1041d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde @Override 1051d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde public boolean hasCamera() { 1061d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return false; 1071d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1081d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1091d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde @Override 1101d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde public boolean hasCameraFacing(@Nonnull Facing facing) { 1111d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return findFirstCameraFacing(facing) != null; 1121d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1131d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1141d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde @Override 1151d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde public CameraId findFirstCamera() { 1161d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return mFirstBackCameraId; 1171d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1181d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1191d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde @Override 1201d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde public CameraId findFirstCameraFacing(@Nonnull Facing facing) { 1211d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (facing == Facing.BACK && mFirstBackCameraId != null) { 1221d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return mFirstBackCameraId; 1231d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } else if (facing == Facing.FRONT && mFirstFrontCameraId != null) { 1241d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return mFirstFrontCameraId; 1251d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1261d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return null; 1271d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1281d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1291d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde @Override 1301d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde public OneCameraCharacteristics getOneCameraCharacteristics(@Nonnull CameraId cameraId) 1311d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde throws OneCameraAccessException { 1321d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde // Returns the cached object if there exists one. 1331d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (cameraId.equals(mFirstBackCameraId)) { 1341d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (mBackCameraCharacteristics == null) { 1351d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.w(TAG, "WARNING: Computing potentially long running device access!" 1361d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde + cameraId); 1371d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde mBackCameraCharacteristics = computeCameraCharacteristics(cameraId); 1381d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1391d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1401d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.w(TAG, "Returning camera characteristics for back camera." 1411d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde + cameraId); 1421d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1431d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return mBackCameraCharacteristics; 1441d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } else if (cameraId.equals(mFirstFrontCameraId)) { 1451d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (mFrontCameraCharacteristics == null) { 1461d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.w(TAG, "WARNING: Computing potentially long running device access!" 1471d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde + cameraId); 1481d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde mFrontCameraCharacteristics = computeCameraCharacteristics(cameraId); 1491d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1501d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1511d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.w(TAG, "Returning camera characteristics for front camera." 1521d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde + cameraId); 1531d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return mFrontCameraCharacteristics; 1541d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1551d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1561d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.e(TAG, "BackCamera: " + mFirstBackCameraId + ", " + " ==? " + (mFirstBackCameraId 1571d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde == cameraId)); 1581d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.e(TAG, "FrontCamera: " + mFirstFrontCameraId); 1591d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.e(TAG, "No matching camera id for: " + cameraId); 1601d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return null; 1611d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1621d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1631d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde public OneCameraCharacteristics computeCameraCharacteristics(CameraId key) 1641d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde throws OneCameraAccessException { 1651d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde OneCameraCharacteristics characteristics; 1661d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Camera camera = null; 1671d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde try { 1681d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde camera = Camera.open(key.getLegacyValue()); 1691d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Camera.Parameters cameraParameters = camera.getParameters(); 1701d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (cameraParameters == null) { 1711d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde Log.e(TAG, "Camera object returned null parameters!"); 1721d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde throw new OneCameraAccessException("API1 Camera.getParameters() returned null"); 1731d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1741d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde characteristics = new OneCameraCharacteristicsImpl( 1751d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde mCameraInfos[key.getLegacyValue()], cameraParameters); 1761d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } finally { 1771d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde if (camera != null) { 1781d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde camera.release(); 1791d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1801d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1811d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde 1821d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde return characteristics; 1831d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde } 1841d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde}