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.common;
18 
19 import android.annotation.TargetApi;
20 import android.graphics.Rect;
21 import android.hardware.camera2.CaptureRequest;
22 import android.hardware.camera2.params.MeteringRectangle;
23 import android.os.Build.VERSION_CODES;
24 
25 import com.android.camera.async.Lifetime;
26 import com.android.camera.async.Observable;
27 import com.android.camera.async.SafeCloseable;
28 import com.android.camera.one.OneCamera;
29 import com.android.camera.one.OneCameraCharacteristics;
30 import com.android.camera.one.OneCameraCharacteristics.FaceDetectMode;
31 import com.android.camera.one.Settings3A;
32 import com.android.camera.one.v2.autofocus.ManualAutoFocus;
33 import com.android.camera.one.v2.autofocus.ManualAutoFocusFactory;
34 import com.android.camera.one.v2.commands.CameraCommand;
35 import com.android.camera.one.v2.commands.CameraCommandExecutor;
36 import com.android.camera.one.v2.commands.ResettingRunnableCameraCommand;
37 import com.android.camera.one.v2.commands.PreviewCommandFactory;
38 import com.android.camera.one.v2.core.FrameServer;
39 import com.android.camera.one.v2.core.RequestBuilder;
40 import com.android.camera.one.v2.core.RequestTemplate;
41 import com.android.camera.one.v2.face.FaceDetect;
42 import com.google.common.base.Supplier;
43 import com.google.common.base.Suppliers;
44 import com.google.common.util.concurrent.MoreExecutors;
45 
46 import java.util.concurrent.Executors;
47 
48 /**
49  * Wires together functionality common to all cameras:
50  * <ul>
51  * <li>Tap-to-focus</li>
52  * <li>Auto exposure, based on the current flash-setting</li>
53  * <li>Metering regions</li>
54  * <li>Zoom</li>
55  * <li>TODO Logging of OS/driver-level errors</li>
56  * </ul>
57  * <p>
58  * Note that this does not include functionality for taking pictures, since this
59  * varies depending on hardware capability.
60  * </p>
61  */
62 @TargetApi(VERSION_CODES.LOLLIPOP)
63 public class BasicCameraFactory {
64     private final ManualAutoFocus mManualAutoFocus;
65     private final RequestBuilder.Factory mMeteredZoomedRequestBuilder;
66     private final Runnable mPreviewUpdater;
67 
68     /**
69      * @param lifetime The lifetime of all created objects and their associated
70      *            resources.
71      * @param cameraCharacteristics
72      * @param rootTemplate Provides preconfigured request builders to be used for
73      *            all requests to mFrameServer.
74      * @param cameraCommandExecutor The
75      * @param templateType The template (e.g. CameraDevice.TEMPLATE_PREVIEW) to
76      *            use for repeating requests.
77      */
BasicCameraFactory(Lifetime lifetime, OneCameraCharacteristics cameraCharacteristics, FrameServer frameServer, RequestBuilder.Factory rootTemplate, CameraCommandExecutor cameraCommandExecutor, PreviewCommandFactory previewCommandFactory, Observable<OneCamera.PhotoCaptureParameters.Flash> flash, Observable<Integer> exposure, Observable<Float> zoom, Observable<Boolean> hdrSceneSetting, int templateType)78     public BasicCameraFactory(Lifetime lifetime,
79             OneCameraCharacteristics cameraCharacteristics,
80             FrameServer frameServer,
81             RequestBuilder.Factory rootTemplate,
82             CameraCommandExecutor cameraCommandExecutor,
83             PreviewCommandFactory previewCommandFactory,
84             Observable<OneCamera.PhotoCaptureParameters.Flash> flash,
85             Observable<Integer> exposure,
86             Observable<Float> zoom,
87             Observable<Boolean> hdrSceneSetting,
88             int templateType) {
89         RequestTemplate requestTemplate = new RequestTemplate(rootTemplate);
90         requestTemplate.setParam(
91               CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
92         requestTemplate.setParam(
93               CaptureRequest.CONTROL_AE_MODE, new FlashBasedAEMode(flash, hdrSceneSetting));
94         requestTemplate.setParam(
95               CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposure);
96 
97         Supplier<FaceDetectMode> faceDetectMode = Suppliers.ofInstance(
98               FaceDetect.getHighestFaceDetectMode(cameraCharacteristics));
99 
100         requestTemplate.setParam(CaptureRequest.CONTROL_MODE,
101               new ControlModeSelector(hdrSceneSetting,
102                     faceDetectMode,
103                     cameraCharacteristics.getSupportedHardwareLevel()));
104         requestTemplate.setParam(
105               CaptureRequest.CONTROL_SCENE_MODE, new ControlSceneModeSelector(
106                     hdrSceneSetting,
107                     faceDetectMode,
108                     cameraCharacteristics.getSupportedHardwareLevel()));
109         requestTemplate.setParam(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
110               new StatisticsFaceDetectMode(faceDetectMode));
111 
112         Supplier<Rect> cropRegion = new ZoomedCropRegion(
113                 cameraCharacteristics.getSensorInfoActiveArraySize(), zoom);
114         requestTemplate.setParam(CaptureRequest.SCALER_CROP_REGION, cropRegion);
115 
116         CameraCommand previewUpdaterCommand =
117               previewCommandFactory.get(requestTemplate, templateType);
118 
119         // Use a resetting command to ensure that many rapid settings changes do
120         // not result in many rapid (>30fps) requests to restart the preview.
121         mPreviewUpdater = new ResettingRunnableCameraCommand(cameraCommandExecutor,
122               previewUpdaterCommand);
123 
124         // Resend the repeating preview request when the zoom or flash state
125         // changes to apply the new setting.
126         // Also, de-register these callbacks when the camera is closed (to
127         // not leak memory).
128         SafeCloseable zoomCallback = zoom.addCallback(mPreviewUpdater, MoreExecutors
129                 .sameThreadExecutor());
130         lifetime.add(zoomCallback);
131         SafeCloseable flashCallback = flash.addCallback(mPreviewUpdater, MoreExecutors
132                 .sameThreadExecutor());
133         lifetime.add(flashCallback);
134         SafeCloseable exposureCallback = exposure.addCallback(mPreviewUpdater, MoreExecutors
135                 .sameThreadExecutor());
136         lifetime.add(exposureCallback);
137         SafeCloseable hdrCallback = hdrSceneSetting.addCallback(mPreviewUpdater, MoreExecutors
138                 .sameThreadExecutor());
139         lifetime.add(hdrCallback);
140 
141         int sensorOrientation = cameraCharacteristics.getSensorOrientation();
142 
143         ManualAutoFocusFactory manualAutoFocusFactory = ManualAutoFocusFactory.create(new
144                 Lifetime(lifetime), frameServer, cameraCommandExecutor, cropRegion,
145                 sensorOrientation, mPreviewUpdater, requestTemplate,
146                 templateType, new Settings3A(), Executors.newScheduledThreadPool(1),
147                 3 /* afHoldSeconds */);
148         mManualAutoFocus = manualAutoFocusFactory.provideManualAutoFocus();
149         Supplier<MeteringRectangle[]> aeRegions =
150                 manualAutoFocusFactory.provideAEMeteringRegion();
151         Supplier<MeteringRectangle[]> afRegions =
152                 manualAutoFocusFactory.provideAFMeteringRegion();
153 
154         requestTemplate.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
155         requestTemplate.setParam(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
156 
157         mMeteredZoomedRequestBuilder = requestTemplate;
158     }
159 
provideMeteredZoomedRequestBuilder()160     public RequestBuilder.Factory provideMeteredZoomedRequestBuilder() {
161         return mMeteredZoomedRequestBuilder;
162     }
163 
provideManualAutoFocus()164     public ManualAutoFocus provideManualAutoFocus() {
165         return mManualAutoFocus;
166     }
167 
providePreviewUpdater()168     public Runnable providePreviewUpdater() {
169         return mPreviewUpdater;
170     }
171 }
172