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