/* * 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.initialization; import android.app.Activity; import android.view.Surface; import com.android.camera.async.FilteredCallback; import com.android.camera.async.Listenable; import com.android.camera.async.SafeCloseable; import com.android.camera.async.Updatable; import com.android.camera.one.OneCamera; import com.android.camera.one.PreviewSizeSelector; import com.android.camera.one.v2.AutoFocusHelper; import com.android.camera.one.v2.autofocus.ManualAutoFocus; import com.android.camera.one.v2.photo.PictureTaker; import com.android.camera.session.CaptureSession; import com.android.camera.ui.motion.LinearScale; import com.android.camera.util.Callback; import com.android.camera.util.Size; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import java.util.concurrent.Executor; import javax.annotation.Nonnull; /** * A generic, composable {@link OneCamera}. *

* Note: This implementation assumes that these four methods are invoked in * sequences matching the following regex: *

* startPreview (takePicture | triggerFocusAndMeterAtPoint)* close *

* All other methods may be called at any time. */ class GenericOneCameraImpl implements OneCamera { private final SafeCloseable mCloseListener; private final PictureTaker mPictureTaker; private final ManualAutoFocus mManualAutoFocus; private final LinearScale mLensRange; private final Executor mMainExecutor; private final Listenable mAFStateListenable; private final Listenable mFocusStateListenable; private final Listenable mReadyStateListenable; private final float mMaxZoom; private final Updatable mZoom; private final Facing mDirection; private final PreviewSizeSelector mPreviewSizeSelector; private final PreviewStarter mPreviewStarter; public GenericOneCameraImpl(SafeCloseable closeListener, PictureTaker pictureTaker, ManualAutoFocus manualAutoFocus, LinearScale lensRange, Executor mainExecutor, Listenable afStateProvider, Listenable focusStateProvider, Listenable readyStateListenable, float maxZoom, Updatable zoom, Facing direction, PreviewSizeSelector previewSizeSelector, PreviewStarter previewStarter) { mCloseListener = closeListener; mMainExecutor = mainExecutor; mMaxZoom = maxZoom; mDirection = direction; mPreviewSizeSelector = previewSizeSelector; mPictureTaker = pictureTaker; mManualAutoFocus = manualAutoFocus; mLensRange = lensRange; mAFStateListenable = afStateProvider; mFocusStateListenable = focusStateProvider; mReadyStateListenable = readyStateListenable; mZoom = zoom; mPreviewStarter = previewStarter; } @Override public void triggerFocusAndMeterAtPoint(float nx, float ny) { mManualAutoFocus.triggerFocusAndMeterAtPoint(nx, ny); } @Override public void takePicture(PhotoCaptureParameters params, CaptureSession session) { mPictureTaker.takePicture(params, session); } @Override public void setFocusStateListener(final FocusStateListener listener) { mAFStateListenable.setCallback(new Callback() { @Override public void onCallback(@Nonnull Integer afState) { // TODO delete frameNumber from FocusStateListener callback. It // is optional and never actually used. long frameNumber = -1; if(listener !=null) { listener.onFocusStatusUpdate(AutoFocusHelper.stateFromCamera2State(afState), frameNumber); } } }); } @Override public void setFocusDistanceListener(final FocusDistanceListener listener) { if (listener == null) { mFocusStateListenable.clear(); return; } mFocusStateListenable.setCallback(new Callback() { @Override public void onCallback(@Nonnull FocusState focusState) { if (focusState.isActive) { listener.onFocusDistance(focusState.lensDistance, mLensRange); } } }); } @Override public void setReadyStateChangedListener(final ReadyStateChangedListener listener) { if (listener == null) { mReadyStateListenable.clear(); return; } Callback readyStateCallback = new Callback() { @Override public void onCallback(@Nonnull Boolean result) { listener.onReadyStateChanged(result); } }; mReadyStateListenable.setCallback(new FilteredCallback<>(readyStateCallback)); } @Override public void startPreview(Surface surface, final CaptureReadyCallback listener) { ListenableFuture result = mPreviewStarter.startPreview(surface); Futures.addCallback(result, new FutureCallback() { @Override public void onSuccess(@Nonnull Void aVoid) { listener.onReadyForCapture(); } @Override public void onFailure(@Nonnull Throwable throwable) { listener.onSetupFailed(); } }, MoreExecutors.directExecutor()); } @Override public void close() { mCloseListener.close(); } @Override public Facing getDirection() { return mDirection; } @Override public float getMaxZoom() { return mMaxZoom; } @Override public void setZoom(float zoom) { mZoom.update(zoom); } @Override public Size pickPreviewSize(Size pictureSize, Activity context) { return mPreviewSizeSelector.pickPreviewSize(pictureSize); } }