[automerger skipped] Skip ab/6749736 in stage. am: 9e04ce7d66 -s ours am: 9a5211fcdc -s ours am: 7641634c69 -s ours

am skip reason: Change-Id I5aa308a65023521d6e35228754e0570a7083acb4 with SHA-1 e52e79c058 is in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Camera2/+/12797208

Change-Id: I3079c1fd32529b83290db0ab72410dcbe007ae29
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 00a58cd..1068bcf 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -411,7 +411,7 @@
         } catch (OneCameraException e) {
             Log.e(TAG, "Unable to provide a OneCameraManager. ", e);
         }
-        mDisplayRotation = CameraUtil.getDisplayRotation();
+        mDisplayRotation = CameraUtil.getDisplayRotation(activity);
         mCameraFacing = getFacingFromCameraId(
               mSettingsManager.getInteger(mAppController.getModuleScope(), Keys.KEY_CAMERA_ID));
         mShowErrorAndFinish = !updateCameraCharacteristics();
@@ -1218,7 +1218,7 @@
         Log.d(TAG, "updatePreviewTransform: " + incomingWidth + " x " + incomingHeight);
 
         synchronized (mDimensionLock) {
-            int incomingRotation = CameraUtil.getDisplayRotation();
+            int incomingRotation = CameraUtil.getDisplayRotation(mUI.getActivity());
             // Check for an actual change:
             if (mScreenHeight == incomingHeight && mScreenWidth == incomingWidth &&
                     incomingRotation == mDisplayRotation && !forceUpdate) {
@@ -1293,7 +1293,7 @@
             return;
         }
 
-        Size previewBufferSize = mCamera.pickPreviewSize(mPictureSize, mContext);
+        Size previewBufferSize = mCamera.pickPreviewSize(mPictureSize, mUI.getActivity());
         mPreviewBufferWidth = previewBufferSize.getWidth();
         mPreviewBufferHeight = previewBufferSize.getHeight();
 
diff --git a/src/com/android/camera/CaptureModuleUI.java b/src/com/android/camera/CaptureModuleUI.java
index cbf1932..c9a1c6e 100644
--- a/src/com/android/camera/CaptureModuleUI.java
+++ b/src/com/android/camera/CaptureModuleUI.java
@@ -94,6 +94,13 @@
     }
 
     /**
+     * Getter for the camera activity this UI is drawn into
+     */
+    public CameraActivity getActivity() {
+        return mActivity;
+    }
+
+    /**
      * Getter for the width of the visible area of the preview.
      */
     public int getPreviewAreaWidth() {
diff --git a/src/com/android/camera/CaptureModuleUtil.java b/src/com/android/camera/CaptureModuleUtil.java
index 6074dc9..d2808ab 100644
--- a/src/com/android/camera/CaptureModuleUtil.java
+++ b/src/com/android/camera/CaptureModuleUtil.java
@@ -16,6 +16,7 @@
 
 package com.android.camera;
 
+import android.app.Activity;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.view.Surface;
@@ -33,9 +34,9 @@
 public class CaptureModuleUtil {
     private static final Tag TAG = new Tag("CaptureModuleUtil");
 
-    public static int getDeviceNaturalOrientation(Context context) {
+    public static int getDeviceNaturalOrientation(Activity context) {
         Configuration config = context.getResources().getConfiguration();
-        int rotation = CameraUtil.getDisplayRotation();
+        int rotation = CameraUtil.getDisplayRotation(context);
 
         if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
                 config.orientation == Configuration.ORIENTATION_LANDSCAPE) ||
@@ -52,8 +53,8 @@
      * {@link CameraUtil#getOptimalPreviewSize(java.util.List, double)}
      * method for the camera1 api.
      */
-    public static Size getOptimalPreviewSize(Size[] sizes,double targetRatio) {
-        return getOptimalPreviewSize(sizes, targetRatio, null);
+    public static Size getOptimalPreviewSize(Size[] sizes, double targetRatio, Activity context) {
+        return getOptimalPreviewSize(sizes, targetRatio, null, context);
     }
 
     /**
@@ -63,7 +64,7 @@
      * tolerance. If tolerance is 'null', a default tolerance will be used.
      */
     public static Size getOptimalPreviewSize(Size[] sizes,
-            double targetRatio, Double aspectRatioTolerance) {
+            double targetRatio, Double aspectRatioTolerance, Activity context) {
         // TODO(andyhuibers): Don't hardcode this but use device's measurements.
         final int MAX_ASPECT_HEIGHT = 1080;
 
@@ -85,7 +86,7 @@
 
         int optimalIndex = CameraUtil
                 .getOptimalPreviewSizeIndex(camera1Sizes, targetRatio,
-                        aspectRatioTolerance);
+                        aspectRatioTolerance, context);
 
         if (optimalIndex == -1) {
             return null;
@@ -106,9 +107,9 @@
      */
     public static Size pickBufferDimensions(Size[] supportedPreviewSizes,
             double bestPreviewAspectRatio,
-            Context context) {
+            Activity context) {
         // Swap dimensions if the device is not in its natural orientation.
-        boolean swapDimens = (CameraUtil.getDisplayRotation() % 180) == 90;
+        boolean swapDimens = (CameraUtil.getDisplayRotation(context) % 180) == 90;
         // Swap dimensions if the device's natural orientation doesn't match
         // the sensor orientation.
         if (CaptureModuleUtil.getDeviceNaturalOrientation(context)
@@ -121,7 +122,7 @@
         }
 
         Size pick = CaptureModuleUtil.getOptimalPreviewSize(supportedPreviewSizes,
-                bestPreviewAspectRatio, null);
+                bestPreviewAspectRatio, null, context);
         Log.d(TAG, "Picked buffer size: " + pick.toString());
         return pick;
     }
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 6fb8243..7f42aaa 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -292,7 +292,7 @@
         // down and camera app is opened. Rotation animation will
         // take some time and the rotation value we have got may be
         // wrong. Framework does not have a callback for this now.
-        if (CameraUtil.getDisplayRotation() != mDisplayRotation) {
+        if (CameraUtil.getDisplayRotation(mActivity) != mDisplayRotation) {
             setDisplayOrientation();
         }
         if (SystemClock.uptimeMillis() - mOnResumeTime < 5000) {
@@ -1597,7 +1597,7 @@
 
     @Override
     public void updateCameraOrientation() {
-        if (mDisplayRotation != CameraUtil.getDisplayRotation()) {
+        if (mDisplayRotation != CameraUtil.getDisplayRotation(mActivity)) {
             setDisplayOrientation();
         }
     }
@@ -1723,7 +1723,7 @@
     }
 
     private void setDisplayOrientation() {
-        mDisplayRotation = CameraUtil.getDisplayRotation();
+        mDisplayRotation = CameraUtil.getDisplayRotation(mActivity);
         Characteristics info =
                 mActivity.getCameraProvider().getCharacteristics(mCameraId);
         mDisplayOrientation = info.getPreviewOrientation(mDisplayRotation);
@@ -2002,7 +2002,7 @@
         // the right aspect ratio.
         List<Size> sizes = Size.convert(mCameraCapabilities.getSupportedPreviewSizes());
         Size optimalSize = CameraUtil.getOptimalPreviewSize(sizes,
-                (double) pictureSize.width() / pictureSize.height());
+                (double) pictureSize.width() / pictureSize.height(), mActivity);
         Size original = new Size(mCameraSettings.getCurrentPreviewSize());
         if (!optimalSize.equals(original)) {
             Log.v(TAG, "setting preview size. optimal: " + optimalSize + "original: " + original);
diff --git a/src/com/android/camera/TextureViewHelper.java b/src/com/android/camera/TextureViewHelper.java
index 2125280..42c41e1 100644
--- a/src/com/android/camera/TextureViewHelper.java
+++ b/src/com/android/camera/TextureViewHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.camera;
 
+import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.RectF;
@@ -104,7 +105,7 @@
         Log.v(TAG, "onLayoutChange");
         int width = right - left;
         int height = bottom - top;
-        int rotation = CameraUtil.getDisplayRotation();
+        int rotation = CameraUtil.getDisplayRotation((Activity) mPreview.getContext());
         if (mWidth != width || mHeight != height || mOrientation != rotation) {
             mWidth = width;
             mHeight = height;
@@ -355,7 +356,7 @@
                 && (mAppController.getCurrentModuleIndex() == mCameraModeId ||
                 mAppController.getCurrentModuleIndex() == mCaptureIntentModeId)) {
             Log.v(TAG, "Applying Photo Mode, Capture Module, Nexus-4 specific fix for b/19271661");
-            mOrientation = CameraUtil.getDisplayRotation();
+            mOrientation = CameraUtil.getDisplayRotation((Activity) mPreview.getContext());
             matrix = getPreviewRotationalTransform(mOrientation,
                     new RectF(0, 0, mWidth, mHeight),
                     mCaptureLayoutHelper.getPreviewRect());
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 856781b..6c9752e 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -256,7 +256,7 @@
                     // down and camera app is opened. Rotation animation will
                     // take some time and the rotation value we have got may be
                     // wrong. Framework does not have a callback for this now.
-                    if ((CameraUtil.getDisplayRotation() != mDisplayRotation)
+                    if ((CameraUtil.getDisplayRotation(mActivity) != mDisplayRotation)
                             && !mMediaRecorderRecording && !mSwitchingCamera) {
                         startPreview();
                     }
@@ -783,7 +783,7 @@
 
         mCameraSettings = mCameraDevice.getSettings();
         Point desiredPreviewSize = getDesiredPreviewSize(
-              mCameraCapabilities, mProfile, mUI.getPreviewScreenSize());
+                mCameraCapabilities, mProfile, mUI.getPreviewScreenSize(), mActivity);
         mDesiredPreviewWidth = desiredPreviewSize.x;
         mDesiredPreviewHeight = desiredPreviewSize.y;
         mUI.setPreviewSize(mDesiredPreviewWidth, mDesiredPreviewHeight);
@@ -807,7 +807,7 @@
      *         opened yet.
      */
     private static Point getDesiredPreviewSize(CameraCapabilities capabilities,
-          CamcorderProfile profile, Point previewScreenSize) {
+            CamcorderProfile profile, Point previewScreenSize, Activity context) {
         if (capabilities.getSupportedVideoSizes() == null ||
             capabilities.getSupportedVideoSizes().isEmpty()) {
             // Driver doesn't support separate outputs for preview and video.
@@ -846,7 +846,7 @@
         }
 
         Size optimalSize = CameraUtil.getOptimalPreviewSize(sizes,
-                (double) profile.videoFrameWidth / profile.videoFrameHeight);
+                (double) profile.videoFrameWidth / profile.videoFrameHeight, context);
         return new Point(optimalSize.width(), optimalSize.height());
     }
 
@@ -865,7 +865,7 @@
     }
 
     private void setDisplayOrientation() {
-        mDisplayRotation = CameraUtil.getDisplayRotation();
+        mDisplayRotation = CameraUtil.getDisplayRotation(mActivity);
         Characteristics info =
                 mActivity.getCameraProvider().getCharacteristics(mCameraId);
         mCameraDisplayOrientation = info.getPreviewOrientation(mDisplayRotation);
@@ -883,7 +883,7 @@
         if (mMediaRecorderRecording) {
             return;
         }
-        if (mDisplayRotation != CameraUtil.getDisplayRotation()) {
+        if (mDisplayRotation != CameraUtil.getDisplayRotation(mActivity)) {
             setDisplayOrientation();
         }
     }
diff --git a/src/com/android/camera/app/CameraAppUI.java b/src/com/android/camera/app/CameraAppUI.java
index 44b4d3b..94bb69f 100644
--- a/src/com/android/camera/app/CameraAppUI.java
+++ b/src/com/android/camera/app/CameraAppUI.java
@@ -16,6 +16,7 @@
 
 package com.android.camera.app;
 
+import android.app.Activity;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -924,7 +925,7 @@
      */
     private void initDisplayListener() {
         if (ApiHelper.HAS_DISPLAY_LISTENER) {
-            mLastRotation = CameraUtil.getDisplayRotation();
+            mLastRotation = CameraUtil.getDisplayRotation((Activity) mAppRootView.getContext());
 
             mDisplayListener = new DisplayManager.DisplayListener() {
                 @Override
@@ -935,7 +936,7 @@
                 @Override
                 public void onDisplayChanged(int displayId) {
                     int rotation = CameraUtil.getDisplayRotation(
-                    );
+                        (Activity) mAppRootView.getContext());
                     if ((rotation - mLastRotation + 360) % 360 == 180
                             && mPreviewStatusListener != null) {
                         mPreviewStatusListener.onPreviewFlipped();
diff --git a/src/com/android/camera/app/OrientationManagerImpl.java b/src/com/android/camera/app/OrientationManagerImpl.java
index e818776..c458736 100644
--- a/src/com/android/camera/app/OrientationManagerImpl.java
+++ b/src/com/android/camera/app/OrientationManagerImpl.java
@@ -108,7 +108,7 @@
 
     @Override
     public DeviceOrientation getDisplayRotation() {
-        return DeviceOrientation.from((360 - CameraUtil.getDisplayRotation()) % 360);
+        return DeviceOrientation.from((360 - CameraUtil.getDisplayRotation(mActivity)) % 360);
     }
 
     @Override
@@ -270,8 +270,8 @@
      * @param context current context
      * @return whether the default orientation of the device is portrait
      */
-    private static boolean isDefaultToPortrait(Context context) {
-        Display currentDisplay = AndroidServices.instance().provideWindowManager()
+    private static boolean isDefaultToPortrait(Activity context) {
+        Display currentDisplay = AndroidServices.instance().provideWindowManager(context)
                 .getDefaultDisplay();
         Point displaySize = new Point();
         currentDisplay.getSize(displaySize);
diff --git a/src/com/android/camera/one/OneCamera.java b/src/com/android/camera/one/OneCamera.java
index 1f2cb66..07c3689 100644
--- a/src/com/android/camera/one/OneCamera.java
+++ b/src/com/android/camera/one/OneCamera.java
@@ -16,7 +16,7 @@
 
 package com.android.camera.one;
 
-import android.content.Context;
+import android.app.Activity;
 import android.location.Location;
 import android.net.Uri;
 import android.view.Surface;
@@ -428,9 +428,9 @@
      *            might choose not to obey these and therefore the returned
      *            preview size might not match the aspect ratio of the given
      *            size.
-     * @param context the android application context
+     * @param context the android activity context
      * @return The preview size that best matches the picture aspect ratio that
      *         will be taken.
      */
-    public Size pickPreviewSize(Size pictureSize, Context context);
+    public Size pickPreviewSize(Size pictureSize, Activity context);
 }
diff --git a/src/com/android/camera/one/v2/OneCameraImpl.java b/src/com/android/camera/one/v2/OneCameraImpl.java
index 8f0ffef..d9c6b03 100644
--- a/src/com/android/camera/one/v2/OneCameraImpl.java
+++ b/src/com/android/camera/one/v2/OneCameraImpl.java
@@ -17,7 +17,7 @@
 package com.android.camera.one.v2;
 
 import android.annotation.TargetApi;
-import android.content.Context;
+import android.app.Activity;
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
@@ -719,7 +719,7 @@
     }
 
     @Override
-    public Size pickPreviewSize(Size pictureSize, Context context) {
+    public Size pickPreviewSize(Size pictureSize, Activity context) {
         if (pictureSize == null) {
             // TODO The default should be selected by the caller, and
             // pictureSize should never be null.
@@ -732,7 +732,7 @@
         // flexible for selecting a matching preview resolution.
         Double aspectRatioTolerance = sCaptureImageFormat == ImageFormat.RAW_SENSOR ? 10d : null;
         Size size = CaptureModuleUtil.getOptimalPreviewSize(supportedSizes,
-                pictureAspectRatio, aspectRatioTolerance);
+                pictureAspectRatio, aspectRatioTolerance, context);
         Log.d(TAG, "Selected preview size: " + size);
         return size;
     }
diff --git a/src/com/android/camera/one/v2/OneCameraZslImpl.java b/src/com/android/camera/one/v2/OneCameraZslImpl.java
index a35a6c1..636f3f5 100644
--- a/src/com/android/camera/one/v2/OneCameraZslImpl.java
+++ b/src/com/android/camera/one/v2/OneCameraZslImpl.java
@@ -15,7 +15,7 @@
 package com.android.camera.one.v2;
 
 import android.annotation.TargetApi;
-import android.content.Context;
+import android.app.Activity;
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
 import android.hardware.camera2.CameraAccessException;
@@ -1090,7 +1090,7 @@
     }
 
     @Override
-    public Size pickPreviewSize(Size pictureSize, Context context) {
+    public Size pickPreviewSize(Size pictureSize, Activity context) {
         if (pictureSize == null) {
             // TODO The default should be selected by the caller, and
             // pictureSize should never be null.
@@ -1098,7 +1098,7 @@
         }
         float pictureAspectRatio = pictureSize.getWidth() / (float) pictureSize.getHeight();
         return CaptureModuleUtil.getOptimalPreviewSize(getSupportedPreviewSizes(),
-              pictureAspectRatio);
+              pictureAspectRatio, context);
     }
 
     @Override
diff --git a/src/com/android/camera/one/v2/autofocus/ManualAutoFocusFactory.java b/src/com/android/camera/one/v2/autofocus/ManualAutoFocusFactory.java
index 1681ddb..690058a 100644
--- a/src/com/android/camera/one/v2/autofocus/ManualAutoFocusFactory.java
+++ b/src/com/android/camera/one/v2/autofocus/ManualAutoFocusFactory.java
@@ -27,6 +27,7 @@
 import com.android.camera.one.v2.commands.CameraCommand;
 import com.android.camera.one.v2.commands.CameraCommandExecutor;
 import com.android.camera.one.v2.commands.ResettingRunnableCameraCommand;
+import com.android.camera.one.v2.commands.UpdateRequestCommand;
 import com.android.camera.one.v2.core.FrameServer;
 import com.android.camera.one.v2.core.RequestBuilder;
 import com.android.camera.one.v2.core.RequestTemplate;
@@ -65,6 +66,8 @@
      * @param threadPool The executor on which to schedule delayed tasks.
      * @param afHoldSeconds The number of seconds to hold AF after a manual AF
      *            sweep is triggered.
+     * @param aeSupport Camera device supports AE metering regions
+     * @param afSupport Camera device supports AF and AF metering regions
      */
     public static ManualAutoFocusFactory create(Lifetime lifetime, FrameServer frameServer,
             CameraCommandExecutor commandExecutor, Supplier<Rect> cropRegion,
@@ -72,7 +75,7 @@
             Runnable previewRunner, RequestBuilder.Factory rootBuilder,
             int templateType, Settings3A settings3A,
             ScheduledExecutorService threadPool,
-            int afHoldSeconds) {
+            int afHoldSeconds, boolean aeSupport, boolean afSupport) {
         ConcurrentState<MeteringParameters> currentMeteringParameters = new ConcurrentState<>(
                 GlobalMeteringParameters.create());
         AEMeteringRegion aeMeteringRegion = new AEMeteringRegion(currentMeteringParameters,
@@ -81,17 +84,27 @@
                 cropRegion);
 
         RequestTemplate afScanRequestBuilder = new RequestTemplate(rootBuilder);
-        afScanRequestBuilder.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeMeteringRegion);
-        afScanRequestBuilder.setParam(CaptureRequest.CONTROL_AF_REGIONS, afMeteringRegion);
+        if (aeSupport) {
+            afScanRequestBuilder.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeMeteringRegion);
+        }
+        if (afSupport) {
+            afScanRequestBuilder.setParam(CaptureRequest.CONTROL_AF_REGIONS, afMeteringRegion);
+        }
 
-        CameraCommand afScanCommand = new FullAFScanCommand(frameServer, afScanRequestBuilder,
-                templateType);
+        CameraCommand initialCommand;
+        if (afSupport) {
+            initialCommand  = new FullAFScanCommand(frameServer, afScanRequestBuilder,
+                    templateType);
+        } else {
+            initialCommand  = new UpdateRequestCommand(frameServer, afScanRequestBuilder,
+                    templateType);
+        }
 
         ResettingDelayedExecutor afHoldDelayedExecutor = new ResettingDelayedExecutor(
                 threadPool, afHoldSeconds, TimeUnit.SECONDS);
         lifetime.add(afHoldDelayedExecutor);
 
-        CameraCommand afScanHoldResetCommand = new AFScanHoldResetCommand(afScanCommand,
+        CameraCommand afScanHoldResetCommand = new AFScanHoldResetCommand(initialCommand,
                 afHoldDelayedExecutor, previewRunner, currentMeteringParameters);
 
         Runnable afRunner = new ResettingRunnableCameraCommand(commandExecutor,
diff --git a/src/com/android/camera/one/v2/commands/UpdateRequestCommand.java b/src/com/android/camera/one/v2/commands/UpdateRequestCommand.java
new file mode 100644
index 0000000..9c15248
--- /dev/null
+++ b/src/com/android/camera/one/v2/commands/UpdateRequestCommand.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 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.commands;
+
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CaptureRequest;
+
+import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionClosedException;
+import com.android.camera.one.v2.commands.CameraCommand;
+import com.android.camera.one.v2.core.FrameServer;
+import com.android.camera.one.v2.core.RequestBuilder;
+import com.android.camera.one.v2.core.ResourceAcquisitionFailedException;
+
+import java.util.Arrays;
+
+import javax.annotation.Nullable;
+import javax.annotation.ParametersAreNonnullByDefault;
+
+/**
+ * Update repeating request.
+ */
+@ParametersAreNonnullByDefault
+public final class UpdateRequestCommand implements CameraCommand {
+    private final FrameServer mFrameServer;
+    private final RequestBuilder.Factory mBuilderFactory;
+    private final int mTemplateType;
+
+    /**
+     * @param frameServer Used for sending requests to the camera.
+     * @param builder Used for building requests.
+     * @param templateType See
+     *            {@link android.hardware.camera2.CameraDevice#createCaptureRequest}
+     */
+    public UpdateRequestCommand(FrameServer frameServer, RequestBuilder.Factory builder, int
+            templateType) {
+        mFrameServer = frameServer;
+        mBuilderFactory = builder;
+        mTemplateType = templateType;
+    }
+
+    /**
+     * Update repeating request.
+     */
+    @Override
+    public void run() throws InterruptedException, CameraAccessException,
+            CameraCaptureSessionClosedException, ResourceAcquisitionFailedException {
+        FrameServer.Session session = mFrameServer.tryCreateExclusiveSession();
+        if (session == null) {
+            // If there are already other commands interacting with the
+            // FrameServer just abort.
+            return;
+        }
+
+        try {
+            RequestBuilder builder = mBuilderFactory.create(mTemplateType);
+            session.submitRequest(Arrays.asList(builder.build()),
+                    FrameServer.RequestType.REPEATING);
+        } finally {
+            session.close();
+        }
+    }
+}
diff --git a/src/com/android/camera/one/v2/common/BasicCameraFactory.java b/src/com/android/camera/one/v2/common/BasicCameraFactory.java
index 44883ea..c42f447 100644
--- a/src/com/android/camera/one/v2/common/BasicCameraFactory.java
+++ b/src/com/android/camera/one/v2/common/BasicCameraFactory.java
@@ -148,7 +148,8 @@
                 Lifetime(lifetime), frameServer, cameraCommandExecutor, cropRegion,
                 sensorOrientation, mPreviewUpdater, requestTemplate,
                 templateType, new Settings3A(), Executors.newScheduledThreadPool(1),
-                3 /* afHoldSeconds */);
+                3 /* afHoldSeconds */, cameraCharacteristics.isAutoExposureSupported(),
+                cameraCharacteristics.isAutoFocusSupported());
         mManualAutoFocus = manualAutoFocusFactory.provideManualAutoFocus();
         Supplier<MeteringRectangle[]> aeRegions =
                 manualAutoFocusFactory.provideAEMeteringRegion();
diff --git a/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java b/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java
index 472378f..da66d6f 100644
--- a/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java
+++ b/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java
@@ -16,7 +16,7 @@
 
 package com.android.camera.one.v2.initialization;
 
-import android.content.Context;
+import android.app.Activity;
 import android.view.Surface;
 
 import com.android.camera.async.FilteredCallback;
@@ -184,7 +184,7 @@
     }
 
     @Override
-    public Size pickPreviewSize(Size pictureSize, Context context) {
+    public Size pickPreviewSize(Size pictureSize, Activity context) {
         return mPreviewSizeSelector.pickPreviewSize(pictureSize);
     }
 }
diff --git a/src/com/android/camera/settings/ResolutionUtil.java b/src/com/android/camera/settings/ResolutionUtil.java
index 632bce0..14d1d75 100644
--- a/src/com/android/camera/settings/ResolutionUtil.java
+++ b/src/com/android/camera/settings/ResolutionUtil.java
@@ -16,8 +16,10 @@
 
 package com.android.camera.settings;
 
+import android.app.Activity;
 import android.content.Context;
 import android.util.DisplayMetrics;
+import android.view.Display;
 import android.view.WindowManager;
 
 import com.android.camera.exif.Rational;
@@ -405,11 +407,11 @@
         return maxSize;
     }
 
-    public static DisplayMetrics getDisplayMetrics(Context context) {
+    public static DisplayMetrics getDisplayMetrics(Activity context) {
         DisplayMetrics displayMetrics = new DisplayMetrics();
-        WindowManager wm = AndroidServices.instance().provideWindowManager();
-        if (wm != null) {
-            wm.getDefaultDisplay().getMetrics(displayMetrics);
+        Display d = context.getDisplay();
+        if (d != null) {
+            d.getMetrics(displayMetrics);
         }
         return displayMetrics;
     }
diff --git a/src/com/android/camera/ui/MainActivityLayout.java b/src/com/android/camera/ui/MainActivityLayout.java
index 39d2b58..98f7089 100644
--- a/src/com/android/camera/ui/MainActivityLayout.java
+++ b/src/com/android/camera/ui/MainActivityLayout.java
@@ -150,7 +150,7 @@
         if (mNonDecorWindowSizeChangedListener != null) {
             mNonDecorWindowSizeChangedListener.onNonDecorWindowSizeChanged(
                     MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec),
-                    CameraUtil.getDisplayRotation());
+                    CameraUtil.getDisplayRotation((Activity) getContext()));
         }
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }
@@ -166,7 +166,7 @@
         if (mNonDecorWindowSizeChangedListener != null) {
             mNonDecorWindowSizeChangedListener.onNonDecorWindowSizeChanged(
                     getMeasuredWidth(), getMeasuredHeight(),
-                    CameraUtil.getDisplayRotation());
+                    CameraUtil.getDisplayRotation((Activity) getContext()));
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/camera/util/AndroidServices.java b/src/com/android/camera/util/AndroidServices.java
index 0b0b981..70c35e8 100644
--- a/src/com/android/camera/util/AndroidServices.java
+++ b/src/com/android/camera/util/AndroidServices.java
@@ -17,6 +17,7 @@
 package com.android.camera.util;
 
 import android.annotation.TargetApi;
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.app.NotificationManager;
@@ -126,14 +127,21 @@
         return (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
     }
 
-    public WindowManager provideWindowManager() {
-        return (WindowManager) getSystemService(Context.WINDOW_SERVICE);
+    public WindowManager provideWindowManager(Activity context) {
+        return (WindowManager) getSystemService(Context.WINDOW_SERVICE, context);
     }
 
     private Object getSystemService(String service) {
+        return getSystemService(service, null);
+    }
+
+    private Object getSystemService(String service, Context targetContext) {
         try {
             long start = System.currentTimeMillis();
-            Object result = mContext.getSystemService(service);
+            if (targetContext == null) targetContext = mContext;
+
+            Object result = targetContext.getSystemService(service);
+
             long duration = System.currentTimeMillis() - start;
             if (duration > LOG_THRESHOLD_MILLIS) {
                 Log.w(TAG, "Warning: providing system service " + service + " took " +
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index 639e635..b6e11b8 100644
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -450,8 +450,8 @@
         return new Size((int) width, (int) height);
     }
 
-    public static int getDisplayRotation() {
-        WindowManager windowManager = AndroidServices.instance().provideWindowManager();
+    public static int getDisplayRotation(Activity context) {
+        WindowManager windowManager = AndroidServices.instance().provideWindowManager(context);
         int rotation = windowManager.getDefaultDisplay()
                 .getRotation();
         switch (rotation) {
@@ -467,15 +467,16 @@
         return 0;
     }
 
-    private static Size getDefaultDisplaySize() {
-        WindowManager windowManager = AndroidServices.instance().provideWindowManager();
+    private static Size getDefaultDisplaySize(Activity context) {
+        WindowManager windowManager = AndroidServices.instance().provideWindowManager(context);
         Point res = new Point();
         windowManager.getDefaultDisplay().getSize(res);
         return new Size(res);
     }
 
-    public static Size getOptimalPreviewSize(List<Size> sizes, double targetRatio) {
-        int optimalPickIndex = getOptimalPreviewSizeIndex(sizes, targetRatio);
+    public static Size getOptimalPreviewSize(List<Size> sizes, double targetRatio,
+            Activity context) {
+        int optimalPickIndex = getOptimalPreviewSizeIndex(sizes, targetRatio, context);
         if (optimalPickIndex == -1) {
             return null;
         } else {
@@ -494,16 +495,18 @@
      * @param sizes the available preview sizes
      * @param targetRatio the target aspect ratio, typically the aspect ratio of
      *            the picture size
+     * @param context the Activity to use for determining display information
      * @return The index into 'previewSizes' for the optimal size, or -1, if no
      *         matching size was found.
      */
-    public static int getOptimalPreviewSizeIndex(List<Size> sizes, double targetRatio) {
+    public static int getOptimalPreviewSizeIndex(List<Size> sizes, double targetRatio,
+            Activity context) {
         // Use a very small tolerance because we want an exact match. HTC 4:3
         // ratios is over .01 from true 4:3, so this value must be above .01,
         // see b/18241645.
         final double aspectRatioTolerance = 0.02;
 
-        return getOptimalPreviewSizeIndex(sizes, targetRatio, aspectRatioTolerance);
+        return getOptimalPreviewSizeIndex(sizes, targetRatio, aspectRatioTolerance, context);
     }
 
     /**
@@ -516,11 +519,13 @@
      * @param aspectRatioTolerance the tolerance we allow between the selected
      *            preview size's aspect ratio and the target ratio. If this is
      *            set to 'null', the default value is used.
+     * @param context the Activity to use for determining display information
      * @return The index into 'previewSizes' for the optimal size, or -1, if no
      *         matching size was found.
      */
     public static int getOptimalPreviewSizeIndex(
-            List<Size> previewSizes, double targetRatio, Double aspectRatioTolerance) {
+            List<Size> previewSizes, double targetRatio, Double aspectRatioTolerance,
+            Activity context) {
         if (previewSizes == null) {
             return -1;
         }
@@ -528,7 +533,7 @@
         // If no particular aspect ratio tolerance is set, use the default
         // value.
         if (aspectRatioTolerance == null) {
-            return getOptimalPreviewSizeIndex(previewSizes, targetRatio);
+            return getOptimalPreviewSizeIndex(previewSizes, targetRatio, context);
         }
 
         int optimalSizeIndex = -1;
@@ -539,7 +544,7 @@
         // wrong size of preview surface. When we change the preview size, the
         // new overlay will be created before the old one closed, which causes
         // an exception. For now, just get the screen size.
-        Size defaultDisplaySize = getDefaultDisplaySize();
+        Size defaultDisplaySize = getDefaultDisplaySize(context);
         int targetHeight = Math.min(defaultDisplaySize.getWidth(), defaultDisplaySize.getHeight());
         // Try to find an size match aspect ratio and size
         for (int i = 0; i < previewSizes.size(); i++) {