blob: 44883eadea6b36513596e8eb92fecf25eb6c2f69 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.camera.one.v2.common;
import android.annotation.TargetApi;
import android.graphics.Rect;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.MeteringRectangle;
import android.os.Build.VERSION_CODES;
import com.android.camera.async.Lifetime;
import com.android.camera.async.Observable;
import com.android.camera.async.SafeCloseable;
import com.android.camera.one.OneCamera;
import com.android.camera.one.OneCameraCharacteristics;
import com.android.camera.one.OneCameraCharacteristics.FaceDetectMode;
import com.android.camera.one.Settings3A;
import com.android.camera.one.v2.autofocus.ManualAutoFocus;
import com.android.camera.one.v2.autofocus.ManualAutoFocusFactory;
import com.android.camera.one.v2.commands.CameraCommand;
import com.android.camera.one.v2.commands.CameraCommandExecutor;
import com.android.camera.one.v2.commands.ResettingRunnableCameraCommand;
import com.android.camera.one.v2.commands.PreviewCommandFactory;
import com.android.camera.one.v2.core.FrameServer;
import com.android.camera.one.v2.core.RequestBuilder;
import com.android.camera.one.v2.core.RequestTemplate;
import com.android.camera.one.v2.face.FaceDetect;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.Executors;
/**
* Wires together functionality common to all cameras:
* <ul>
* <li>Tap-to-focus</li>
* <li>Auto exposure, based on the current flash-setting</li>
* <li>Metering regions</li>
* <li>Zoom</li>
* <li>TODO Logging of OS/driver-level errors</li>
* </ul>
* <p>
* Note that this does not include functionality for taking pictures, since this
* varies depending on hardware capability.
* </p>
*/
@TargetApi(VERSION_CODES.LOLLIPOP)
public class BasicCameraFactory {
private final ManualAutoFocus mManualAutoFocus;
private final RequestBuilder.Factory mMeteredZoomedRequestBuilder;
private final Runnable mPreviewUpdater;
/**
* @param lifetime The lifetime of all created objects and their associated
* resources.
* @param cameraCharacteristics
* @param rootTemplate Provides preconfigured request builders to be used for
* all requests to mFrameServer.
* @param cameraCommandExecutor The
* @param templateType The template (e.g. CameraDevice.TEMPLATE_PREVIEW) to
* use for repeating requests.
*/
public 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) {
RequestTemplate requestTemplate = new RequestTemplate(rootTemplate);
if (cameraCharacteristics.isContinuousPictureAutoFocusSupported()) {
requestTemplate.setParam(
CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
}
requestTemplate.setParam(
CaptureRequest.CONTROL_AE_MODE, new FlashBasedAEMode(flash, hdrSceneSetting));
requestTemplate.setParam(
CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposure);
Supplier<FaceDetectMode> faceDetectMode = Suppliers.ofInstance(
FaceDetect.getHighestFaceDetectMode(cameraCharacteristics));
requestTemplate.setParam(CaptureRequest.CONTROL_MODE,
new ControlModeSelector(hdrSceneSetting,
faceDetectMode,
cameraCharacteristics.getSupportedHardwareLevel()));
requestTemplate.setParam(
CaptureRequest.CONTROL_SCENE_MODE, new ControlSceneModeSelector(
hdrSceneSetting,
faceDetectMode,
cameraCharacteristics.getSupportedHardwareLevel()));
requestTemplate.setParam(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
new StatisticsFaceDetectMode(faceDetectMode));
Supplier<Rect> cropRegion = new ZoomedCropRegion(
cameraCharacteristics.getSensorInfoActiveArraySize(), zoom);
requestTemplate.setParam(CaptureRequest.SCALER_CROP_REGION, cropRegion);
CameraCommand previewUpdaterCommand =
previewCommandFactory.get(requestTemplate, templateType);
// Use a resetting command to ensure that many rapid settings changes do
// not result in many rapid (>30fps) requests to restart the preview.
mPreviewUpdater = new ResettingRunnableCameraCommand(cameraCommandExecutor,
previewUpdaterCommand);
// Resend the repeating preview request when the zoom or flash state
// changes to apply the new setting.
// Also, de-register these callbacks when the camera is closed (to
// not leak memory).
SafeCloseable zoomCallback = zoom.addCallback(mPreviewUpdater, MoreExecutors
.directExecutor());
lifetime.add(zoomCallback);
SafeCloseable flashCallback = flash.addCallback(mPreviewUpdater, MoreExecutors
.directExecutor());
lifetime.add(flashCallback);
SafeCloseable exposureCallback = exposure.addCallback(mPreviewUpdater, MoreExecutors
.directExecutor());
lifetime.add(exposureCallback);
SafeCloseable hdrCallback = hdrSceneSetting.addCallback(mPreviewUpdater, MoreExecutors
.directExecutor());
lifetime.add(hdrCallback);
int sensorOrientation = cameraCharacteristics.getSensorOrientation();
ManualAutoFocusFactory manualAutoFocusFactory = ManualAutoFocusFactory.create(new
Lifetime(lifetime), frameServer, cameraCommandExecutor, cropRegion,
sensorOrientation, mPreviewUpdater, requestTemplate,
templateType, new Settings3A(), Executors.newScheduledThreadPool(1),
3 /* afHoldSeconds */);
mManualAutoFocus = manualAutoFocusFactory.provideManualAutoFocus();
Supplier<MeteringRectangle[]> aeRegions =
manualAutoFocusFactory.provideAEMeteringRegion();
Supplier<MeteringRectangle[]> afRegions =
manualAutoFocusFactory.provideAFMeteringRegion();
requestTemplate.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
requestTemplate.setParam(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
mMeteredZoomedRequestBuilder = requestTemplate;
}
public RequestBuilder.Factory provideMeteredZoomedRequestBuilder() {
return mMeteredZoomedRequestBuilder;
}
public ManualAutoFocus provideManualAutoFocus() {
return mManualAutoFocus;
}
public Runnable providePreviewUpdater() {
return mPreviewUpdater;
}
}