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         if (cameraCharacteristics.isContinuousPictureAutoFocusSupported()) {
91             requestTemplate.setParam(
92                     CaptureRequest.CONTROL_AF_MODE,
93                     CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
94         }
95 
96         requestTemplate.setParam(
97               CaptureRequest.CONTROL_AE_MODE, new FlashBasedAEMode(flash, hdrSceneSetting));
98         requestTemplate.setParam(
99               CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposure);
100 
101         Supplier<FaceDetectMode> faceDetectMode = Suppliers.ofInstance(
102               FaceDetect.getHighestFaceDetectMode(cameraCharacteristics));
103 
104         requestTemplate.setParam(CaptureRequest.CONTROL_MODE,
105               new ControlModeSelector(hdrSceneSetting,
106                     faceDetectMode,
107                     cameraCharacteristics.getSupportedHardwareLevel()));
108         requestTemplate.setParam(
109               CaptureRequest.CONTROL_SCENE_MODE, new ControlSceneModeSelector(
110                     hdrSceneSetting,
111                     faceDetectMode,
112                     cameraCharacteristics.getSupportedHardwareLevel()));
113         requestTemplate.setParam(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
114               new StatisticsFaceDetectMode(faceDetectMode));
115 
116         Supplier<Rect> cropRegion = new ZoomedCropRegion(
117                 cameraCharacteristics.getSensorInfoActiveArraySize(), zoom);
118         requestTemplate.setParam(CaptureRequest.SCALER_CROP_REGION, cropRegion);
119 
120         CameraCommand previewUpdaterCommand =
121               previewCommandFactory.get(requestTemplate, templateType);
122 
123         // Use a resetting command to ensure that many rapid settings changes do
124         // not result in many rapid (>30fps) requests to restart the preview.
125         mPreviewUpdater = new ResettingRunnableCameraCommand(cameraCommandExecutor,
126               previewUpdaterCommand);
127 
128         // Resend the repeating preview request when the zoom or flash state
129         // changes to apply the new setting.
130         // Also, de-register these callbacks when the camera is closed (to
131         // not leak memory).
132         SafeCloseable zoomCallback = zoom.addCallback(mPreviewUpdater, MoreExecutors
133                 .directExecutor());
134         lifetime.add(zoomCallback);
135         SafeCloseable flashCallback = flash.addCallback(mPreviewUpdater, MoreExecutors
136                 .directExecutor());
137         lifetime.add(flashCallback);
138         SafeCloseable exposureCallback = exposure.addCallback(mPreviewUpdater, MoreExecutors
139                 .directExecutor());
140         lifetime.add(exposureCallback);
141         SafeCloseable hdrCallback = hdrSceneSetting.addCallback(mPreviewUpdater, MoreExecutors
142                 .directExecutor());
143         lifetime.add(hdrCallback);
144 
145         int sensorOrientation = cameraCharacteristics.getSensorOrientation();
146 
147         ManualAutoFocusFactory manualAutoFocusFactory = ManualAutoFocusFactory.create(new
148                 Lifetime(lifetime), frameServer, cameraCommandExecutor, cropRegion,
149                 sensorOrientation, mPreviewUpdater, requestTemplate,
150                 templateType, new Settings3A(), Executors.newScheduledThreadPool(1),
151                 3 /* afHoldSeconds */);
152         mManualAutoFocus = manualAutoFocusFactory.provideManualAutoFocus();
153         Supplier<MeteringRectangle[]> aeRegions =
154                 manualAutoFocusFactory.provideAEMeteringRegion();
155         Supplier<MeteringRectangle[]> afRegions =
156                 manualAutoFocusFactory.provideAFMeteringRegion();
157 
158         requestTemplate.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
159         requestTemplate.setParam(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
160 
161         mMeteredZoomedRequestBuilder = requestTemplate;
162     }
163 
provideMeteredZoomedRequestBuilder()164     public RequestBuilder.Factory provideMeteredZoomedRequestBuilder() {
165         return mMeteredZoomedRequestBuilder;
166     }
167 
provideManualAutoFocus()168     public ManualAutoFocus provideManualAutoFocus() {
169         return mManualAutoFocus;
170     }
171 
providePreviewUpdater()172     public Runnable providePreviewUpdater() {
173         return mPreviewUpdater;
174     }
175 }
176