1a0842b40441db5332a5290f941021636b1182761Sol Boucher/* 2a0842b40441db5332a5290f941021636b1182761Sol Boucher * Copyright (C) 2014 The Android Open Source Project 3a0842b40441db5332a5290f941021636b1182761Sol Boucher * 4a0842b40441db5332a5290f941021636b1182761Sol Boucher * Licensed under the Apache License, Version 2.0 (the "License"); 5a0842b40441db5332a5290f941021636b1182761Sol Boucher * you may not use this file except in compliance with the License. 6a0842b40441db5332a5290f941021636b1182761Sol Boucher * You may obtain a copy of the License at 7a0842b40441db5332a5290f941021636b1182761Sol Boucher * 8a0842b40441db5332a5290f941021636b1182761Sol Boucher * http://www.apache.org/licenses/LICENSE-2.0 9a0842b40441db5332a5290f941021636b1182761Sol Boucher * 10a0842b40441db5332a5290f941021636b1182761Sol Boucher * Unless required by applicable law or agreed to in writing, software 11a0842b40441db5332a5290f941021636b1182761Sol Boucher * distributed under the License is distributed on an "AS IS" BASIS, 12a0842b40441db5332a5290f941021636b1182761Sol Boucher * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a0842b40441db5332a5290f941021636b1182761Sol Boucher * See the License for the specific language governing permissions and 14a0842b40441db5332a5290f941021636b1182761Sol Boucher * limitations under the License. 15a0842b40441db5332a5290f941021636b1182761Sol Boucher */ 16a0842b40441db5332a5290f941021636b1182761Sol Boucher 17a0842b40441db5332a5290f941021636b1182761Sol Boucherpackage com.android.ex.camera2.portability; 18a0842b40441db5332a5290f941021636b1182761Sol Boucher 19de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport static android.hardware.camera2.CaptureRequest.*; 20de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 212569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucherimport android.graphics.Matrix; 22de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport android.graphics.Rect; 232569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucherimport android.graphics.RectF; 24de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport android.hardware.camera2.CameraAccessException; 25de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport android.hardware.camera2.CameraDevice; 26de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport android.hardware.camera2.params.MeteringRectangle; 27d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucherimport android.location.Location; 28de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport android.util.Range; 29de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 30de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport com.android.ex.camera2.portability.CameraCapabilities.FlashMode; 31de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport com.android.ex.camera2.portability.CameraCapabilities.FocusMode; 32de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport com.android.ex.camera2.portability.CameraCapabilities.SceneMode; 33de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport com.android.ex.camera2.portability.CameraCapabilities.WhiteBalance; 34de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport com.android.ex.camera2.portability.debug.Log; 35de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport com.android.ex.camera2.utils.Camera2RequestSettingsSet; 36de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 37de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport java.util.List; 38de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucherimport java.util.Objects; 39a0842b40441db5332a5290f941021636b1182761Sol Boucher 40a0842b40441db5332a5290f941021636b1182761Sol Boucher/** 41a0842b40441db5332a5290f941021636b1182761Sol Boucher * The subclass of {@link CameraSettings} for Android Camera 2 API. 42a0842b40441db5332a5290f941021636b1182761Sol Boucher */ 43a0842b40441db5332a5290f941021636b1182761Sol Boucherpublic class AndroidCamera2Settings extends CameraSettings { 44de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private static final Log.Tag TAG = new Log.Tag("AndCam2Set"); 45de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 46de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private final Builder mTemplateSettings; 47de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private final Camera2RequestSettingsSet mRequestSettings; 482569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher /** Sensor's active array bounds. */ 499d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher private final Rect mActiveArray; 502569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher /** Crop rectangle for digital zoom (measured WRT the active array). */ 519d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher private final Rect mCropRectangle; 522569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher /** Bounds of visible preview portion (measured WRT the active array). */ 532569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher private Rect mVisiblePreviewRectangle; 54de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 55de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher /** 56de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * Create a settings representation that answers queries of unspecified 57de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * options in the same way as the provided template would. 58de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * 59de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * <p>The default settings provided by the given template are only ever used 60de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * for reporting back to the client app (i.e. when it queries an option 61de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * it didn't explicitly set first). {@link Camera2RequestSettingsSet}s 62de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * generated by an instance of this class will have any settings not 63de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * modified using one of that instance's mutators forced to default, so that 64de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * their effective values when submitting a capture request will be those of 65de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * the template that is provided to the camera framework at that time.</p> 66de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * 679d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @param camera Device from which to draw default settings 689d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * (non-{@code null}). 69de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * @param template Specific template to use for the defaults. 709d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @param activeArray Boundary coordinates of the sensor's active array 719d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * (non-{@code null}). 72de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * @param preview Dimensions of preview streams. 73de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * @param photo Dimensions of captured images. 74de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * 759d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * @throws IllegalArgumentException If {@code camera} or {@code activeArray} 769d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher * is {@code null}. 77de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher * @throws CameraAccessException Upon internal framework/driver failure. 78de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher */ 79de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher public AndroidCamera2Settings(CameraDevice camera, int template, Rect activeArray, 80de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Size preview, Size photo) throws CameraAccessException { 819d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher if (camera == null) { 829d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher throw new NullPointerException("camera must not be null"); 839d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 849d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher if (activeArray == null) { 859d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher throw new NullPointerException("activeArray must not be null"); 869d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 879d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher 88de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mTemplateSettings = camera.createCaptureRequest(template); 89de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings = new Camera2RequestSettingsSet(); 909d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mActiveArray = activeArray; 919d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCropRectangle = new Rect(0, 0, activeArray.width(), activeArray.height()); 92de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 932569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher mSizesLocked = false; 942569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 95de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Range<Integer> previewFpsRange = mTemplateSettings.get(CONTROL_AE_TARGET_FPS_RANGE); 96de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (previewFpsRange != null) { 97de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher setPreviewFpsRange(previewFpsRange.getLower(), previewFpsRange.getUpper()); 98de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 99a0842b40441db5332a5290f941021636b1182761Sol Boucher setPreviewSize(preview); 100de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mCurrentPreviewFormat 101a0842b40441db5332a5290f941021636b1182761Sol Boucher setPhotoSize(photo); 102de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mJpegCompressQuality = queryTemplateDefaultOrMakeOneUp(JPEG_QUALITY, (byte) 0); 103de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mCurrentPhotoFormat 1049d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher // NB: We're assuming that templates won't be zoomed in by default. 1059d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCurrentZoomRatio = CameraCapabilities.ZOOM_RATIO_UNZOOMED; 106de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mCurrentZoomIndex 107de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mExposureCompensationIndex = 108de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher queryTemplateDefaultOrMakeOneUp(CONTROL_AE_EXPOSURE_COMPENSATION, 0); 109bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher 110de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mCurrentFlashMode = flashModeFromRequest(); 111bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher Integer currentFocusMode = mTemplateSettings.get(CONTROL_AF_MODE); 112bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher if (currentFocusMode != null) { 113bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher mCurrentFocusMode = AndroidCamera2Capabilities.focusModeFromInt(currentFocusMode); 114bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher } 115bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher Integer currentSceneMode = mTemplateSettings.get(CONTROL_SCENE_MODE); 116bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher if (currentSceneMode != null) { 117bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher mCurrentSceneMode = AndroidCamera2Capabilities.sceneModeFromInt(currentSceneMode); 118bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher } 119bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher Integer whiteBalance = mTemplateSettings.get(CONTROL_AWB_MODE); 120bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher if (whiteBalance != null) { 121bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher mWhiteBalance = AndroidCamera2Capabilities.whiteBalanceFromInt(whiteBalance); 122bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher } 123bc9c0e2cb071b085ecc5646751fb59f5145d51b1Sol Boucher 124de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mVideoStabilizationEnabled = queryTemplateDefaultOrMakeOneUp( 125de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher CONTROL_VIDEO_STABILIZATION_MODE, CONTROL_VIDEO_STABILIZATION_MODE_OFF) == 126de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher CONTROL_VIDEO_STABILIZATION_MODE_ON; 127de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mAutoExposureLocked = queryTemplateDefaultOrMakeOneUp(CONTROL_AE_LOCK, false); 128de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mAutoWhiteBalanceLocked = queryTemplateDefaultOrMakeOneUp(CONTROL_AWB_LOCK, false); 129de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mRecordingHintEnabled 130de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mGpsData 131de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher android.util.Size exifThumbnailSize = mTemplateSettings.get(JPEG_THUMBNAIL_SIZE); 132de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (exifThumbnailSize != null) { 133de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mExifThumbnailSize = 134de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher new Size(exifThumbnailSize.getWidth(), exifThumbnailSize.getHeight()); 135de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 136de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 137de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 138de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher public AndroidCamera2Settings(AndroidCamera2Settings other) { 139de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher super(other); 140de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mTemplateSettings = other.mTemplateSettings; 141de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings = new Camera2RequestSettingsSet(other.mRequestSettings); 1429d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mActiveArray = other.mActiveArray; 1439d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCropRectangle = new Rect(other.mCropRectangle); 144de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 145de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 146de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher @Override 147de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher public CameraSettings copy() { 148de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return new AndroidCamera2Settings(this); 149de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 150de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 151de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private <T> T queryTemplateDefaultOrMakeOneUp(Key<T> key, T defaultDefault) { 152de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher T val = mTemplateSettings.get(key); 153de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (val != null) { 154de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return val; 155de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else { 156de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // Spoof the default so matchesTemplateDefault excludes this key from generated sets. 157de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // This approach beats a simple sentinel because it provides basic boolean support. 158de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mTemplateSettings.set(key, defaultDefault); 159de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return defaultDefault; 160de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 161de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 162de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 163de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private FlashMode flashModeFromRequest() { 164de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Integer autoExposure = mTemplateSettings.get(CONTROL_AE_MODE); 165de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (autoExposure != null) { 166de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher switch (autoExposure) { 167de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case CONTROL_AE_MODE_ON: 168de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return FlashMode.OFF; 169de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case CONTROL_AE_MODE_ON_AUTO_FLASH: 170de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return FlashMode.AUTO; 171de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case CONTROL_AE_MODE_ON_ALWAYS_FLASH: { 172de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (mTemplateSettings.get(FLASH_MODE) == FLASH_MODE_TORCH) { 173de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return FlashMode.TORCH; 174de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else { 175de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return FlashMode.ON; 176de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 177de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 178de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE: 179de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return FlashMode.RED_EYE; 180de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 181de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 182de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return null; 183de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 184de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 1859d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher @Override 1869d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher public void setZoomRatio(float ratio) { 1879d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher super.setZoomRatio(ratio); 1882569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 1892569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // Compute the crop rectangle to be passed to the framework 1909d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCropRectangle.set(0, 0, 1919d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher toIntConstrained( 1929d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mActiveArray.width() / mCurrentZoomRatio, 0, mActiveArray.width()), 1939d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher toIntConstrained( 1949d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mActiveArray.height() / mCurrentZoomRatio, 0, mActiveArray.height())); 1959d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCropRectangle.offsetTo((mActiveArray.width() - mCropRectangle.width()) / 2, 1969d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher (mActiveArray.height() - mCropRectangle.height()) / 2); 1972569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 1982569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // Compute the effective crop rectangle to be used for computing focus/metering coordinates 1992569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher mVisiblePreviewRectangle = 2002569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher effectiveCropRectFromRequested(mCropRectangle, mCurrentPreviewSize); 2019d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher } 2029d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher 203de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private boolean matchesTemplateDefault(Key<?> setting) { 204de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (setting == CONTROL_AE_REGIONS) { 205de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return mMeteringAreas.size() == 0; 206de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else if (setting == CONTROL_AF_REGIONS) { 207de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return mFocusAreas.size() == 0; 208de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else if (setting == CONTROL_AE_TARGET_FPS_RANGE) { 209dc05ed7a8443af7c1a7b1bb39519d09d79284e42Igor Murashkin Range<Integer> defaultFpsRange = mTemplateSettings.get(CONTROL_AE_TARGET_FPS_RANGE); 210de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return (mPreviewFpsRangeMin == 0 && mPreviewFpsRangeMax == 0) || 211de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher (defaultFpsRange != null && mPreviewFpsRangeMin == defaultFpsRange.getLower() && 212de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mPreviewFpsRangeMax == defaultFpsRange.getUpper()); 213de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else if (setting == JPEG_QUALITY) { 214de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return Objects.equals(mJpegCompressQuality, 215de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mTemplateSettings.get(JPEG_QUALITY)); 216de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else if (setting == CONTROL_AE_EXPOSURE_COMPENSATION) { 217de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return Objects.equals(mExposureCompensationIndex, 218de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mTemplateSettings.get(CONTROL_AE_EXPOSURE_COMPENSATION)); 219de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else if (setting == CONTROL_VIDEO_STABILIZATION_MODE) { 220de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Integer videoStabilization = mTemplateSettings.get(CONTROL_VIDEO_STABILIZATION_MODE); 221de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return (videoStabilization != null && 222de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher (mVideoStabilizationEnabled && videoStabilization == 223de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher CONTROL_VIDEO_STABILIZATION_MODE_ON) || 224de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher (!mVideoStabilizationEnabled && videoStabilization == 225de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher CONTROL_VIDEO_STABILIZATION_MODE_OFF)); 226de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else if (setting == CONTROL_AE_LOCK) { 227de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return Objects.equals(mAutoExposureLocked, mTemplateSettings.get(CONTROL_AE_LOCK)); 228de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else if (setting == CONTROL_AWB_LOCK) { 229de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return Objects.equals(mAutoWhiteBalanceLocked, mTemplateSettings.get(CONTROL_AWB_LOCK)); 230de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } else if (setting == JPEG_THUMBNAIL_SIZE) { 231698997b9ef47f215350f03c0289f291846cd3604Puneet Lall if (mExifThumbnailSize == null) { 232698997b9ef47f215350f03c0289f291846cd3604Puneet Lall // It doesn't matter if this is true or false since setting this 233698997b9ef47f215350f03c0289f291846cd3604Puneet Lall // to null in the request settings will use the default anyway. 234698997b9ef47f215350f03c0289f291846cd3604Puneet Lall return false; 235698997b9ef47f215350f03c0289f291846cd3604Puneet Lall } 236de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher android.util.Size defaultThumbnailSize = mTemplateSettings.get(JPEG_THUMBNAIL_SIZE); 237de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return (mExifThumbnailSize.width() == 0 && mExifThumbnailSize.height() == 0) || 238de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher (defaultThumbnailSize != null && 239de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mExifThumbnailSize.width() == defaultThumbnailSize.getWidth() && 240de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mExifThumbnailSize.height() == defaultThumbnailSize.getHeight()); 241de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 242de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Log.w(TAG, "Settings implementation checked default of unhandled option key"); 243de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // Since this class isn't equipped to handle it, claim it matches the default to prevent 244de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // updateRequestSettingOrForceToDefault from going with the user-provided preference 245de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return true; 246de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 247de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 248de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private <T> void updateRequestSettingOrForceToDefault(Key<T> setting, T possibleChoice) { 249de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings.set(setting, matchesTemplateDefault(setting) ? null : possibleChoice); 250de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 251de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 252de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher public Camera2RequestSettingsSet getRequestSettings() { 253de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSettingOrForceToDefault(CONTROL_AE_REGIONS, 254de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher legacyAreasToMeteringRectangles(mMeteringAreas)); 255de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSettingOrForceToDefault(CONTROL_AF_REGIONS, 256de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher legacyAreasToMeteringRectangles(mFocusAreas)); 257de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSettingOrForceToDefault(CONTROL_AE_TARGET_FPS_RANGE, 258de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher new Range(mPreviewFpsRangeMin, mPreviewFpsRangeMax)); 259de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mCurrentPreviewFormat 260de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSettingOrForceToDefault(JPEG_QUALITY, mJpegCompressQuality); 261de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mCurrentPhotoFormat 2629d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mRequestSettings.set(SCALER_CROP_REGION, mCropRectangle); 263de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mCurrentZoomIndex 264de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSettingOrForceToDefault(CONTROL_AE_EXPOSURE_COMPENSATION, 265de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mExposureCompensationIndex); 266de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestFlashMode(); 267de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestFocusMode(); 268de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSceneMode(); 269de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestWhiteBalance(); 270de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSettingOrForceToDefault(CONTROL_VIDEO_STABILIZATION_MODE, 271de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mVideoStabilizationEnabled ? 272de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher CONTROL_VIDEO_STABILIZATION_MODE_ON : CONTROL_VIDEO_STABILIZATION_MODE_OFF); 273de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // OIS shouldn't be on if software video stabilization is. 274de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings.set(LENS_OPTICAL_STABILIZATION_MODE, 275de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mVideoStabilizationEnabled ? LENS_OPTICAL_STABILIZATION_MODE_OFF : 276de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher null); 277de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSettingOrForceToDefault(CONTROL_AE_LOCK, mAutoExposureLocked); 278de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher updateRequestSettingOrForceToDefault(CONTROL_AWB_LOCK, mAutoWhiteBalanceLocked); 279de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: mRecordingHintEnabled 280d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher updateRequestGpsData(); 281698997b9ef47f215350f03c0289f291846cd3604Puneet Lall if (mExifThumbnailSize != null) { 282698997b9ef47f215350f03c0289f291846cd3604Puneet Lall updateRequestSettingOrForceToDefault(JPEG_THUMBNAIL_SIZE, 283698997b9ef47f215350f03c0289f291846cd3604Puneet Lall new android.util.Size( 284698997b9ef47f215350f03c0289f291846cd3604Puneet Lall mExifThumbnailSize.width(), mExifThumbnailSize.height())); 285698997b9ef47f215350f03c0289f291846cd3604Puneet Lall } else { 286698997b9ef47f215350f03c0289f291846cd3604Puneet Lall updateRequestSettingOrForceToDefault(JPEG_THUMBNAIL_SIZE, null); 287698997b9ef47f215350f03c0289f291846cd3604Puneet Lall } 288de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 289de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return mRequestSettings; 290de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 291de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 292de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private MeteringRectangle[] legacyAreasToMeteringRectangles( 293de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher List<android.hardware.Camera.Area> reference) { 294de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher MeteringRectangle[] transformed = null; 295de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (reference.size() > 0) { 296de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher transformed = new MeteringRectangle[reference.size()]; 297de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher for (int index = 0; index < reference.size(); ++index) { 298de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher android.hardware.Camera.Area source = reference.get(index); 299de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Rect rectangle = source.rect; 300de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 301de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // Old API coordinates were [-1000,1000]; new ones are [0,ACTIVE_ARRAY_SIZE). 3029d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher // We're also going from preview image--relative to sensor active array--relative. 303de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher double oldLeft = (rectangle.left + 1000) / 2000.0; 304de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher double oldTop = (rectangle.top + 1000) / 2000.0; 305de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher double oldRight = (rectangle.right + 1000) / 2000.0; 306de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher double oldBottom = (rectangle.bottom + 1000) / 2000.0; 3079d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher int left = mCropRectangle.left + toIntConstrained( 3089d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCropRectangle.width() * oldLeft, 0, mCropRectangle.width() - 1); 3099d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher int top = mCropRectangle.top + toIntConstrained( 3109d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCropRectangle.height() * oldTop, 0, mCropRectangle.height() - 1); 3119d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher int right = mCropRectangle.left + toIntConstrained( 3129d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCropRectangle.width() * oldRight, 0, mCropRectangle.width() - 1); 3139d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher int bottom = mCropRectangle.top + toIntConstrained( 3149d8668449376fa47bc6528c7a61b04d6a0f691b3Sol Boucher mCropRectangle.height() * oldBottom, 0, mCropRectangle.height() - 1); 315de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher transformed[index] = new MeteringRectangle(left, top, right - left, bottom - top, 316de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher source.weight); 317de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 318de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 319de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return transformed; 320de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 321de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 322de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private int toIntConstrained(double original, int min, int max) { 323de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher original = Math.max(original, min); 324de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher original = Math.min(original, max); 325de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher return (int) original; 326de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 327de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 328de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private void updateRequestFlashMode() { 329de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Integer aeMode = null; 330de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Integer flashMode = null; 331de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (mCurrentFlashMode != null) { 332de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher switch (mCurrentFlashMode) { 333de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case AUTO: { 334de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher aeMode = CONTROL_AE_MODE_ON_AUTO_FLASH; 335de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 336de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 337de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case OFF: { 338de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher aeMode = CONTROL_AE_MODE_ON; 339de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher flashMode = FLASH_MODE_OFF; 340de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 341de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 342de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case ON: { 343de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher aeMode = CONTROL_AE_MODE_ON_ALWAYS_FLASH; 344de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher flashMode = FLASH_MODE_SINGLE; 345de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 346de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 347de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case TORCH: { 348de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher flashMode = FLASH_MODE_TORCH; 349de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 350de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 351de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case RED_EYE: { 352de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher aeMode = CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; 353de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 354de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 355de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher default: { 356de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Log.w(TAG, "Unable to convert to API 2 flash mode: " + mCurrentFlashMode); 357de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 358de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 359de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 360de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 361de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings.set(CONTROL_AE_MODE, aeMode); 362de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings.set(FLASH_MODE, flashMode); 363de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 364de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 365de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private void updateRequestFocusMode() { 366de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Integer mode = null; 367de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (mCurrentFocusMode != null) { 368de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher switch (mCurrentFocusMode) { 369de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case AUTO: { 370de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AF_MODE_AUTO; 371de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 372de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 373de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case CONTINUOUS_PICTURE: { 374de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AF_MODE_CONTINUOUS_PICTURE; 375de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 376de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 377de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case CONTINUOUS_VIDEO: { 378de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AF_MODE_CONTINUOUS_VIDEO; 379de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 380de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 381de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case EXTENDED_DOF: { 382de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AF_MODE_EDOF; 383de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 384de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 385de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case FIXED: { 386de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AF_MODE_OFF; 387de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 388de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 389de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: We cannot support INFINITY 390de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case MACRO: { 391de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AF_MODE_MACRO; 392de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 393de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 394de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher default: { 395de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Log.w(TAG, "Unable to convert to API 2 focus mode: " + mCurrentFocusMode); 396de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 397de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 398de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 399de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 400de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings.set(CONTROL_AF_MODE, mode); 401de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 402de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher 403de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private void updateRequestSceneMode() { 404de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Integer mode = null; 405de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (mCurrentSceneMode != null) { 406de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher switch (mCurrentSceneMode) { 407de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case AUTO: { 408de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_DISABLED; 409de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 410de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 411de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case ACTION: { 412de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_ACTION; 413de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 414de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 415de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case BARCODE: { 416de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_BARCODE; 417de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 418de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 419de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case BEACH: { 420de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_BEACH; 421de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 422de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 423de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case CANDLELIGHT: { 424de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_CANDLELIGHT; 425de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 426de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 427de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case FIREWORKS: { 428de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_FIREWORKS; 429de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 430de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 43154c8f898815a233ba6478630940432ddafdb4314Ruben Brunk case HDR: { 43254c8f898815a233ba6478630940432ddafdb4314Ruben Brunk mode = LegacyVendorTags.CONTROL_SCENE_MODE_HDR; 43354c8f898815a233ba6478630940432ddafdb4314Ruben Brunk break; 43454c8f898815a233ba6478630940432ddafdb4314Ruben Brunk } 435de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case LANDSCAPE: { 436de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_LANDSCAPE; 437de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 438de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 439de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case NIGHT: { 440de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_NIGHT; 441de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 442de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 443de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher // TODO: We cannot support NIGHT_PORTRAIT 444de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case PARTY: { 445de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_PARTY; 446de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 447de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 448de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case PORTRAIT: { 449de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_PORTRAIT; 450de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 451de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 452de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case SNOW: { 453de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_SNOW; 454de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 455de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 456de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case SPORTS: { 457de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_SPORTS; 458de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 459de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 460de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case STEADYPHOTO: { 461de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_STEADYPHOTO; 462de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 463de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 464de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case SUNSET: { 465de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_SUNSET; 466de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 467de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 468de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case THEATRE: { 469de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_SCENE_MODE_THEATRE; 470de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 471de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 472de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher default: { 473de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Log.w(TAG, "Unable to convert to API 2 scene mode: " + mCurrentSceneMode); 474de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 475de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 476de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 477de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 478de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings.set(CONTROL_SCENE_MODE, mode); 479de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 480a0842b40441db5332a5290f941021636b1182761Sol Boucher 481de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher private void updateRequestWhiteBalance() { 482de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Integer mode = null; 483de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher if (mWhiteBalance != null) { 484de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher switch (mWhiteBalance) { 485de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case AUTO: { 486de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AWB_MODE_AUTO; 487de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 488de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 489de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case CLOUDY_DAYLIGHT: { 490de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AWB_MODE_CLOUDY_DAYLIGHT; 491de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 492de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 493de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case DAYLIGHT: { 494de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AWB_MODE_DAYLIGHT; 495de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 496de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 497de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case FLUORESCENT: { 498de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AWB_MODE_FLUORESCENT; 499de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 500de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 501de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case INCANDESCENT: { 502de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AWB_MODE_INCANDESCENT; 503de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 504de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 505de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case SHADE: { 506de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AWB_MODE_SHADE; 507de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 508de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 509de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case TWILIGHT: { 510de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AWB_MODE_TWILIGHT; 511de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 512de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 513de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher case WARM_FLUORESCENT: { 514de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mode = CONTROL_AWB_MODE_WARM_FLUORESCENT; 515de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 516de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 517de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher default: { 518de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher Log.w(TAG, "Unable to convert to API 2 white balance: " + mWhiteBalance); 519de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher break; 520de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 521de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 522de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher } 523de48004068f8c16f9a56c60b0ed2485a67687b4bSol Boucher mRequestSettings.set(CONTROL_AWB_MODE, mode); 524a0842b40441db5332a5290f941021636b1182761Sol Boucher } 525d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher 526d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher private void updateRequestGpsData() { 527d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher if (mGpsData == null || mGpsData.processingMethod == null) { 528d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher // It's a hack since we always use GPS time stamp but does 529d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher // not use other fields sometimes. Setting processing 530d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher // method to null means the other fields should not be used. 531d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher mRequestSettings.set(JPEG_GPS_LOCATION, null); 532d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher } else { 533d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher Location location = new Location(mGpsData.processingMethod); 534d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher location.setTime(mGpsData.timeStamp); 535d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher location.setAltitude(mGpsData.altitude); 536d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher location.setLatitude(mGpsData.latitude); 537d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher location.setLongitude(mGpsData.longitude); 538d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher mRequestSettings.set(JPEG_GPS_LOCATION, location); 539d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher } 540d0185cc2f5786571565f01b26e1143ce0099bdc8Sol Boucher } 5412569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 5422569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher /** 5432569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * Calculate the effective crop rectangle for this preview viewport; 5442569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * assumes the preview is centered to the sensor and scaled to fit across one of the dimensions 5452569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * without skewing. 5462569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * 5472569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * <p>Assumes the zoom level of the provided desired crop rectangle.</p> 5482569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * 5492569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * @param requestedCrop Desired crop rectangle, in active array space. 5502569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * @param previewSize Size of the preview buffer render target, in pixels (not in sensor space). 5512569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * @return A rectangle that serves as the preview stream's effective crop region (unzoomed), in 5522569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * sensor space. 5532569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * 5542569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * @throws NullPointerException 5552569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher * If any of the args were {@code null}. 5562569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher */ 5572569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher private static Rect effectiveCropRectFromRequested(Rect requestedCrop, Size previewSize) { 5582569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher float aspectRatioArray = requestedCrop.width() * 1.0f / requestedCrop.height(); 5592569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher float aspectRatioPreview = previewSize.width() * 1.0f / previewSize.height(); 5602569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 5612569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher float cropHeight, cropWidth; 5622569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher if (aspectRatioPreview < aspectRatioArray) { 5632569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // The new width must be smaller than the height, so scale the width by AR 5642569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher cropHeight = requestedCrop.height(); 5652569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher cropWidth = cropHeight * aspectRatioPreview; 5662569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher } else { 5672569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // The new height must be smaller (or equal) than the width, so scale the height by AR 5682569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher cropWidth = requestedCrop.width(); 5692569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher cropHeight = cropWidth / aspectRatioPreview; 5702569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher } 5712569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 5722569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher Matrix translateMatrix = new Matrix(); 5732569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher RectF cropRect = new RectF(/*left*/0, /*top*/0, cropWidth, cropHeight); 5742569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 5752569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // Now center the crop rectangle so its center is in the center of the active array 5762569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher translateMatrix.setTranslate(requestedCrop.exactCenterX(), requestedCrop.exactCenterY()); 5772569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher translateMatrix.postTranslate(-cropRect.centerX(), -cropRect.centerY()); 5782569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 5792569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher translateMatrix.mapRect(/*inout*/cropRect); 5802569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher 5812569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher // Round the rect corners towards the nearest integer values 5822569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher Rect result = new Rect(); 5832569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher cropRect.roundOut(result); 5842569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher return result; 5852569329d6cff25bfe9941df539df14a0aeb4c4f4Sol Boucher } 586a0842b40441db5332a5290f941021636b1182761Sol Boucher} 587