blob: 472378f1794b0ddeff045f7894a477315e1522a9 [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.initialization;
import android.content.Context;
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}.
* <p>
* Note: This implementation assumes that these four methods are invoked in
* sequences matching the following regex:
* <p>
* startPreview (takePicture | triggerFocusAndMeterAtPoint)* close
* <p>
* 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<Integer> mAFStateListenable;
private final Listenable<FocusState> mFocusStateListenable;
private final Listenable<Boolean> mReadyStateListenable;
private final float mMaxZoom;
private final Updatable<Float> 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<Integer> afStateProvider, Listenable<FocusState> focusStateProvider,
Listenable<Boolean> readyStateListenable, float maxZoom, Updatable<Float> 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<Integer>() {
@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<FocusState>() {
@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<Boolean> readyStateCallback = new Callback<Boolean>() {
@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<Void> result = mPreviewStarter.startPreview(surface);
Futures.addCallback(result, new FutureCallback<Void>() {
@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, Context context) {
return mPreviewSizeSelector.pickPreviewSize(pictureSize);
}
}