Merge "Interface ImageTaskManager for Image-based Tasks" into ub-camera-haleakala
diff --git a/src/com/android/camera/async/HandlerFactory.java b/src/com/android/camera/async/HandlerFactory.java
new file mode 100644
index 0000000..79be101
--- /dev/null
+++ b/src/com/android/camera/async/HandlerFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.async;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+/**
+ * Creates new handlers backed by threads with a specified lifetime.
+ */
+public class HandlerFactory {
+ /**
+ * @param lifetime The lifetime of the associated handler's thread.
+ * @param threadName The name to assign to the created thread.
+ * @return A handler backed by a new thread.
+ */
+ public Handler create(Lifetime lifetime, String threadName) {
+ final HandlerThread thread = new HandlerThread(threadName);
+ thread.start();
+
+ lifetime.add(new SafeCloseable() {
+ @Override
+ public void close() {
+ thread.quitSafely();
+ }
+ });
+
+ return new Handler(thread.getLooper());
+ }
+}
diff --git a/src/com/android/camera/async/MainThreadExecutor.java b/src/com/android/camera/async/MainThreadExecutor.java
new file mode 100644
index 0000000..51c3899
--- /dev/null
+++ b/src/com/android/camera/async/MainThreadExecutor.java
@@ -0,0 +1,30 @@
+/*
+ * 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.async;
+
+import android.os.Handler;
+import android.os.Looper;
+
+public class MainThreadExecutor extends HandlerExecutor {
+ public MainThreadExecutor(Handler handler) {
+ super(handler);
+ }
+
+ public static MainThreadExecutor create() {
+ return new MainThreadExecutor(new Handler(Looper.getMainLooper()));
+ }
+}
diff --git a/src/com/android/camera/async/Observable.java b/src/com/android/camera/async/Observable.java
index 496c8ef..e9b3df0 100644
--- a/src/com/android/camera/async/Observable.java
+++ b/src/com/android/camera/async/Observable.java
@@ -17,7 +17,6 @@
package com.android.camera.async;
import com.android.camera.util.Callback;
-import com.google.common.base.Optional;
import com.google.common.base.Supplier;
import java.util.concurrent.Executor;
@@ -35,5 +34,5 @@
* @return A {@link SafeCloseable} handle to be closed when the callback
* must be removed.
*/
- public SafeCloseable addCallback(Callback callback, Executor executor);
+ public SafeCloseable addCallback(Callback<T> callback, Executor executor);
}
diff --git a/src/com/android/camera/one/OneCamera.java b/src/com/android/camera/one/OneCamera.java
index e8e3b84..c24c3e7 100644
--- a/src/com/android/camera/one/OneCamera.java
+++ b/src/com/android/camera/one/OneCamera.java
@@ -399,17 +399,6 @@
public void close();
/**
- * @return A list of all supported preview resolutions.
- */
- public Size[] getSupportedPreviewSizes();
-
- /**
- * @return The aspect ratio of the full size capture (usually the native
- * resolution of the camera).
- */
- public float getFullSizeAspectRatio();
-
- /**
* @return The direction of the camera.
*/
public Facing getDirection();
diff --git a/src/com/android/camera/one/OneCameraCharacteristics.java b/src/com/android/camera/one/OneCameraCharacteristics.java
index 9e806b8..c2b4418 100644
--- a/src/com/android/camera/one/OneCameraCharacteristics.java
+++ b/src/com/android/camera/one/OneCameraCharacteristics.java
@@ -16,6 +16,10 @@
package com.android.camera.one;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+
import com.android.camera.util.Size;
import java.util.List;
@@ -23,16 +27,38 @@
/**
* The properties describing a OneCamera device. These properties are fixed for
* a given OneCamera device.
- *
- * TODO: Complete this interface to expose all camera
- * properties.
*/
public interface OneCameraCharacteristics {
/**
* Gets the supported picture sizes for the given image format.
*
* @param imageFormat The specific image format listed on
- * {@link ImageFormat}.
+ * {@link ImageFormat}.
*/
public List<Size> getSupportedPictureSizes(int imageFormat);
+
+ /**
+ * Gets the supported preview sizes.
+ */
+ public List<Size> getSupportedPreviewSizes();
+
+ /**
+ * @See {@link CameraCharacteristics#SENSOR_ORIENTATION}
+ */
+ public int getSensorOrientation();
+
+ /**
+ * @Return The direction of the camera
+ */
+ public OneCamera.Facing getCameraDirection();
+
+ /**
+ * @See {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}
+ */
+ public Rect getSensorInfoActiveArraySize();
+
+ /**
+ * @See {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM}
+ */
+ public float getAvailableMaxDigitalZoom();
}
diff --git a/src/com/android/camera/one/OneCameraManager.java b/src/com/android/camera/one/OneCameraManager.java
index dde1ca2..4cd6552 100644
--- a/src/com/android/camera/one/OneCameraManager.java
+++ b/src/com/android/camera/one/OneCameraManager.java
@@ -107,7 +107,7 @@
int maxMemoryMB = activity.getServices().getMemoryManager()
.getMaxAllowedNativeMemoryAllocation();
return new com.android.camera.one.v2.OneCameraManagerImpl(
- activity.getApplicationContext(), cameraManager, maxMemoryMB,
+ activity, cameraManager, maxMemoryMB,
displayMetrics, activity.getSoundPlayer());
}
diff --git a/src/com/android/camera/one/v2/OneCameraCharacteristicsImpl.java b/src/com/android/camera/one/v2/OneCameraCharacteristicsImpl.java
index 77278e5..2994717 100644
--- a/src/com/android/camera/one/v2/OneCameraCharacteristicsImpl.java
+++ b/src/com/android/camera/one/v2/OneCameraCharacteristicsImpl.java
@@ -16,9 +16,12 @@
package com.android.camera.one.v2;
-import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.params.StreamConfigurationMap;
+
+import com.android.camera.one.OneCamera;
import com.android.camera.one.OneCameraCharacteristics;
import com.android.camera.util.Size;
@@ -26,8 +29,9 @@
import java.util.List;
/**
- * Describes a OneCamera device which is on top of camera2 API. This is essential a wrapper
- * for #{link android.hardware.camera2.CameraCharacteristics}.
+ * Describes a OneCamera device which is on top of camera2 API. This is
+ * essential a wrapper for #{link
+ * android.hardware.camera2.CameraCharacteristics}.
*/
public class OneCameraCharacteristicsImpl implements OneCameraCharacteristics {
private final CameraCharacteristics mCameraCharacteristics;
@@ -46,4 +50,40 @@
}
return supportedPictureSizes;
}
+
+ @Override
+ public List<Size> getSupportedPreviewSizes() {
+ StreamConfigurationMap configMap =
+ mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ ArrayList<Size> supportedPictureSizes = new ArrayList<>();
+ for (android.util.Size androidSize : configMap.getOutputSizes(SurfaceTexture.class)) {
+ supportedPictureSizes.add(new Size(androidSize));
+ }
+ return supportedPictureSizes;
+ }
+
+ @Override
+ public int getSensorOrientation() {
+ return mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
+ }
+
+ @Override
+ public OneCamera.Facing getCameraDirection() {
+ int direction = mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
+ if (direction == CameraCharacteristics.LENS_FACING_BACK) {
+ return OneCamera.Facing.BACK;
+ } else {
+ return OneCamera.Facing.FRONT;
+ }
+ }
+
+ @Override
+ public Rect getSensorInfoActiveArraySize() {
+ return mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+ }
+
+ @Override
+ public float getAvailableMaxDigitalZoom() {
+ return mCameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
+ }
}
diff --git a/src/com/android/camera/one/v2/OneCameraFactory.java b/src/com/android/camera/one/v2/OneCameraFactory.java
new file mode 100644
index 0000000..aab328d
--- /dev/null
+++ b/src/com/android/camera/one/v2/OneCameraFactory.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import android.os.Handler;
+
+import com.android.camera.async.MainThreadExecutor;
+import com.android.camera.async.Observable;
+import com.android.camera.one.OneCamera;
+import com.android.camera.one.OneCameraCharacteristics;
+import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy;
+import com.android.camera.util.Size;
+
+import java.util.concurrent.Executor;
+
+public interface OneCameraFactory {
+ OneCamera createOneCamera(CameraDeviceProxy cameraDevice,
+ OneCameraCharacteristics characteristics,
+ MainThreadExecutor mainThreadExecutor,
+ Size pictureSize,
+ Observable<OneCamera.PhotoCaptureParameters.Flash> flashSetting);
+}
diff --git a/src/com/android/camera/one/v2/OneCameraImpl.java b/src/com/android/camera/one/v2/OneCameraImpl.java
index 15a5411..26c860a 100644
--- a/src/com/android/camera/one/v2/OneCameraImpl.java
+++ b/src/com/android/camera/one/v2/OneCameraImpl.java
@@ -436,14 +436,12 @@
mDevice.close();
}
- @Override
public Size[] getSupportedPreviewSizes() {
StreamConfigurationMap config = mCharacteristics
.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
return Size.convert(config.getOutputSizes(SurfaceTexture.class));
}
- @Override
public float getFullSizeAspectRatio() {
return mFullSizeAspectRatio;
}
diff --git a/src/com/android/camera/one/v2/OneCameraManagerImpl.java b/src/com/android/camera/one/v2/OneCameraManagerImpl.java
index 584cb4e..704b8fe 100644
--- a/src/com/android/camera/one/v2/OneCameraManagerImpl.java
+++ b/src/com/android/camera/one/v2/OneCameraManagerImpl.java
@@ -25,6 +25,7 @@
import android.util.DisplayMetrics;
import com.android.camera.SoundPlayer;
+import com.android.camera.app.AppController;
import com.android.camera.debug.Log;
import com.android.camera.debug.Log.Tag;
import com.android.camera.one.OneCamera;
@@ -41,7 +42,7 @@
public class OneCameraManagerImpl extends OneCameraManager {
private static final Tag TAG = new Tag("OneCameraMgrImpl2");
- private final Context mContext;
+ private final AppController mAppController;
private final CameraManager mCameraManager;
private final int mMaxMemoryMB;
private final DisplayMetrics mDisplayMetrics;
@@ -54,9 +55,9 @@
* @param maxMemoryMB maximum amount of memory opened cameras should consume
* during capture and processing, in megabytes.
*/
- public OneCameraManagerImpl(Context context, CameraManager cameraManager, int maxMemoryMB,
- DisplayMetrics displayMetrics, SoundPlayer soundPlayer) {
- mContext = context;
+ public OneCameraManagerImpl(AppController appController, CameraManager cameraManager, int
+ maxMemoryMB, DisplayMetrics displayMetrics, SoundPlayer soundPlayer) {
+ mAppController = appController;
mCameraManager = cameraManager;
mMaxMemoryMB = maxMemoryMB;
mDisplayMetrics = displayMetrics;
@@ -113,8 +114,9 @@
CameraCharacteristics characteristics = mCameraManager
.getCameraCharacteristics(device.getId());
// TODO: Set boolean based on whether HDR+ is enabled.
- OneCamera oneCamera = OneCameraCreator.create(mContext, useHdr, device,
- characteristics, pictureSize, mMaxMemoryMB, mDisplayMetrics,
+ OneCamera oneCamera = OneCameraCreator.create(mAppController, useHdr,
+ device, characteristics, pictureSize, mMaxMemoryMB,
+ mDisplayMetrics,
mSoundPlayer);
openCallback.onCameraOpened(oneCamera);
} catch (CameraAccessException e) {
diff --git a/src/com/android/camera/one/v2/OneCameraZslImpl.java b/src/com/android/camera/one/v2/OneCameraZslImpl.java
index 033e832..cfd314f 100644
--- a/src/com/android/camera/one/v2/OneCameraZslImpl.java
+++ b/src/com/android/camera/one/v2/OneCameraZslImpl.java
@@ -597,14 +597,12 @@
mCaptureImageReader.close();
}
- @Override
public Size[] getSupportedPreviewSizes() {
StreamConfigurationMap config =
mCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
return Size.convert(config.getOutputSizes(sCaptureImageFormat));
}
- @Override
public float getFullSizeAspectRatio() {
return mFullSizeAspectRatio;
}
diff --git a/src/com/android/camera/one/v2/SimpleJpegOneCameraFactory.java b/src/com/android/camera/one/v2/SimpleJpegOneCameraFactory.java
deleted file mode 100644
index 367ce11..0000000
--- a/src/com/android/camera/one/v2/SimpleJpegOneCameraFactory.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * 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;
-
-import android.annotation.TargetApi;
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.media.ImageReader;
-import android.os.Build;
-import android.os.Handler;
-import android.view.Surface;
-
-import com.android.camera.app.OrientationManager;
-import com.android.camera.async.CallbackRunnable;
-import com.android.camera.async.ConcurrentState;
-import com.android.camera.async.HandlerExecutor;
-import com.android.camera.async.Lifetime;
-import com.android.camera.async.Updatable;
-import com.android.camera.one.OneCamera;
-import com.android.camera.one.v2.autofocus.ManualAutoFocus;
-import com.android.camera.one.v2.autofocus.ManualAutoFocusFactory;
-import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
-import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy;
-import com.android.camera.one.v2.camera2proxy.CameraDeviceRequestBuilderFactory;
-import com.android.camera.one.v2.camera2proxy.ImageProxy;
-import com.android.camera.one.v2.commands.CameraCommandExecutor;
-import com.android.camera.one.v2.commands.PreviewCommand;
-import com.android.camera.one.v2.commands.RunnableCameraCommand;
-import com.android.camera.one.v2.common.SimpleCaptureStream;
-import com.android.camera.one.v2.common.TimestampResponseListener;
-import com.android.camera.one.v2.common.TotalCaptureResultResponseListener;
-import com.android.camera.one.v2.common.ZoomedCropRegion;
-import com.android.camera.one.v2.core.CaptureStream;
-import com.android.camera.one.v2.core.RequestTemplate;
-import com.android.camera.one.v2.core.FrameServer;
-import com.android.camera.one.v2.core.FrameServerFactory;
-import com.android.camera.one.v2.initialization.CameraStarter;
-import com.android.camera.one.v2.initialization.InitializedOneCameraFactory;
-import com.android.camera.one.v2.photo.ImageSaver;
-import com.android.camera.one.v2.photo.PictureTaker;
-import com.android.camera.one.v2.photo.PictureTakerFactory;
-import com.android.camera.one.v2.sharedimagereader.ImageStreamFactory;
-import com.android.camera.one.v2.sharedimagereader.SharedImageReaderFactory;
-import com.android.camera.session.CaptureSession;
-import com.android.camera.util.Size;
-import com.google.common.base.Supplier;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-/**
- * Creates a camera which takes jpeg images using the hardware encoder with
- * baseline functionality.
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-public class SimpleJpegOneCameraFactory {
- /**
- * Finishes constructing the camera when prerequisites, e.g. the preview
- * stream and capture session, are ready.
- */
- private static class CameraStarterImpl implements CameraStarter {
- private final CameraDeviceProxy mDevice;
- private final CameraCharacteristics mCameraCharacteristics;
- private final ImageReader mImageReader;
- private final Handler mMainHandler;
-
- private CameraStarterImpl(
- CameraDeviceProxy device,
- CameraCharacteristics cameraCharacteristics,
- ImageReader imageReader, Handler mainHandler) {
- mDevice = device;
- mCameraCharacteristics = cameraCharacteristics;
- mImageReader = imageReader;
- mMainHandler = mainHandler;
- }
-
- @Override
- public CameraControls startCamera(Lifetime cameraLifetime,
- CameraCaptureSessionProxy cameraCaptureSession,
- Surface previewSurface,
- ConcurrentState<Float> zoomState,
- Updatable<TotalCaptureResult> metadataCallback,
- Updatable<Boolean> readyState) {
- // Build the FrameServer from the CaptureSession
- FrameServerFactory frameServerFactory =
- new FrameServerFactory(new Lifetime(cameraLifetime), cameraCaptureSession);
- FrameServer frameServer = frameServerFactory.provideFrameServer();
-
- // Build the shared image reader
- SharedImageReaderFactory sharedImageReaderFactory = new SharedImageReaderFactory(new
- Lifetime(cameraLifetime), mImageReader);
-
- Updatable<Long> globalTimestampCallback =
- sharedImageReaderFactory.provideGlobalTimestampQueue();
- ImageStreamFactory imageStreamFactory =
- sharedImageReaderFactory.provideSharedImageReader();
-
- // The request builder used by all camera operations.
- // Streams, ResponseListeners, and Parameters added to
- // this will be applied to *all* requests sent to the camera.
- RequestTemplate rootBuilder = new RequestTemplate
- (new CameraDeviceRequestBuilderFactory(mDevice));
- // The shared image reader must be wired to receive every timestamp
- // for every image (including the preview).
- rootBuilder.addResponseListener(
- new TimestampResponseListener(globalTimestampCallback));
-
- rootBuilder.addResponseListener(new TotalCaptureResultResponseListener
- (metadataCallback));
-
- ZoomedCropRegion cropRegion = new ZoomedCropRegion(mCameraCharacteristics,
- zoomState);
- rootBuilder.setParam(CaptureRequest.SCALER_CROP_REGION, cropRegion);
-
- CaptureStream previewStream = new SimpleCaptureStream(previewSurface);
- rootBuilder.addStream(previewStream);
-
- int templateType = CameraDevice.TEMPLATE_PREVIEW;
-
- ScheduledExecutorService miscThreadPool = Executors.newScheduledThreadPool(1);
-
- CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor(miscThreadPool);
- PreviewCommand previewCommand = new PreviewCommand(frameServer, rootBuilder,
- templateType);
- Runnable previewRunner = new RunnableCameraCommand(cameraCommandExecutor,
- previewCommand);
-
- // Restart the preview when the zoom changes.
- zoomState.addCallback(new CallbackRunnable(previewRunner), miscThreadPool);
-
- OrientationManager.DeviceOrientation sensorOrientation = getSensorOrientation();
-
- ManualAutoFocusFactory manualAutoFocusFactory = new ManualAutoFocusFactory(new
- Lifetime(cameraLifetime), frameServer, miscThreadPool, cropRegion,
- sensorOrientation, previewRunner, rootBuilder, templateType);
- ManualAutoFocus autoFocus = manualAutoFocusFactory.provideManualAutoFocus();
- Supplier<MeteringRectangle[]> aeRegions =
- manualAutoFocusFactory.provideAEMeteringRegion();
- Supplier<MeteringRectangle[]> afRegions =
- manualAutoFocusFactory.provideAFMeteringRegion();
-
- rootBuilder.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
- rootBuilder.setParam(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
-
- HandlerExecutor mainExecutor = new HandlerExecutor(mMainHandler);
-
- // FIXME TODO Replace stub with real implementation
- ImageSaver.Builder imageSaverBuilder = new ImageSaver.Builder() {
- @Override
- public ImageSaver build(OrientationManager.DeviceOrientation orientation,
- CaptureSession session) {
- return new ImageSaver() {
- @Override
- public void saveAndCloseImage(ImageProxy imageProxy) {
- imageProxy.close();
- }
- };
- }
- };
-
- PictureTakerFactory pictureTakerFactory = new PictureTakerFactory(mainExecutor,
- cameraCommandExecutor, imageSaverBuilder, frameServer, rootBuilder,
- imageStreamFactory);
- PictureTaker pictureTaker = pictureTakerFactory.providePictureTaker();
-
- previewRunner.run();
-
- return new CameraControls(pictureTaker, autoFocus);
- }
-
- private OrientationManager.DeviceOrientation getSensorOrientation() {
- Integer degrees = mCameraCharacteristics.get(CameraCharacteristics
- .SENSOR_ORIENTATION);
-
- switch (degrees) {
- case 0:
- return OrientationManager.DeviceOrientation.CLOCKWISE_0;
- case 90:
- return OrientationManager.DeviceOrientation.CLOCKWISE_90;
- case 180:
- return OrientationManager.DeviceOrientation.CLOCKWISE_180;
- case 270:
- return OrientationManager.DeviceOrientation.CLOCKWISE_270;
- default:
- return OrientationManager.DeviceOrientation.CLOCKWISE_0;
- }
- }
- }
-
- private final InitializedOneCameraFactory mInitializedOneCameraFactory;
-
- public SimpleJpegOneCameraFactory(CameraDevice cameraDevice,
- CameraCharacteristics characteristics, Handler mainHandler, Size pictureSize) {
- CameraDeviceProxy device = new CameraDeviceProxy(cameraDevice);
-
- int imageFormat = ImageFormat.JPEG;
- // TODO This is totally arbitrary, and could probably be increased.
- int maxImageCount = 10;
-
- ImageReader imageReader = ImageReader.newInstance(pictureSize.getWidth(),
- pictureSize.getHeight(), imageFormat, 10);
-
- // FIXME TODO Close the ImageReader when all images have been freed!
-
- List<Surface> outputSurfaces = new ArrayList<>();
- outputSurfaces.add(imageReader.getSurface());
-
- CameraStarter cameraStarter = new CameraStarterImpl(device, characteristics, imageReader,
- mainHandler);
-
- mInitializedOneCameraFactory =
- new InitializedOneCameraFactory(cameraStarter, device, characteristics,
- outputSurfaces, imageFormat, mainHandler);
- }
-
- public OneCamera provideOneCamera() {
- return mInitializedOneCameraFactory.provideOneCamera();
- }
-}
diff --git a/src/com/android/camera/one/v2/SimpleOneCameraFactory.java b/src/com/android/camera/one/v2/SimpleOneCameraFactory.java
new file mode 100644
index 0000000..bf58849
--- /dev/null
+++ b/src/com/android/camera/one/v2/SimpleOneCameraFactory.java
@@ -0,0 +1,173 @@
+/*
+ * 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;
+
+import android.annotation.TargetApi;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.TotalCaptureResult;
+import android.media.ImageReader;
+import android.os.Build;
+import android.view.Surface;
+
+import com.android.camera.async.HandlerFactory;
+import com.android.camera.async.Lifetime;
+import com.android.camera.async.MainThreadExecutor;
+import com.android.camera.async.Observable;
+import com.android.camera.async.Updatable;
+import com.android.camera.one.OneCamera;
+import com.android.camera.one.OneCameraCharacteristics;
+import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
+import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy;
+import com.android.camera.one.v2.camera2proxy.CameraDeviceRequestBuilderFactory;
+import com.android.camera.one.v2.commands.CameraCommandExecutor;
+import com.android.camera.one.v2.common.BasicCameraFactory;
+import com.android.camera.one.v2.common.SimpleCaptureStream;
+import com.android.camera.one.v2.common.TimestampResponseListener;
+import com.android.camera.one.v2.core.FrameServer;
+import com.android.camera.one.v2.core.FrameServerFactory;
+import com.android.camera.one.v2.core.RequestBuilder;
+import com.android.camera.one.v2.core.RequestTemplate;
+import com.android.camera.one.v2.initialization.CameraStarter;
+import com.android.camera.one.v2.initialization.InitializedOneCameraFactory;
+import com.android.camera.one.v2.photo.ImageRotationCalculator;
+import com.android.camera.one.v2.photo.ImageRotationCalculatorImpl;
+import com.android.camera.one.v2.photo.ImageSaver;
+import com.android.camera.one.v2.photo.PictureTakerFactory;
+import com.android.camera.one.v2.photo.YuvImageBackendImageSaver;
+import com.android.camera.one.v2.sharedimagereader.ImageStreamFactory;
+import com.android.camera.one.v2.sharedimagereader.SharedImageReaderFactory;
+import com.android.camera.util.Size;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * Creates a camera which takes jpeg images using the hardware encoder with
+ * baseline functionality.
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class SimpleOneCameraFactory implements OneCameraFactory {
+ private final int mImageFormat;
+ private final int mMaxImageCount;
+
+ /**
+ * @param imageFormat The {@link ImageFormat} to use for full-size images to
+ * be saved.
+ * @param maxImageCount The size of the image reader to use for full-size
+ * images.
+ */
+ public SimpleOneCameraFactory(int imageFormat, int maxImageCount) {
+ mImageFormat = imageFormat;
+ mMaxImageCount = maxImageCount;
+ }
+
+ @Override
+ public OneCamera createOneCamera(final CameraDeviceProxy device,
+ final OneCameraCharacteristics characteristics, final MainThreadExecutor mainExecutor,
+ Size pictureSize,
+ final Observable<OneCamera.PhotoCaptureParameters.Flash> flashSetting) {
+
+ final ImageReader imageReader = ImageReader.newInstance(pictureSize.getWidth(),
+ pictureSize.getHeight(), mImageFormat, mMaxImageCount);
+ // FIXME TODO Close the ImageReader when all images have been freed!
+
+ List<Surface> outputSurfaces = new ArrayList<>();
+ outputSurfaces.add(imageReader.getSurface());
+
+ /**
+ * Finishes constructing the camera when prerequisites, e.g. the preview
+ * stream and capture session, are ready.
+ */
+ CameraStarter cameraStarter = new CameraStarter() {
+ @Override
+ public CameraStarter.CameraControls startCamera(Lifetime cameraLifetime,
+ CameraCaptureSessionProxy cameraCaptureSession,
+ Surface previewSurface,
+ Observable<Float> zoomState,
+ Updatable<TotalCaptureResult> metadataCallback,
+ Updatable<Boolean> readyState) {
+ // Create the FrameServer from the CaptureSession.
+ FrameServer frameServer = new FrameServerFactory(
+ new Lifetime(cameraLifetime), cameraCaptureSession, new HandlerFactory())
+ .provideFrameServer();
+
+ // Create a thread pool on which to execute camera operations.
+ ScheduledExecutorService miscThreadPool = Executors.newScheduledThreadPool(1);
+
+ // Create the shared image reader.
+ SharedImageReaderFactory sharedImageReaderFactory =
+ new SharedImageReaderFactory(new Lifetime(cameraLifetime), imageReader);
+ Updatable<Long> globalTimestampCallback =
+ sharedImageReaderFactory.provideGlobalTimestampQueue();
+ ImageStreamFactory imageStreamFactory =
+ sharedImageReaderFactory.provideSharedImageReader();
+
+ // Create the request builder used by all camera operations.
+ // Streams, ResponseListeners, and Parameters added to
+ // this will be applied to *all* requests sent to the camera.
+ RequestTemplate rootBuilder = new RequestTemplate
+ (new CameraDeviceRequestBuilderFactory(device));
+ // The shared image reader must be wired to receive every
+ // timestamp for every image (including the preview).
+ rootBuilder.addResponseListener(
+ new TimestampResponseListener(globalTimestampCallback));
+ rootBuilder.addStream(new SimpleCaptureStream(previewSurface));
+
+ // Create basic functionality (zoom, AE, AF).
+ BasicCameraFactory basicCameraFactory = new BasicCameraFactory(new Lifetime
+ (cameraLifetime), characteristics, frameServer, rootBuilder,
+ miscThreadPool, flashSetting, zoomState, CameraDevice
+ .TEMPLATE_ZERO_SHUTTER_LAG);
+
+ RequestBuilder.Factory meteredZooomedRequestBuilder =
+ basicCameraFactory.provideMeteredZoomedRequestBuilder();
+
+ // Create the image saver.
+ // Used to rotate images the right way based on the sensor used
+ // for taking the image.
+ ImageRotationCalculator imageRotationCalculator = ImageRotationCalculatorImpl
+ .from(characteristics);
+ // FIXME Create based on mImageFormat
+ ImageSaver.Builder imageSaverBuilder = new YuvImageBackendImageSaver(mainExecutor,
+ imageRotationCalculator);
+
+ // Create the picture-taker.
+ CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor(
+ miscThreadPool);
+
+ PictureTakerFactory pictureTakerFactory = new PictureTakerFactory(mainExecutor,
+ cameraCommandExecutor, imageSaverBuilder, frameServer,
+ meteredZooomedRequestBuilder, imageStreamFactory);
+
+ basicCameraFactory.providePreviewStarter().run();
+
+ return new CameraStarter.CameraControls(
+ pictureTakerFactory.providePictureTaker(),
+ basicCameraFactory.provideManualAutoFocus());
+ }
+ };
+
+ float maxZoom = characteristics.getAvailableMaxDigitalZoom();
+ List<Size> supportedPreviewSizes = characteristics.getSupportedPreviewSizes();
+ OneCamera.Facing direction = characteristics.getCameraDirection();
+
+ return new InitializedOneCameraFactory(cameraStarter, device, outputSurfaces, mainExecutor,
+ new HandlerFactory(), maxZoom, supportedPreviewSizes, direction).provideOneCamera();
+ }
+}
diff --git a/src/com/android/camera/one/v2/SimpleYuvOneCameraFactory.java b/src/com/android/camera/one/v2/SimpleYuvOneCameraFactory.java
deleted file mode 100644
index e5ccead..0000000
--- a/src/com/android/camera/one/v2/SimpleYuvOneCameraFactory.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * 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;
-
-import android.annotation.TargetApi;
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.media.ImageReader;
-import android.os.Build;
-import android.os.Handler;
-import android.view.Surface;
-
-import com.android.camera.app.OrientationManager;
-import com.android.camera.async.CallbackRunnable;
-import com.android.camera.async.ConcurrentState;
-import com.android.camera.async.HandlerExecutor;
-import com.android.camera.async.Lifetime;
-import com.android.camera.async.Updatable;
-import com.android.camera.one.OneCamera;
-import com.android.camera.one.v2.autofocus.ManualAutoFocus;
-import com.android.camera.one.v2.autofocus.ManualAutoFocusFactory;
-import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
-import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy;
-import com.android.camera.one.v2.camera2proxy.CameraDeviceRequestBuilderFactory;
-import com.android.camera.one.v2.commands.CameraCommandExecutor;
-import com.android.camera.one.v2.commands.PreviewCommand;
-import com.android.camera.one.v2.commands.RunnableCameraCommand;
-import com.android.camera.one.v2.common.SimpleCaptureStream;
-import com.android.camera.one.v2.common.TimestampResponseListener;
-import com.android.camera.one.v2.common.TotalCaptureResultResponseListener;
-import com.android.camera.one.v2.common.ZoomedCropRegion;
-import com.android.camera.one.v2.core.CaptureStream;
-import com.android.camera.one.v2.core.RequestTemplate;
-import com.android.camera.one.v2.core.FrameServer;
-import com.android.camera.one.v2.core.FrameServerFactory;
-import com.android.camera.one.v2.initialization.CameraStarter;
-import com.android.camera.one.v2.initialization.InitializedOneCameraFactory;
-import com.android.camera.one.v2.photo.ImageRotationCalculator;
-import com.android.camera.one.v2.photo.ImageRotationCalculatorImpl;
-import com.android.camera.one.v2.photo.ImageSaver;
-import com.android.camera.one.v2.photo.PictureTaker;
-import com.android.camera.one.v2.photo.PictureTakerFactory;
-import com.android.camera.one.v2.photo.YuvImageBackendImageSaver;
-import com.android.camera.one.v2.sharedimagereader.ImageStreamFactory;
-import com.android.camera.one.v2.sharedimagereader.SharedImageReaderFactory;
-import com.android.camera.util.Size;
-import com.google.common.base.Optional;
-import com.google.common.base.Supplier;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-/**
- * Creates a camera which takes jpeg images using the hardware encoder with
- * baseline functionality.
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-public class SimpleYuvOneCameraFactory {
- /**
- * Finishes constructing the camera when prerequisites, e.g. the preview
- * stream and capture session, are ready.
- */
- private static class CameraStarterImpl implements CameraStarter {
- private final CameraDeviceProxy mDevice;
- private final CameraCharacteristics mCameraCharacteristics;
- private final ImageReader mImageReader;
- private final Handler mMainHandler;
-
- private CameraStarterImpl(
- CameraDeviceProxy device,
- CameraCharacteristics cameraCharacteristics,
- ImageReader imageReader, Handler mainHandler) {
- mDevice = device;
- mCameraCharacteristics = cameraCharacteristics;
- mImageReader = imageReader;
- mMainHandler = mainHandler;
- }
-
- @Override
- public CameraControls startCamera(Lifetime cameraLifetime,
- CameraCaptureSessionProxy cameraCaptureSession,
- Surface previewSurface,
- ConcurrentState<Float> zoomState,
- Updatable<TotalCaptureResult> metadataCallback,
- Updatable<Boolean> readyState) {
- // Build the FrameServer from the CaptureSession
- FrameServerFactory frameServerFactory =
- new FrameServerFactory(new Lifetime(cameraLifetime), cameraCaptureSession);
- FrameServer frameServer = frameServerFactory.provideFrameServer();
-
- // Build the shared image reader
- SharedImageReaderFactory sharedImageReaderFactory = new SharedImageReaderFactory(new
- Lifetime(cameraLifetime), mImageReader);
-
- Updatable<Long> globalTimestampCallback =
- sharedImageReaderFactory.provideGlobalTimestampQueue();
- ImageStreamFactory imageStreamFactory =
- sharedImageReaderFactory.provideSharedImageReader();
-
- // The request builder used by all camera operations.
- // Streams, ResponseListeners, and Parameters added to
- // this will be applied to *all* requests sent to the camera.
- RequestTemplate rootBuilder = new RequestTemplate
- (new CameraDeviceRequestBuilderFactory(mDevice));
- // The shared image reader must be wired to receive every timestamp
- // for every image (including the preview).
- rootBuilder.addResponseListener(
- new TimestampResponseListener(globalTimestampCallback));
-
- rootBuilder.addResponseListener(new TotalCaptureResultResponseListener
- (metadataCallback));
-
- ZoomedCropRegion cropRegion = new ZoomedCropRegion(mCameraCharacteristics,
- zoomState);
- rootBuilder.setParam(CaptureRequest.SCALER_CROP_REGION, cropRegion);
-
- CaptureStream previewStream = new SimpleCaptureStream(previewSurface);
- rootBuilder.addStream(previewStream);
-
- int templateType = CameraDevice.TEMPLATE_PREVIEW;
-
- ScheduledExecutorService miscThreadPool = Executors.newScheduledThreadPool(1);
-
- CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor(miscThreadPool);
- PreviewCommand previewCommand = new PreviewCommand(frameServer, rootBuilder,
- templateType);
- Runnable previewRunner = new RunnableCameraCommand(cameraCommandExecutor,
- previewCommand);
-
- // Restart the preview when the zoom changes.
- zoomState.addCallback(new CallbackRunnable(previewRunner), miscThreadPool);
-
- OrientationManager.DeviceOrientation sensorOrientation = getSensorOrientation();
-
- ManualAutoFocusFactory manualAutoFocusFactory = new ManualAutoFocusFactory(new
- Lifetime(cameraLifetime), frameServer, miscThreadPool, cropRegion,
- sensorOrientation, previewRunner, rootBuilder, templateType);
- ManualAutoFocus autoFocus = manualAutoFocusFactory.provideManualAutoFocus();
- Supplier<MeteringRectangle[]> aeRegions =
- manualAutoFocusFactory.provideAEMeteringRegion();
- Supplier<MeteringRectangle[]> afRegions =
- manualAutoFocusFactory.provideAFMeteringRegion();
-
- rootBuilder.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
- rootBuilder.setParam(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
-
- HandlerExecutor mainExecutor = new HandlerExecutor(mMainHandler);
-
- // Used to rotate images the right way based on the sensor used for taking the image.
- ImageRotationCalculator imageRotationCalculator = ImageRotationCalculatorImpl
- .from(mCameraCharacteristics);
-
- ImageSaver.Builder imageSaverBuilder = new YuvImageBackendImageSaver(mainExecutor,
- imageRotationCalculator);
-
- PictureTakerFactory pictureTakerFactory = new PictureTakerFactory(mainExecutor,
- cameraCommandExecutor, imageSaverBuilder, frameServer, rootBuilder,
- imageStreamFactory);
- PictureTaker pictureTaker = pictureTakerFactory.providePictureTaker();
-
- previewRunner.run();
-
- return new CameraControls(pictureTaker, autoFocus);
- }
-
- private OrientationManager.DeviceOrientation getSensorOrientation() {
- Integer degrees = mCameraCharacteristics.get(CameraCharacteristics
- .SENSOR_ORIENTATION);
-
- switch (degrees) {
- case 0:
- return OrientationManager.DeviceOrientation.CLOCKWISE_0;
- case 90:
- return OrientationManager.DeviceOrientation.CLOCKWISE_90;
- case 180:
- return OrientationManager.DeviceOrientation.CLOCKWISE_180;
- case 270:
- return OrientationManager.DeviceOrientation.CLOCKWISE_270;
- default:
- return OrientationManager.DeviceOrientation.CLOCKWISE_0;
- }
- }
- }
-
- private final InitializedOneCameraFactory mInitializedOneCameraFactory;
-
- public SimpleYuvOneCameraFactory(CameraDevice cameraDevice,
- CameraCharacteristics characteristics, Handler mainHandler, Size pictureSize) {
- CameraDeviceProxy device = new CameraDeviceProxy(cameraDevice);
-
- int imageFormat = ImageFormat.YUV_420_888;
- // TODO This is totally arbitrary, and could probably be increased.
- int maxImageCount = 10;
-
- ImageReader imageReader = ImageReader.newInstance(pictureSize.getWidth(),
- pictureSize.getHeight(), imageFormat, maxImageCount);
-
- // FIXME TODO Close the ImageReader when all images have been freed!
-
- List<Surface> outputSurfaces = new ArrayList<>();
- outputSurfaces.add(imageReader.getSurface());
-
- CameraStarter cameraStarter = new CameraStarterImpl(device, characteristics, imageReader,
- mainHandler);
-
- mInitializedOneCameraFactory =
- new InitializedOneCameraFactory(cameraStarter, device, characteristics,
- outputSurfaces, imageFormat, mainHandler);
- }
-
- public OneCamera provideOneCamera() {
- return mInitializedOneCameraFactory.provideOneCamera();
- }
-}
diff --git a/src/com/android/camera/one/v2/ZslOneCameraFactory.java b/src/com/android/camera/one/v2/ZslOneCameraFactory.java
index 3ceecc0..32ef1bd 100644
--- a/src/com/android/camera/one/v2/ZslOneCameraFactory.java
+++ b/src/com/android/camera/one/v2/ZslOneCameraFactory.java
@@ -16,230 +16,149 @@
package com.android.camera.one.v2;
-import android.annotation.TargetApi;
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.params.MeteringRectangle;
import android.media.ImageReader;
-import android.os.Build;
-import android.os.Handler;
import android.view.Surface;
-import com.android.camera.app.OrientationManager;
-import com.android.camera.async.CallbackRunnable;
-import com.android.camera.async.ConcurrentState;
-import com.android.camera.async.HandlerExecutor;
+import com.android.camera.async.HandlerFactory;
import com.android.camera.async.Lifetime;
+import com.android.camera.async.MainThreadExecutor;
+import com.android.camera.async.Observable;
import com.android.camera.async.Updatable;
import com.android.camera.one.OneCamera;
-import com.android.camera.one.v2.autofocus.ManualAutoFocus;
-import com.android.camera.one.v2.autofocus.ManualAutoFocusFactory;
+import com.android.camera.one.OneCameraCharacteristics;
import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy;
import com.android.camera.one.v2.camera2proxy.CameraDeviceRequestBuilderFactory;
import com.android.camera.one.v2.commands.CameraCommandExecutor;
-import com.android.camera.one.v2.commands.PreviewCommand;
-import com.android.camera.one.v2.commands.RunnableCameraCommand;
+import com.android.camera.one.v2.common.BasicCameraFactory;
import com.android.camera.one.v2.common.SimpleCaptureStream;
import com.android.camera.one.v2.common.TimestampResponseListener;
-import com.android.camera.one.v2.common.TotalCaptureResultResponseListener;
-import com.android.camera.one.v2.common.ZoomedCropRegion;
-import com.android.camera.one.v2.core.CaptureStream;
import com.android.camera.one.v2.core.FrameServer;
import com.android.camera.one.v2.core.FrameServerFactory;
+import com.android.camera.one.v2.core.RequestBuilder;
import com.android.camera.one.v2.core.RequestTemplate;
import com.android.camera.one.v2.initialization.CameraStarter;
import com.android.camera.one.v2.initialization.InitializedOneCameraFactory;
import com.android.camera.one.v2.photo.ImageRotationCalculator;
import com.android.camera.one.v2.photo.ImageRotationCalculatorImpl;
import com.android.camera.one.v2.photo.ImageSaver;
-import com.android.camera.one.v2.photo.PictureTaker;
import com.android.camera.one.v2.photo.YuvImageBackendImageSaver;
import com.android.camera.one.v2.photo.ZslPictureTakerFactory;
import com.android.camera.one.v2.sharedimagereader.ImageStreamFactory;
import com.android.camera.one.v2.sharedimagereader.ZslSharedImageReaderFactory;
import com.android.camera.one.v2.sharedimagereader.imagedistributor.ImageStream;
-import com.android.camera.one.v2.stats.PreviewFpsListener;
import com.android.camera.util.Size;
-import com.google.common.base.Supplier;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
-/**
- * Creates a camera which takes YUV images with zero shutter lag.
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-public class ZslOneCameraFactory {
- /**
- * Finishes constructing the camera when prerequisites, e.g. the preview
- * stream and capture session, are ready.
- */
- private static class CameraStarterImpl implements CameraStarter {
- private final CameraDeviceProxy mDevice;
- private final CameraCharacteristics mCameraCharacteristics;
- private final ImageReader mImageReader;
- private final Handler mMainHandler;
+public class ZslOneCameraFactory implements OneCameraFactory {
+ private final int mImageFormat;
+ private final int mMaxImageCount;
- private CameraStarterImpl(
- CameraDeviceProxy device,
- CameraCharacteristics cameraCharacteristics,
- ImageReader imageReader, Handler mainHandler) {
- mDevice = device;
- mCameraCharacteristics = cameraCharacteristics;
- mImageReader = imageReader;
- mMainHandler = mainHandler;
- }
-
- @Override
- public CameraControls startCamera(Lifetime cameraLifetime,
- CameraCaptureSessionProxy cameraCaptureSession,
- Surface previewSurface,
- ConcurrentState<Float> zoomState,
- Updatable<TotalCaptureResult> metadataCallback,
- Updatable<Boolean> readyState) {
- // Build the FrameServer from the CaptureSession
- FrameServerFactory frameServerFactory =
- new FrameServerFactory(new Lifetime(cameraLifetime), cameraCaptureSession);
- FrameServer frameServer = frameServerFactory.provideFrameServer();
-
- // Build the shared image reader
- ZslSharedImageReaderFactory sharedImageReaderFactory =
- new ZslSharedImageReaderFactory(new Lifetime(cameraLifetime), mImageReader);
-
- Updatable<Long> globalTimestampCallback =
- sharedImageReaderFactory.provideGlobalTimestampQueue();
- ImageStreamFactory imageStreamFactory =
- sharedImageReaderFactory.provideSharedImageReader();
- ImageStream zslImageStream = sharedImageReaderFactory.provideZSLCaptureStream();
-
- // The request builder used by all camera operations.
- // Streams, ResponseListeners, and Parameters added to
- // this will be applied to *all* requests sent to the camera.
- RequestTemplate rootBuilder = new RequestTemplate
- (new CameraDeviceRequestBuilderFactory(mDevice));
- // The shared image reader must be wired to receive every timestamp
- // for every image (including the preview).
- rootBuilder.addResponseListener(
- new TimestampResponseListener(globalTimestampCallback));
-
- rootBuilder.addResponseListener(new PreviewFpsListener());
-
- // TODO Change AE mode depending on flash mode.
- rootBuilder.setParam(CaptureRequest.CONTROL_AE_MODE, CaptureRequest
- .CONTROL_AE_MODE_ON);
-
- rootBuilder.addStream(zslImageStream);
-
- rootBuilder.addResponseListener(new TotalCaptureResultResponseListener
- (metadataCallback));
-
- ZoomedCropRegion cropRegion = new ZoomedCropRegion(mCameraCharacteristics,
- zoomState);
- rootBuilder.setParam(CaptureRequest.SCALER_CROP_REGION, cropRegion);
-
- CaptureStream previewStream = new SimpleCaptureStream(previewSurface);
- rootBuilder.addStream(previewStream);
-
- ScheduledExecutorService miscThreadPool = Executors.newScheduledThreadPool(1);
-
- CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor(miscThreadPool);
- PreviewCommand previewCommand = new PreviewCommand(frameServer, rootBuilder,
- CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
-
- Runnable previewRunner = new RunnableCameraCommand(cameraCommandExecutor,
- previewCommand);
-
- // Resend the repeating preview request when the zoom changes to
- // apply the new crop factor.
- zoomState.addCallback(new CallbackRunnable(previewRunner), miscThreadPool);
-
- OrientationManager.DeviceOrientation sensorOrientation = getSensorOrientation();
-
- ManualAutoFocusFactory manualAutoFocusFactory = new ManualAutoFocusFactory(new
- Lifetime(cameraLifetime), frameServer, miscThreadPool, cropRegion,
- sensorOrientation, previewRunner, rootBuilder,
- CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
- ManualAutoFocus autoFocus = manualAutoFocusFactory.provideManualAutoFocus();
- Supplier<MeteringRectangle[]> aeRegions =
- manualAutoFocusFactory.provideAEMeteringRegion();
- Supplier<MeteringRectangle[]> afRegions =
- manualAutoFocusFactory.provideAFMeteringRegion();
-
- rootBuilder.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
- rootBuilder.setParam(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
-
- HandlerExecutor mainExecutor = new HandlerExecutor(mMainHandler);
-
- // Used to rotate images the right way based on the sensor used for taking the image.
- ImageRotationCalculator imageRotationCalculator = ImageRotationCalculatorImpl
- .from(mCameraCharacteristics);
-
- ImageSaver.Builder imageSaverBuilder = new YuvImageBackendImageSaver(mainExecutor,
- imageRotationCalculator);
-
- ZslPictureTakerFactory pictureTakerFactory = new ZslPictureTakerFactory(mainExecutor,
- cameraCommandExecutor, imageSaverBuilder, frameServer, rootBuilder,
- imageStreamFactory, zslImageStream);
- PictureTaker pictureTaker = pictureTakerFactory.providePictureTaker();
-
- previewRunner.run();
-
- return new CameraControls(pictureTaker, autoFocus);
- }
-
- private OrientationManager.DeviceOrientation getSensorOrientation() {
- Integer degrees = mCameraCharacteristics.get(CameraCharacteristics
- .SENSOR_ORIENTATION);
-
- switch (degrees) {
- case 0:
- return OrientationManager.DeviceOrientation.CLOCKWISE_0;
- case 90:
- return OrientationManager.DeviceOrientation.CLOCKWISE_90;
- case 180:
- return OrientationManager.DeviceOrientation.CLOCKWISE_180;
- case 270:
- return OrientationManager.DeviceOrientation.CLOCKWISE_270;
- default:
- return OrientationManager.DeviceOrientation.CLOCKWISE_0;
- }
- }
+ public ZslOneCameraFactory(int imageFormat, int maxImageCount) {
+ mImageFormat = imageFormat;
+ mMaxImageCount = maxImageCount;
}
- private final InitializedOneCameraFactory mInitializedOneCameraFactory;
+ @Override
+ public OneCamera createOneCamera(final CameraDeviceProxy device,
+ final OneCameraCharacteristics characteristics,
+ final MainThreadExecutor mainThreadExecutor,
+ Size pictureSize,
+ final Observable<OneCamera.PhotoCaptureParameters.Flash> flashSetting) {
- public ZslOneCameraFactory(CameraDevice cameraDevice,
- CameraCharacteristics characteristics, Handler mainHandler, Size pictureSize) {
- CameraDeviceProxy device = new CameraDeviceProxy(cameraDevice);
-
- int imageFormat = ImageFormat.YUV_420_888;
- // TODO This is totally arbitrary, and could probably be increased.
- int maxImageCount = 10;
-
- ImageReader imageReader = ImageReader.newInstance(pictureSize.getWidth(),
- pictureSize.getHeight(), imageFormat, maxImageCount);
-
+ final ImageReader imageReader = ImageReader.newInstance(pictureSize.getWidth(),
+ pictureSize.getHeight(), mImageFormat, mMaxImageCount);
// FIXME TODO Close the ImageReader when all images have been freed!
List<Surface> outputSurfaces = new ArrayList<>();
outputSurfaces.add(imageReader.getSurface());
- CameraStarter cameraStarter = new CameraStarterImpl(device, characteristics, imageReader,
- mainHandler);
+ /**
+ * Finishes constructing the camera when prerequisites, e.g. the preview
+ * stream and capture session, are ready.
+ */
+ CameraStarter cameraStarter = new CameraStarter() {
+ @Override
+ public CameraControls startCamera(Lifetime cameraLifetime,
+ CameraCaptureSessionProxy cameraCaptureSession,
+ Surface previewSurface,
+ Observable<Float> zoomState,
+ Updatable<TotalCaptureResult> metadataCallback,
+ Updatable<Boolean> readyState) {
+ // Create the FrameServer from the CaptureSession.
+ FrameServer frameServer = new FrameServerFactory(
+ new Lifetime(cameraLifetime), cameraCaptureSession, new HandlerFactory())
+ .provideFrameServer();
- mInitializedOneCameraFactory =
- new InitializedOneCameraFactory(cameraStarter, device, characteristics,
- outputSurfaces, imageFormat, mainHandler);
- }
+ // Create a thread pool on which to execute camera operations.
+ ScheduledExecutorService miscThreadPool = Executors.newScheduledThreadPool(1);
- public OneCamera provideOneCamera() {
- return mInitializedOneCameraFactory.provideOneCamera();
+ // Create the shared image reader.
+ ZslSharedImageReaderFactory sharedImageReaderFactory =
+ new ZslSharedImageReaderFactory(new Lifetime(cameraLifetime), imageReader);
+ Updatable<Long> globalTimestampCallback =
+ sharedImageReaderFactory.provideGlobalTimestampQueue();
+ ImageStreamFactory imageStreamFactory =
+ sharedImageReaderFactory.provideSharedImageReader();
+ ImageStream zslStream = sharedImageReaderFactory.provideZSLCaptureStream();
+
+ // Create the request builder used by all camera operations.
+ // Streams, ResponseListeners, and Parameters added to
+ // this will be applied to *all* requests sent to the camera.
+ RequestTemplate rootBuilder = new RequestTemplate
+ (new CameraDeviceRequestBuilderFactory(device));
+ // The shared image reader must be wired to receive every
+ // timestamp for every image (including the preview).
+ rootBuilder.addResponseListener(
+ new TimestampResponseListener(globalTimestampCallback));
+ rootBuilder.addStream(new SimpleCaptureStream(previewSurface));
+ rootBuilder.addStream(zslStream);
+
+ // Create basic functionality (zoom, AE, AF).
+ BasicCameraFactory basicCameraFactory = new BasicCameraFactory(new Lifetime
+ (cameraLifetime), characteristics, frameServer, rootBuilder,
+ miscThreadPool, flashSetting, zoomState, CameraDevice
+ .TEMPLATE_ZERO_SHUTTER_LAG);
+
+ RequestBuilder.Factory meteredZooomedRequestBuilder =
+ basicCameraFactory.provideMeteredZoomedRequestBuilder();
+
+ // Create the image saver.
+ // Used to rotate images the right way based on the sensor used
+ // for taking the image.
+ ImageRotationCalculator imageRotationCalculator = ImageRotationCalculatorImpl
+ .from(characteristics);
+ ImageSaver.Builder imageSaverBuilder = new YuvImageBackendImageSaver(
+ mainThreadExecutor, imageRotationCalculator);
+
+ // Create the picture-taker.
+ CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor(
+ miscThreadPool);
+
+ ZslPictureTakerFactory pictureTakerFactory = new ZslPictureTakerFactory(
+ mainThreadExecutor, cameraCommandExecutor, imageSaverBuilder, frameServer,
+ meteredZooomedRequestBuilder, imageStreamFactory, zslStream);
+
+ basicCameraFactory.providePreviewStarter().run();
+
+ return new CameraControls(
+ pictureTakerFactory.providePictureTaker(),
+ basicCameraFactory.provideManualAutoFocus());
+ }
+ };
+
+ float maxZoom = characteristics.getAvailableMaxDigitalZoom();
+ List<Size> supportedPreviewSizes = characteristics.getSupportedPreviewSizes();
+ OneCamera.Facing direction = characteristics.getCameraDirection();
+ return new InitializedOneCameraFactory(cameraStarter, device,
+ outputSurfaces, mainThreadExecutor, new HandlerFactory(), maxZoom,
+ supportedPreviewSizes, direction).provideOneCamera();
}
}
diff --git a/src/com/android/camera/one/v2/autofocus/AEMeteringRegion.java b/src/com/android/camera/one/v2/autofocus/AEMeteringRegion.java
index 70b16ed..f0547ac 100644
--- a/src/com/android/camera/one/v2/autofocus/AEMeteringRegion.java
+++ b/src/com/android/camera/one/v2/autofocus/AEMeteringRegion.java
@@ -31,11 +31,11 @@
class AEMeteringRegion implements Supplier<MeteringRectangle[]> {
private final Supplier<MeteringParameters> mMeteringParameters;
private final Supplier<Rect> mCropRegion;
- private final OrientationManager.DeviceOrientation mSensorOrientation;
+ private final int mSensorOrientation;
public AEMeteringRegion(Supplier<MeteringParameters> meteringParameters,
Supplier<Rect> cropRegion,
- OrientationManager.DeviceOrientation sensorOrientation) {
+ int sensorOrientation) {
mMeteringParameters = meteringParameters;
mCropRegion = cropRegion;
mSensorOrientation = sensorOrientation;
@@ -48,7 +48,7 @@
Rect cropRegion = mCropRegion.get();
PointF point = parameters.getAEPoint();
return AutoFocusHelper.aeRegionsForNormalizedCoord(point.x, point.y, cropRegion,
- mSensorOrientation.getDegrees());
+ mSensorOrientation);
} else {
return AutoFocusHelper.getZeroWeightRegion();
}
diff --git a/src/com/android/camera/one/v2/autofocus/AFMeteringRegion.java b/src/com/android/camera/one/v2/autofocus/AFMeteringRegion.java
index 6f6b74a..bbb1843 100644
--- a/src/com/android/camera/one/v2/autofocus/AFMeteringRegion.java
+++ b/src/com/android/camera/one/v2/autofocus/AFMeteringRegion.java
@@ -31,11 +31,11 @@
class AFMeteringRegion implements Supplier<MeteringRectangle[]> {
private final Supplier<MeteringParameters> mMeteringParameters;
private final Supplier<Rect> mCropRegion;
- private final OrientationManager.DeviceOrientation mSensorOrientation;
+ private final int mSensorOrientation;
public AFMeteringRegion(Supplier<MeteringParameters> meteringParameters,
Supplier<Rect> cropRegion,
- OrientationManager.DeviceOrientation sensorOrientation) {
+ int sensorOrientation) {
mMeteringParameters = meteringParameters;
mCropRegion = cropRegion;
mSensorOrientation = sensorOrientation;
@@ -48,7 +48,7 @@
Rect cropRegion = mCropRegion.get();
PointF point = parameters.getAEPoint();
return AutoFocusHelper.afRegionsForNormalizedCoord(point.x, point.y, cropRegion,
- mSensorOrientation.getDegrees());
+ mSensorOrientation);
} else {
return AutoFocusHelper.getZeroWeightRegion();
}
diff --git a/src/com/android/camera/one/v2/autofocus/ManualAutoFocusFactory.java b/src/com/android/camera/one/v2/autofocus/ManualAutoFocusFactory.java
index d1b4d19..319e00c 100644
--- a/src/com/android/camera/one/v2/autofocus/ManualAutoFocusFactory.java
+++ b/src/com/android/camera/one/v2/autofocus/ManualAutoFocusFactory.java
@@ -60,7 +60,7 @@
*/
public ManualAutoFocusFactory(Lifetime lifetime, FrameServer frameServer,
ScheduledExecutorService threadPool, Supplier<Rect> cropRegion,
- OrientationManager.DeviceOrientation sensorOrientation,
+ int sensorOrientation,
Runnable previewRunner, RequestBuilder.Factory rootBuilder,
int templateType) {
CameraCommandExecutor commandExecutor = new CameraCommandExecutor(threadPool);
diff --git a/src/com/android/camera/one/v2/common/BasicCameraFactory.java b/src/com/android/camera/one/v2/common/BasicCameraFactory.java
new file mode 100644
index 0000000..1f04719
--- /dev/null
+++ b/src/com/android/camera/one/v2/common/BasicCameraFactory.java
@@ -0,0 +1,136 @@
+/*
+ * 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.graphics.Rect;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.MeteringRectangle;
+
+import com.android.camera.app.OrientationManager;
+import com.android.camera.async.CallbackRunnable;
+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.v2.autofocus.ManualAutoFocus;
+import com.android.camera.one.v2.autofocus.ManualAutoFocusFactory;
+import com.android.camera.one.v2.commands.CameraCommandExecutor;
+import com.android.camera.one.v2.commands.PreviewCommand;
+import com.android.camera.one.v2.commands.RunnableCameraCommand;
+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.google.common.base.Supplier;
+
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * 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>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>
+ */
+public class BasicCameraFactory {
+ private final ManualAutoFocus mManualAutoFocus;
+ private final RequestBuilder.Factory mMeteredZoomedRequestBuilder;
+ private final Runnable mPreviewStarter;
+ private OrientationManager.DeviceOrientation mSensorOrientation;
+
+ /**
+ * @param lifetime The lifetime of all created objects and their associated
+ * resources.
+ * @param cameraCharacteristics
+ * @param rootBuilder Provides preconfigured request builders to be used for
+ * all requests to mFrameServer.
+ * @param threadPool A dynamically-sized thread pool on which to interact
+ * @param templateType
+ */
+ public BasicCameraFactory(Lifetime lifetime,
+ OneCameraCharacteristics cameraCharacteristics,
+ FrameServer frameServer,
+ RequestBuilder.Factory rootBuilder,
+ ScheduledExecutorService threadPool,
+ Observable<OneCamera.PhotoCaptureParameters.Flash> flash,
+ Observable<Float> zoom, int templateType) {
+ RequestTemplate previewBuilder = new RequestTemplate(rootBuilder);
+ previewBuilder.setParam(
+ CaptureRequest.CONTROL_AE_MODE, new FlashBasedAEMode(flash));
+
+ Supplier<Rect> cropRegion = new ZoomedCropRegion(
+ cameraCharacteristics.getSensorInfoActiveArraySize(), zoom);
+ previewBuilder.setParam(CaptureRequest.SCALER_CROP_REGION, cropRegion);
+
+ CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor(threadPool);
+ lifetime.add(cameraCommandExecutor);
+ PreviewCommand previewCommand = new PreviewCommand(frameServer, previewBuilder,
+ templateType);
+
+ mPreviewStarter = new RunnableCameraCommand(cameraCommandExecutor,
+ previewCommand);
+
+ // 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(new CallbackRunnable(mPreviewStarter),
+ threadPool);
+ lifetime.add(zoomCallback);
+ SafeCloseable flashCallback = flash.addCallback(new CallbackRunnable(mPreviewStarter),
+ threadPool);
+ lifetime.add(flashCallback);
+
+ int sensorOrientation =
+ cameraCharacteristics.getSensorOrientation();
+
+ ManualAutoFocusFactory manualAutoFocusFactory = new ManualAutoFocusFactory(new
+ Lifetime(lifetime), frameServer, threadPool, cropRegion,
+ sensorOrientation, mPreviewStarter, rootBuilder,
+ CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
+ mManualAutoFocus = manualAutoFocusFactory.provideManualAutoFocus();
+ Supplier<MeteringRectangle[]> aeRegions =
+ manualAutoFocusFactory.provideAEMeteringRegion();
+ Supplier<MeteringRectangle[]> afRegions =
+ manualAutoFocusFactory.provideAFMeteringRegion();
+
+ previewBuilder.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
+ previewBuilder.setParam(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
+
+ mMeteredZoomedRequestBuilder = previewBuilder;
+ }
+
+ public RequestBuilder.Factory provideMeteredZoomedRequestBuilder() {
+ return mMeteredZoomedRequestBuilder;
+ }
+
+ public ManualAutoFocus provideManualAutoFocus() {
+ return mManualAutoFocus;
+ }
+
+ public Runnable providePreviewStarter() {
+ return mPreviewStarter;
+ }
+}
diff --git a/src/com/android/camera/one/v2/common/ZoomedCropRegion.java b/src/com/android/camera/one/v2/common/ZoomedCropRegion.java
index dd89088..19d6535 100644
--- a/src/com/android/camera/one/v2/common/ZoomedCropRegion.java
+++ b/src/com/android/camera/one/v2/common/ZoomedCropRegion.java
@@ -25,18 +25,18 @@
* Computes the current crop region based on the current zoom.
*/
public class ZoomedCropRegion implements Supplier<Rect> {
- private final CameraCharacteristics mCharacteristics;
+ private final Rect mSensorArrayArea;
private final Supplier<Float> mZoom;
- public ZoomedCropRegion(CameraCharacteristics characteristics, Supplier<Float> zoom) {
- mCharacteristics = characteristics;
+ public ZoomedCropRegion(Rect sensorArrayArea, Supplier<Float> zoom) {
+ mSensorArrayArea = sensorArrayArea;
mZoom = zoom;
}
@Override
public Rect get() {
float zoom = mZoom.get();
- Rect sensor = mCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+ Rect sensor = mSensorArrayArea;
int xCenter = sensor.width() / 2;
int yCenter = sensor.height() / 2;
int xDelta = (int) (0.5f * sensor.width() / zoom);
diff --git a/src/com/android/camera/one/v2/core/FrameServerFactory.java b/src/com/android/camera/one/v2/core/FrameServerFactory.java
index 3304b6c..6859434 100644
--- a/src/com/android/camera/one/v2/core/FrameServerFactory.java
+++ b/src/com/android/camera/one/v2/core/FrameServerFactory.java
@@ -16,21 +16,24 @@
package com.android.camera.one.v2.core;
+import android.os.Handler;
+
import com.android.camera.async.CloseableHandlerThread;
+import com.android.camera.async.HandlerFactory;
import com.android.camera.async.Lifetime;
import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
public class FrameServerFactory {
private FrameServer mFrameServer;
- public FrameServerFactory(Lifetime lifetime, CameraCaptureSessionProxy cameraCaptureSession) {
- CloseableHandlerThread cameraHandler = new CloseableHandlerThread("CameraMetadataHandler");
- lifetime.add(cameraHandler);
+ public FrameServerFactory(Lifetime lifetime, CameraCaptureSessionProxy cameraCaptureSession,
+ HandlerFactory handlerFactory) {
+ Handler cameraHandler = handlerFactory.create(lifetime, "CameraMetadataHandler");
// TODO Maybe enable closing the FrameServer along with the lifetime?
// It would allow clean reuse of the cameraCaptureSession with
// non-frameserver interaction
mFrameServer = new FrameServerImpl(new TagDispatchCaptureSession(cameraCaptureSession,
- cameraHandler.get()));
+ cameraHandler));
}
public FrameServer provideFrameServer() {
diff --git a/src/com/android/camera/one/v2/initialization/CameraStarter.java b/src/com/android/camera/one/v2/initialization/CameraStarter.java
index b6e4242..f92f63b 100644
--- a/src/com/android/camera/one/v2/initialization/CameraStarter.java
+++ b/src/com/android/camera/one/v2/initialization/CameraStarter.java
@@ -21,6 +21,7 @@
import com.android.camera.async.ConcurrentState;
import com.android.camera.async.Lifetime;
+import com.android.camera.async.Observable;
import com.android.camera.async.Updatable;
import com.android.camera.one.v2.autofocus.ManualAutoFocus;
import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
@@ -64,7 +65,7 @@
Lifetime cameraLifetime,
CameraCaptureSessionProxy cameraCaptureSession,
Surface previewSurface,
- ConcurrentState<Float> zoomState,
+ Observable<Float> zoomState,
Updatable<TotalCaptureResult> metadataCallback,
Updatable<Boolean> readyStateCallback);
}
diff --git a/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java b/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java
index 9c51060..e24c11f 100644
--- a/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java
+++ b/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java
@@ -58,27 +58,19 @@
private final Listenable<Boolean> mReadyStateListenable;
private final float mMaxZoom;
private final Updatable<Float> mZoom;
- private final Size[] mSupportedPreviewSizes;
- private final float mFullSizeAspectRatio;
private final Facing mDirection;
private final PreviewSizeSelector mPreviewSizeSelector;
- private final Listenable<Boolean> mPreviewStartSuccessListenable;
private final PreviewStarter mPreviewStarter;
public GenericOneCameraImpl(SafeCloseable closeListener, PictureTaker pictureTaker,
ManualAutoFocus manualAutoFocus, Executor mainExecutor,
Listenable<Integer> afStateProvider, Listenable<FocusState> focusStateProvider,
Listenable<Boolean> readyStateListenable, float maxZoom, Updatable<Float> zoom,
- Size[] supportedPreviewSizes, float fullSizeAspectRatio, Facing direction,
- PreviewSizeSelector previewSizeSelector,
- Listenable<Boolean> previewStartSuccessListenable,
+ Facing direction, PreviewSizeSelector previewSizeSelector,
PreviewStarter previewStarter) {
- mPreviewStartSuccessListenable = previewStartSuccessListenable;
mCloseListener = closeListener;
mMainExecutor = mainExecutor;
mMaxZoom = maxZoom;
- mSupportedPreviewSizes = supportedPreviewSizes;
- mFullSizeAspectRatio = fullSizeAspectRatio;
mDirection = direction;
mPreviewSizeSelector = previewSizeSelector;
mPictureTaker = pictureTaker;
@@ -166,16 +158,6 @@
}
@Override
- public Size[] getSupportedPreviewSizes() {
- return mSupportedPreviewSizes;
- }
-
- @Override
- public float getFullSizeAspectRatio() {
- return mFullSizeAspectRatio;
- }
-
- @Override
public Facing getDirection() {
return mDirection;
}
diff --git a/src/com/android/camera/one/v2/initialization/InitializedOneCameraFactory.java b/src/com/android/camera/one/v2/initialization/InitializedOneCameraFactory.java
index 3467f7b..43de683 100644
--- a/src/com/android/camera/one/v2/initialization/InitializedOneCameraFactory.java
+++ b/src/com/android/camera/one/v2/initialization/InitializedOneCameraFactory.java
@@ -17,20 +17,14 @@
package com.android.camera.one.v2.initialization;
import android.annotation.TargetApi;
-import android.graphics.Rect;
-import android.graphics.SurfaceTexture;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Build;
import android.os.Handler;
import android.view.Surface;
-import com.android.camera.async.CloseableHandlerThread;
import com.android.camera.async.ConcurrentState;
import com.android.camera.async.FilteredUpdatable;
-import com.android.camera.async.HandlerExecutor;
+import com.android.camera.async.HandlerFactory;
import com.android.camera.async.Lifetime;
import com.android.camera.async.Listenable;
import com.android.camera.async.ListenableConcurrentState;
@@ -65,53 +59,30 @@
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class InitializedOneCameraFactory {
- private final CameraStarter mCameraStarter;
- private final CameraDeviceProxy mDevice;
- private final CameraCharacteristics mCameraCharacteristics;
- private final List<Surface> mOutputSurfaces;
- private final int mImageFormat;
- private final Handler mMainHandler;
+ private final GenericOneCameraImpl mOneCamera;
/**
* @param cameraStarter Starts the camera, after initialization of the
* preview stream and capture session is complete.
* @param device
- * @param cameraCharacteristics
* @param outputSurfaces The set of output Surfaces (excluding the
* not-yet-available preview Surface) to use when configuring the
* capture session.
- * @param imageFormat The image format of the Surface for full-size images
- * to be saved.
- * @param mainHandler
*/
public InitializedOneCameraFactory(
- CameraStarter cameraStarter,
- CameraDeviceProxy device,
- CameraCharacteristics cameraCharacteristics,
- List<Surface> outputSurfaces,
- int imageFormat,
- Handler mainHandler) {
- mCameraStarter = cameraStarter;
- mDevice = device;
- mCameraCharacteristics = cameraCharacteristics;
- mOutputSurfaces = outputSurfaces;
- mImageFormat = imageFormat;
- mMainHandler = mainHandler;
- }
-
- public OneCamera provideOneCamera() {
+ final CameraStarter cameraStarter, CameraDeviceProxy device,
+ List<Surface> outputSurfaces, Executor mainThreadExecutor,
+ HandlerFactory handlerFactory, float maxZoom, List<Size> supportedPreviewSizes,
+ OneCamera.Facing direction) {
// Assembles and returns a OneCamera based on the CameraStarter.
// All resources tied to the camera are contained (directly or
// transitively) by this.
final Lifetime cameraLifetime = new Lifetime();
- cameraLifetime.add(mDevice);
+ cameraLifetime.add(device);
// Create/wrap required threads.
- Executor mainThreadExecutor = new HandlerExecutor(mMainHandler);
-
- final CloseableHandlerThread cameraHandler = new CloseableHandlerThread("CameraHandler");
- cameraLifetime.add(cameraHandler);
+ final Handler cameraHandler = handlerFactory.create(cameraLifetime, "CameraHandler");
final ExecutorService miscThreadPool = Executors.newCachedThreadPool();
@@ -137,7 +108,6 @@
final ConcurrentState<Integer> afMode = new ConcurrentState<>(CaptureResult
.CONTROL_AF_MODE_OFF);
final ConcurrentState<Boolean> readyState = new ConcurrentState<>(false);
- final ConcurrentState<Boolean> previewStartSuccessState = new ConcurrentState<>(null);
// Wrap state to be able to register listeners which run on the main
// thread.
@@ -147,8 +117,6 @@
focusState, mainThreadExecutor);
Listenable<Boolean> readyStateListenable = new ListenableConcurrentState<>(readyState,
mainThreadExecutor);
- Listenable<Boolean> previewStateListenable = new ListenableConcurrentState<>
- (previewStartSuccessState, mainThreadExecutor);
// Wrap each value in a filter to ensure that only differences pass
// through.
@@ -168,16 +136,16 @@
// Note that these must be created in reverse-order to when they are run
// because each stage depends on the previous one.
- final CaptureSessionCreator captureSessionCreator = new CaptureSessionCreator(mDevice,
- cameraHandler.get());
+ final CaptureSessionCreator captureSessionCreator = new CaptureSessionCreator(device,
+ cameraHandler);
- PreviewStarter mPreviewStarter = new PreviewStarter(mOutputSurfaces,
+ PreviewStarter mPreviewStarter = new PreviewStarter(outputSurfaces,
captureSessionCreator,
new PreviewStarter.CameraCaptureSessionCreatedListener() {
@Override
public void onCameraCaptureSessionCreated(CameraCaptureSessionProxy session,
Surface previewSurface) {
- CameraStarter.CameraControls controls = mCameraStarter.startCamera(
+ CameraStarter.CameraControls controls = cameraStarter.startCamera(
new Lifetime(cameraLifetime),
session, previewSurface,
zoomState, metadataCallback, readyState);
@@ -186,47 +154,14 @@
}
});
- // Various constants/functionality which OneCamera implementations must
- // provide which do not depend on anything other than the
- // characteristics.
- PreviewSizeSelector previewSizeSelector = new PreviewSizeSelector(mImageFormat,
- getSupportedPreviewSizes());
- float maxZoom = getMaxZoom();
- Size[] supportedPreviewSizes = getSupportedPreviewSizes();
- float fullSizeAspectRatio = getFullSizeAspectRatio();
- OneCamera.Facing direction = getDirection();
+ PreviewSizeSelector previewSizeSelector = new PreviewSizeSelector(supportedPreviewSizes);
- return new GenericOneCameraImpl(cameraLifetime, pictureTaker,
- manualAutoFocus, mainThreadExecutor, afStateListenable, focusStateListenable,
- readyStateListenable, maxZoom, zoomState, supportedPreviewSizes,
- fullSizeAspectRatio, direction, previewSizeSelector, previewStateListenable,
- mPreviewStarter);
-
+ mOneCamera = new GenericOneCameraImpl(cameraLifetime, pictureTaker, manualAutoFocus,
+ mainThreadExecutor, afStateListenable, focusStateListenable, readyStateListenable,
+ maxZoom, zoomState, direction, previewSizeSelector, mPreviewStarter);
}
- private OneCamera.Facing getDirection() {
- switch (mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING)) {
- case CameraMetadata.LENS_FACING_BACK:
- return OneCamera.Facing.BACK;
- case CameraMetadata.LENS_FACING_FRONT:
- return OneCamera.Facing.FRONT;
- }
- return OneCamera.Facing.BACK;
- }
-
- private float getFullSizeAspectRatio() {
- Rect activeArraySize = mCameraCharacteristics.get(
- CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
- return ((float) (activeArraySize.width())) / activeArraySize.height();
- }
-
- private Size[] getSupportedPreviewSizes() {
- StreamConfigurationMap config = mCameraCharacteristics
- .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
- return Size.convert(config.getOutputSizes(SurfaceTexture.class));
- }
-
- private float getMaxZoom() {
- return mCameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
+ public OneCamera provideOneCamera() {
+ return mOneCamera;
}
}
diff --git a/src/com/android/camera/one/v2/initialization/PreviewSizeSelector.java b/src/com/android/camera/one/v2/initialization/PreviewSizeSelector.java
index c36a5e2..a28c2d5 100644
--- a/src/com/android/camera/one/v2/initialization/PreviewSizeSelector.java
+++ b/src/com/android/camera/one/v2/initialization/PreviewSizeSelector.java
@@ -17,56 +17,51 @@
package com.android.camera.one.v2.initialization;
import android.content.Context;
-import android.graphics.ImageFormat;
import com.android.camera.CaptureModuleUtil;
import com.android.camera.util.Size;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
/**
- * Picks a preview size.
+ * Picks a preview size. TODO Remove dependency on static CaptureModuleUtil
+ * function and write tests.
*/
class PreviewSizeSelector {
- private final int mImageFormat;
- private final Size[] mSupportedPreviewSizes;
+ private final List<Size> mSupportedPreviewSizes;
- public PreviewSizeSelector(int imageFormat, Size[] supportedPreviewSizes) {
- mImageFormat = imageFormat;
- mSupportedPreviewSizes = supportedPreviewSizes;
+ public PreviewSizeSelector(List<Size> supportedPreviewSizes) {
+ mSupportedPreviewSizes = new ArrayList<>(supportedPreviewSizes);
}
public Size pickPreviewSize(Size pictureSize, Context context) {
if (pictureSize == null) {
// TODO The default should be selected by the caller, and
// pictureSize should never be null.
- pictureSize = getDefaultPictureSize();
+ pictureSize = getLargestPictureSize();
}
float pictureAspectRatio = pictureSize.getWidth() / (float) pictureSize.getHeight();
- // Since devices only have one raw resolution we need to be more
- // flexible for selecting a matching preview resolution.
- Double aspectRatioTolerance = mImageFormat == ImageFormat.RAW_SENSOR ? 10d : null;
- Size size = CaptureModuleUtil.getOptimalPreviewSize(context, mSupportedPreviewSizes,
- pictureAspectRatio, aspectRatioTolerance);
+ Size size = CaptureModuleUtil.getOptimalPreviewSize(context,
+ (Size[]) mSupportedPreviewSizes.toArray(new Size[mSupportedPreviewSizes.size()]),
+ pictureAspectRatio, null);
return size;
}
/**
* @return The largest supported picture size.
*/
- private Size getDefaultPictureSize() {
- Size[] supportedSizes = mSupportedPreviewSizes;
-
- // Find the largest supported size.
- Size largestSupportedSize = supportedSizes[0];
- long largestSupportedSizePixels =
- largestSupportedSize.getWidth() * largestSupportedSize.getHeight();
- for (int i = 1; i < supportedSizes.length; i++) {
- long numPixels = supportedSizes[i].getWidth() * supportedSizes[i].getHeight();
- if (numPixels > largestSupportedSizePixels) {
- largestSupportedSize = supportedSizes[i];
- largestSupportedSizePixels = numPixels;
+ private Size getLargestPictureSize() {
+ return Collections.max(mSupportedPreviewSizes, new Comparator<Size>() {
+ @Override
+ public int compare(Size size1, Size size2) {
+ int area1 = size1.getWidth() * size1.getHeight();
+ int area2 = size2.getWidth() * size2.getHeight();
+ return Integer.compare(area1, area2);
}
- }
- return new Size(largestSupportedSize.getWidth(), largestSupportedSize.getHeight());
+ });
}
}
diff --git a/src/com/android/camera/one/v2/photo/ImageRotationCalculatorImpl.java b/src/com/android/camera/one/v2/photo/ImageRotationCalculatorImpl.java
index b20cca7..c999a53 100644
--- a/src/com/android/camera/one/v2/photo/ImageRotationCalculatorImpl.java
+++ b/src/com/android/camera/one/v2/photo/ImageRotationCalculatorImpl.java
@@ -17,10 +17,11 @@
package com.android.camera.one.v2.photo;
import android.annotation.TargetApi;
-import android.hardware.camera2.CameraCharacteristics;
import android.os.Build;
import com.android.camera.app.OrientationManager;
+import com.android.camera.one.OneCamera;
+import com.android.camera.one.OneCameraCharacteristics;
import com.android.camera.util.CameraUtil;
/**
@@ -48,11 +49,11 @@
/**
* Create a calculator based on Camera characteristics.
*/
- public static ImageRotationCalculator from(CameraCharacteristics characteristics) {
- int sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
- int lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING);
+ public static ImageRotationCalculator from(OneCameraCharacteristics characteristics) {
+ int sensorOrientation = characteristics.getSensorOrientation();
+ OneCamera.Facing lensDirection = characteristics.getCameraDirection();
return new ImageRotationCalculatorImpl(sensorOrientation,
- lensFacing == CameraCharacteristics.LENS_FACING_FRONT);
+ lensDirection == OneCamera.Facing.FRONT);
}
@Override
diff --git a/src/com/android/camera/one/v2/photo/PictureTakerFactory.java b/src/com/android/camera/one/v2/photo/PictureTakerFactory.java
index dbf0caf..0439b3f 100644
--- a/src/com/android/camera/one/v2/photo/PictureTakerFactory.java
+++ b/src/com/android/camera/one/v2/photo/PictureTakerFactory.java
@@ -18,6 +18,7 @@
import java.util.concurrent.Executor;
+import com.android.camera.async.MainThreadExecutor;
import com.android.camera.one.v2.commands.CameraCommandExecutor;
import com.android.camera.one.v2.core.FrameServer;
import com.android.camera.one.v2.core.RequestBuilder;
@@ -26,7 +27,8 @@
public class PictureTakerFactory {
private final PictureTakerImpl mPictureTaker;
- public PictureTakerFactory(Executor mainExecutor, CameraCommandExecutor commandExecutor,
+ public PictureTakerFactory(MainThreadExecutor mainExecutor,
+ CameraCommandExecutor commandExecutor,
ImageSaver.Builder imageSaverBuilder,
FrameServer frameServer,
RequestBuilder.Factory rootRequestBuilder,
diff --git a/src/com/android/camera/one/v2/photo/PictureTakerImpl.java b/src/com/android/camera/one/v2/photo/PictureTakerImpl.java
index c4a31a4..a738081 100644
--- a/src/com/android/camera/one/v2/photo/PictureTakerImpl.java
+++ b/src/com/android/camera/one/v2/photo/PictureTakerImpl.java
@@ -19,6 +19,7 @@
import android.hardware.camera2.CameraAccessException;
import com.android.camera.app.OrientationManager;
+import com.android.camera.async.MainThreadExecutor;
import com.android.camera.async.Updatable;
import com.android.camera.one.OneCamera;
import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionClosedException;
@@ -31,14 +32,14 @@
import java.util.concurrent.Executor;
class PictureTakerImpl implements PictureTaker {
- private final Executor mMainExecutor;
+ private final MainThreadExecutor mMainExecutor;
private final CameraCommandExecutor mCameraCommandExecutor;
private final ImageSaver.Builder mImageSaverBuilder;
private final ImageCaptureCommand mFlashOffCommand;
private final ImageCaptureCommand mFlashOnCommand;
private final ImageCaptureCommand mFlashAutoCommand;
- public PictureTakerImpl(Executor mainExecutor,
+ public PictureTakerImpl(MainThreadExecutor mainExecutor,
CameraCommandExecutor cameraCommandExecutor,
ImageSaver.Builder imageSaverBuilder,
ImageCaptureCommand flashOffCommand,
diff --git a/src/com/android/camera/one/v2/photo/YuvImageBackendImageSaver.java b/src/com/android/camera/one/v2/photo/YuvImageBackendImageSaver.java
index 446b9f6..93120d8 100644
--- a/src/com/android/camera/one/v2/photo/YuvImageBackendImageSaver.java
+++ b/src/com/android/camera/one/v2/photo/YuvImageBackendImageSaver.java
@@ -18,6 +18,7 @@
import android.net.Uri;
import com.android.camera.app.OrientationManager;
+import com.android.camera.async.MainThreadExecutor;
import com.android.camera.one.v2.camera2proxy.ImageProxy;
import com.android.camera.processing.ProcessingServiceManager;
import com.android.camera.processing.imagebackend.ImageBackend;
@@ -46,7 +47,7 @@
* @param imageRotationCalculator the image rotation calculator to determine
* the final image rotation with
*/
- public YuvImageBackendImageSaver(Executor executor,
+ public YuvImageBackendImageSaver(MainThreadExecutor executor,
ImageRotationCalculator imageRotationCalculator) {
mExecutor = executor;
mImageRotationCalculator = imageRotationCalculator;
diff --git a/src/com/android/camera/one/v2/photo/ZslPictureTakerFactory.java b/src/com/android/camera/one/v2/photo/ZslPictureTakerFactory.java
index 4d27785..95c114b 100644
--- a/src/com/android/camera/one/v2/photo/ZslPictureTakerFactory.java
+++ b/src/com/android/camera/one/v2/photo/ZslPictureTakerFactory.java
@@ -35,6 +35,7 @@
import java.util.concurrent.Executor;
import com.android.camera.async.BufferQueue;
+import com.android.camera.async.MainThreadExecutor;
import com.android.camera.one.v2.camera2proxy.ImageProxy;
import com.android.camera.one.v2.commands.CameraCommandExecutor;
import com.android.camera.one.v2.core.FrameServer;
@@ -44,7 +45,7 @@
public class ZslPictureTakerFactory {
private final PictureTakerImpl mPictureTaker;
- public ZslPictureTakerFactory(Executor mainExecutor,
+ public ZslPictureTakerFactory(MainThreadExecutor mainExecutor,
CameraCommandExecutor commandExecutor,
ImageSaver.Builder imageSaverBuilder,
FrameServer frameServer,
diff --git a/src/com/android/camera/one/v2/sharedimagereader/imagedistributor/ImageDistributor.java b/src/com/android/camera/one/v2/sharedimagereader/imagedistributor/ImageDistributor.java
index c1b2380..906c767 100644
--- a/src/com/android/camera/one/v2/sharedimagereader/imagedistributor/ImageDistributor.java
+++ b/src/com/android/camera/one/v2/sharedimagereader/imagedistributor/ImageDistributor.java
@@ -20,6 +20,9 @@
import com.android.camera.async.BufferQueueController;
import com.android.camera.one.v2.camera2proxy.ImageProxy;
+import javax.annotation.ParametersAreNonnullByDefault;
+
+@ParametersAreNonnullByDefault
public interface ImageDistributor {
/**
* Begins routing new images with timestamps matching those found in
diff --git a/src/com/android/camera/one/v2/sharedimagereader/imagedistributor/ImageDistributorImpl.java b/src/com/android/camera/one/v2/sharedimagereader/imagedistributor/ImageDistributorImpl.java
index 69e426e..1f378de 100644
--- a/src/com/android/camera/one/v2/sharedimagereader/imagedistributor/ImageDistributorImpl.java
+++ b/src/com/android/camera/one/v2/sharedimagereader/imagedistributor/ImageDistributorImpl.java
@@ -21,15 +21,18 @@
import com.android.camera.one.v2.camera2proxy.ImageProxy;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import javax.annotation.ParametersAreNonnullByDefault;
+import javax.annotation.concurrent.GuardedBy;
+
/**
* Distributes incoming images to output {@link BufferQueueController}s
* according to their timestamp.
*/
+@ParametersAreNonnullByDefault
class ImageDistributorImpl implements ImageDistributor {
/**
* An input timestamp stream and an output image stream to receive images
@@ -51,6 +54,7 @@
* the {@link BufferQueueController} to receive images with those
* timestamps.
*/
+ @GuardedBy("mDispatchTable")
private final Set<DispatchRecord> mDispatchTable;
/**
@@ -68,7 +72,7 @@
*/
public ImageDistributorImpl(BufferQueue<Long> globalTimestampBufferQueue) {
mGlobalTimestampBufferQueue = globalTimestampBufferQueue;
- mDispatchTable = Collections.synchronizedSet(new HashSet<DispatchRecord>());
+ mDispatchTable = new HashSet<>();
}
/**
@@ -85,8 +89,6 @@
* @param image The image to distribute.
*/
public void distributeImage(ImageProxy image) {
- // TODO Profile GC impact, and pool all allocations if necessary &
- // possible.
final long timestamp = image.getTimestamp();
// Wait until the global timestamp stream indicates that either the
@@ -98,7 +100,10 @@
// stream associated with a {@link DispatchRecord} are updated on the
// same thread in order.
try {
- while (mGlobalTimestampBufferQueue.getNext() <= timestamp) {
+ while (true) {
+ if (mGlobalTimestampBufferQueue.getNext() > timestamp) {
+ break;
+ }
}
} catch (InterruptedException e) {
image.close();
@@ -113,7 +118,10 @@
// mDispatchTable may be modified in {@link #addRoute} while iterating,
// so to avoid unnecessary locking, make a copy to iterate over.
- Set<DispatchRecord> recordsToProcess = new HashSet<>(mDispatchTable);
+ Set<DispatchRecord> recordsToProcess;
+ synchronized (mDispatchTable) {
+ recordsToProcess = new HashSet<>(mDispatchTable);
+ }
for (DispatchRecord dispatchRecord : recordsToProcess) {
// If either the input timestampBufferQueue or the output
// imageStream is closed, then the route can be removed.
@@ -125,14 +133,16 @@
if (requestedImageTimestamp == null) {
continue;
}
- if (requestedImageTimestamp.longValue() == timestamp) {
+ if (requestedImageTimestamp == timestamp) {
// Discard the value we just looked at.
dispatchRecord.timestampBufferQueue.discardNext();
streamsToReceiveImage.add(dispatchRecord.imageStream);
}
}
- mDispatchTable.removeAll(deadRecords);
+ synchronized (mDispatchTable) {
+ mDispatchTable.removeAll(deadRecords);
+ }
RefCountedImageProxy sharedImage = new RefCountedImageProxy(image,
streamsToReceiveImage.size());
@@ -161,6 +171,8 @@
@Override
public void addRoute(BufferQueue<Long> inputTimestampBufferQueue,
BufferQueueController<ImageProxy> outputStream) {
- mDispatchTable.add(new DispatchRecord(inputTimestampBufferQueue, outputStream));
+ synchronized (mDispatchTable) {
+ mDispatchTable.add(new DispatchRecord(inputTimestampBufferQueue, outputStream));
+ }
}
}
diff --git a/src_pd/com/android/camera/one/v2/OneCameraCreator.java b/src_pd/com/android/camera/one/v2/OneCameraCreator.java
index afb96b3..8d6781d 100644
--- a/src_pd/com/android/camera/one/v2/OneCameraCreator.java
+++ b/src_pd/com/android/camera/one/v2/OneCameraCreator.java
@@ -21,12 +21,13 @@
import android.hardware.camera2.CameraDevice;
import android.util.DisplayMetrics;
+import com.android.camera.app.AppController;
import com.android.camera.SoundPlayer;
import com.android.camera.one.OneCamera;
import com.android.camera.util.Size;
public class OneCameraCreator {
- public static OneCamera create(Context context, boolean useHdr, CameraDevice device,
+ public static OneCamera create(AppController context, boolean useHdr, CameraDevice device,
CameraCharacteristics characteristics, Size pictureSize, int maxMemoryMB,
DisplayMetrics displayMetrics, SoundPlayer soundPlayer) {
// TODO: Might want to switch current camera to vendor HDR.