OSDN Git Service

am ee189bcb: am 3755aefa: Merge "Eliminate unnecessary context in FragmentActivity...
[android-x86/packages-apps-Camera2.git] / src / com / android / camera / one / v2 / OneCameraManagerImpl.java
1 /*
2  * Copyright (C) 2014 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.v2;
18
19 import android.content.Context;
20 import android.hardware.camera2.CameraAccessException;
21 import android.hardware.camera2.CameraCharacteristics;
22 import android.hardware.camera2.CameraDevice;
23 import android.hardware.camera2.CameraManager;
24 import android.os.Handler;
25 import android.util.DisplayMetrics;
26
27 import com.android.camera.SoundPlayer;
28 import com.android.camera.debug.Log;
29 import com.android.camera.debug.Log.Tag;
30 import com.android.camera.one.OneCamera;
31 import com.android.camera.one.OneCamera.Facing;
32 import com.android.camera.one.OneCamera.OpenCallback;
33 import com.android.camera.one.OneCameraManager;
34 import com.android.camera.util.Size;
35
36 /**
37  * The {@link OneCameraManager} implementation on top of Camera2 API.
38  */
39 public class OneCameraManagerImpl extends OneCameraManager {
40     private static final Tag TAG = new Tag("OneCameraMgrImpl2");
41
42     private final Context mContext;
43     private final CameraManager mCameraManager;
44     private final int mMaxMemoryMB;
45     private final DisplayMetrics mDisplayMetrics;
46     private final SoundPlayer mSoundPlayer;
47
48     /**
49      * Instantiates a new {@link OneCameraManager} for Camera2 API.
50      *
51      * @param cameraManager the underlying Camera2 camera manager.
52      * @param maxMemoryMB maximum amount of memory opened cameras should consume
53      *            during capture and processing, in megabytes.
54      */
55     public OneCameraManagerImpl(Context context, CameraManager cameraManager, int maxMemoryMB,
56             DisplayMetrics displayMetrics, SoundPlayer soundPlayer) {
57         mContext = context;
58         mCameraManager = cameraManager;
59         mMaxMemoryMB = maxMemoryMB;
60         mDisplayMetrics = displayMetrics;
61         mSoundPlayer = soundPlayer;
62     }
63
64     @Override
65     public void open(Facing facing, final boolean useHdr, final Size pictureSize,
66             final OpenCallback openCallback, Handler handler) {
67         try {
68             final String cameraId = getCameraId(facing);
69             Log.i(TAG, "Opening Camera ID " + cameraId);
70             mCameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
71                 // We may get multiple calls to StateCallback, but only the
72                 // first callback indicates the status of the camera-opening
73                 // operation.  For example, we may receive onOpened() and later
74                 // onClosed(), but only the first should be relayed to
75                 // openCallback.
76                 private boolean isFirstCallback = true;
77
78                 @Override
79                 public void onDisconnected(CameraDevice device) {
80                     if (isFirstCallback) {
81                         isFirstCallback = false;
82                         // If the camera is disconnected before it is opened
83                         // then we must call close.
84                         device.close();
85                         openCallback.onCameraClosed();
86                     }
87                 }
88
89                 @Override
90                 public void onClosed(CameraDevice device) {
91                     if (isFirstCallback) {
92                         isFirstCallback = false;
93                         openCallback.onCameraClosed();
94                     }
95                 }
96
97                 @Override
98                 public void onError(CameraDevice device, int error) {
99                     if (isFirstCallback) {
100                         isFirstCallback = false;
101                         device.close();
102                         openCallback.onFailure();
103                     }
104                 }
105
106                 @Override
107                 public void onOpened(CameraDevice device) {
108                     if (isFirstCallback) {
109                         isFirstCallback = false;
110                         try {
111                             CameraCharacteristics characteristics = mCameraManager
112                                     .getCameraCharacteristics(device.getId());
113                             // TODO: Set boolean based on whether HDR+ is enabled.
114                             OneCamera oneCamera = OneCameraCreator.create(mContext, useHdr, device,
115                                     characteristics, pictureSize, mMaxMemoryMB, mDisplayMetrics,
116                                     mSoundPlayer);
117                             openCallback.onCameraOpened(oneCamera);
118                         } catch (CameraAccessException e) {
119                             Log.d(TAG, "Could not get camera characteristics");
120                             openCallback.onFailure();
121                         }
122                     }
123                 }
124             }, handler);
125         } catch (CameraAccessException ex) {
126             Log.e(TAG, "Could not open camera. " + ex.getMessage());
127             handler.post(new Runnable() {
128                 @Override
129                 public void run() {
130                     openCallback.onFailure();
131                 }
132             });
133         } catch (UnsupportedOperationException ex) {
134             Log.e(TAG, "Could not open camera. " + ex.getMessage());
135             handler.post(new Runnable() {
136                 @Override
137                 public void run() {
138                     openCallback.onFailure();
139                 }
140             });
141         }
142     }
143
144     @Override
145     public boolean hasCameraFacing(Facing facing) {
146         return getFirstCameraFacing(facing == Facing.FRONT ? CameraCharacteristics.LENS_FACING_FRONT
147                 : CameraCharacteristics.LENS_FACING_BACK) != null;
148     }
149
150     /** Returns the ID of the first camera facing the given direction. */
151     private String getCameraId(Facing facing) {
152         if (facing == Facing.FRONT) {
153             return getFirstFrontCameraId();
154         } else {
155             return getFirstBackCameraId();
156         }
157     }
158
159     /** Returns the ID of the first back-facing camera. */
160     public String getFirstBackCameraId() {
161         Log.d(TAG, "Getting First BACK Camera");
162         String cameraId = getFirstCameraFacing(CameraCharacteristics.LENS_FACING_BACK);
163         if (cameraId == null) {
164             throw new RuntimeException("No back-facing camera found.");
165         }
166         return cameraId;
167     }
168
169     /** Returns the ID of the first front-facing camera. */
170     public String getFirstFrontCameraId() {
171         Log.d(TAG, "Getting First FRONT Camera");
172         String cameraId = getFirstCameraFacing(CameraCharacteristics.LENS_FACING_FRONT);
173         if (cameraId == null) {
174             throw new RuntimeException("No front-facing camera found.");
175         }
176         return cameraId;
177     }
178
179     /** Returns the ID of the first camera facing the given direction. */
180     private String getFirstCameraFacing(int facing) {
181         try {
182             String[] cameraIds = mCameraManager.getCameraIdList();
183             for (String cameraId : cameraIds) {
184                 CameraCharacteristics characteristics = mCameraManager
185                         .getCameraCharacteristics(cameraId);
186                 if (characteristics.get(CameraCharacteristics.LENS_FACING) == facing) {
187                     return cameraId;
188                 }
189             }
190             return null;
191         } catch (CameraAccessException ex) {
192             throw new RuntimeException("Unable to get camera ID", ex);
193         }
194     }
195 }