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 package com.android.camera.one.v1; 18 19 import android.hardware.Camera; 20 21 import com.android.camera.debug.Log; 22 import com.android.camera.debug.Log.Tag; 23 import com.android.camera.device.CameraId; 24 import com.android.camera.one.OneCamera.Facing; 25 import com.android.camera.one.OneCameraAccessException; 26 import com.android.camera.one.OneCameraCharacteristics; 27 import com.android.camera.one.OneCameraManager; 28 import com.google.common.base.Optional; 29 30 import javax.annotation.Nonnull; 31 32 /** 33 * The {@link com.android.camera.one.OneCameraManager} implementation on top of the Camera API 1. 34 */ 35 public class LegacyOneCameraManagerImpl implements OneCameraManager { 36 private static final Tag TAG = new Tag("LegacyHM"); 37 private static final int NO_DEVICE = -1; 38 private static final long CAMERA_ACCESS_TIMEOUT_MILLIS = 750; 39 40 // Lazy singleton 41 private static Optional<LegacyOneCameraManagerImpl> INSTANCE; 42 43 private final CameraId mFirstBackCameraId; 44 private final CameraId mFirstFrontCameraId; 45 private final Camera.CameraInfo[] mCameraInfos; 46 47 private OneCameraCharacteristics mBackCameraCharacteristics; 48 private OneCameraCharacteristics mFrontCameraCharacteristics; 49 instance()50 public static Optional<LegacyOneCameraManagerImpl> instance() { 51 if (INSTANCE != null) { 52 return INSTANCE; 53 } 54 55 int numberOfCameras; 56 Camera.CameraInfo[] cameraInfos; 57 try { 58 numberOfCameras = Camera.getNumberOfCameras(); 59 cameraInfos = new Camera.CameraInfo[numberOfCameras]; 60 for (int i = 0; i < numberOfCameras; i++) { 61 cameraInfos[i] = new Camera.CameraInfo(); 62 Camera.getCameraInfo(i, cameraInfos[i]); 63 } 64 } catch (RuntimeException ex) { 65 Log.e(TAG, "Exception while creating CameraDeviceInfo", ex); 66 return Optional.absent(); 67 } 68 69 int firstFront = NO_DEVICE; 70 int firstBack = NO_DEVICE; 71 // Get the first (smallest) back and first front camera id. 72 for (int i = numberOfCameras - 1; i >= 0; i--) { 73 if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 74 firstBack = i; 75 } else { 76 if (cameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 77 firstFront = i; 78 } 79 } 80 } 81 82 CameraId frontCameraId = firstFront >= 0 ? CameraId.fromLegacyId(firstFront) : null; 83 CameraId backCameraId = firstBack >= 0 ? CameraId.fromLegacyId(firstBack) : null; 84 85 LegacyOneCameraManagerImpl cameraManager = 86 new LegacyOneCameraManagerImpl(backCameraId, frontCameraId, cameraInfos); 87 INSTANCE = Optional.of(cameraManager); 88 return INSTANCE; 89 } 90 91 /** 92 * Instantiates a new {@link com.android.camera.one.OneCameraManager} for Camera1 API. 93 */ LegacyOneCameraManagerImpl( CameraId firstBackCameraId, CameraId firstFrontCameraId, Camera.CameraInfo[] info)94 public LegacyOneCameraManagerImpl( 95 CameraId firstBackCameraId, 96 CameraId firstFrontCameraId, 97 Camera.CameraInfo[] info) { 98 mFirstBackCameraId = firstBackCameraId; 99 mFirstFrontCameraId = firstFrontCameraId; 100 101 mCameraInfos = info; 102 } 103 104 @Override hasCamera()105 public boolean hasCamera() { 106 return false; 107 } 108 109 @Override hasCameraFacing(@onnull Facing facing)110 public boolean hasCameraFacing(@Nonnull Facing facing) { 111 return findFirstCameraFacing(facing) != null; 112 } 113 114 @Override findFirstCamera()115 public CameraId findFirstCamera() { 116 return mFirstBackCameraId; 117 } 118 119 @Override findFirstCameraFacing(@onnull Facing facing)120 public CameraId findFirstCameraFacing(@Nonnull Facing facing) { 121 if (facing == Facing.BACK && mFirstBackCameraId != null) { 122 return mFirstBackCameraId; 123 } else if (facing == Facing.FRONT && mFirstFrontCameraId != null) { 124 return mFirstFrontCameraId; 125 } 126 return null; 127 } 128 129 @Override getOneCameraCharacteristics(@onnull CameraId cameraId)130 public OneCameraCharacteristics getOneCameraCharacteristics(@Nonnull CameraId cameraId) 131 throws OneCameraAccessException { 132 // Returns the cached object if there exists one. 133 if (cameraId.equals(mFirstBackCameraId)) { 134 if (mBackCameraCharacteristics == null) { 135 Log.w(TAG, "WARNING: Computing potentially long running device access!" 136 + cameraId); 137 mBackCameraCharacteristics = computeCameraCharacteristics(cameraId); 138 } 139 140 Log.w(TAG, "Returning camera characteristics for back camera." 141 + cameraId); 142 143 return mBackCameraCharacteristics; 144 } else if (cameraId.equals(mFirstFrontCameraId)) { 145 if (mFrontCameraCharacteristics == null) { 146 Log.w(TAG, "WARNING: Computing potentially long running device access!" 147 + cameraId); 148 mFrontCameraCharacteristics = computeCameraCharacteristics(cameraId); 149 } 150 151 Log.w(TAG, "Returning camera characteristics for front camera." 152 + cameraId); 153 return mFrontCameraCharacteristics; 154 } 155 156 Log.e(TAG, "BackCamera: " + mFirstBackCameraId + ", " + " ==? " + (mFirstBackCameraId 157 == cameraId)); 158 Log.e(TAG, "FrontCamera: " + mFirstFrontCameraId); 159 Log.e(TAG, "No matching camera id for: " + cameraId); 160 return null; 161 } 162 computeCameraCharacteristics(CameraId key)163 public OneCameraCharacteristics computeCameraCharacteristics(CameraId key) 164 throws OneCameraAccessException { 165 OneCameraCharacteristics characteristics; 166 Camera camera = null; 167 try { 168 camera = Camera.open(key.getLegacyValue()); 169 Camera.Parameters cameraParameters = camera.getParameters(); 170 if (cameraParameters == null) { 171 Log.e(TAG, "Camera object returned null parameters!"); 172 throw new OneCameraAccessException("API1 Camera.getParameters() returned null"); 173 } 174 characteristics = new OneCameraCharacteristicsImpl( 175 mCameraInfos[key.getLegacyValue()], cameraParameters); 176 } finally { 177 if (camera != null) { 178 camera.release(); 179 } 180 } 181 182 return characteristics; 183 } 184 }