aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-prod (mdb) <android-build-team-robot@google.com>2021-04-09 07:43:46 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-04-09 07:43:46 +0000
commita9afbafa874d82fe037dbf6680c20d84624592eb (patch)
tree8954fbf27fd069b998a925927725381b01faa383
parent17893f7667cf39bc1e94f77b6ad55cd10987594b (diff)
parent3bc7b0501ed9c52cf64e6084a4a67fd9213f7eac (diff)
downloadsupport-snap-temp-L12800000867760435.tar.gz
Merge "Merge cherrypicks of [1671245, 1671246] into androidx-camera-release" into androidx-camera-releasesnap-temp-L76800000867674383snap-temp-L12800000867760435
-rw-r--r--buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt2
-rw-r--r--camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java64
-rw-r--r--camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/DeviceQuirksLoader.java4
-rw-r--r--camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/ImageCaptureWashedOutImageQuirk.java61
4 files changed, 121 insertions, 10 deletions
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index a866bb76396..c7f0fb6a80a 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -35,7 +35,7 @@ object LibraryVersions {
val BIOMETRIC = Version("1.2.0-alpha02")
val BROWSER = Version("1.3.0-rc01")
val BUILDSRC_TESTS = Version("1.0.0-alpha01")
- val CAMERA = Version("1.0.0-rc04")
+ val CAMERA = Version("1.0.0-rc05")
val CAMERA_EXTENSIONS = Version("1.0.0-alpha22")
val CAMERA_PIPE = Version("1.0.0-alpha01")
val CAMERA_VIDEO = Version("1.0.0-alpha01")
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index 442ea68b1b6..e100a24ea8c 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -112,6 +112,8 @@ import androidx.camera.core.impl.utils.futures.Futures;
import androidx.camera.core.internal.IoConfig;
import androidx.camera.core.internal.TargetConfig;
import androidx.camera.core.internal.YuvToJpegProcessor;
+import androidx.camera.core.internal.compat.quirk.DeviceQuirks;
+import androidx.camera.core.internal.compat.quirk.ImageCaptureWashedOutImageQuirk;
import androidx.camera.core.internal.compat.quirk.SoftwareJpegEncodingPreferredQuirk;
import androidx.camera.core.internal.compat.workaround.ExifRotationAvailability;
import androidx.camera.core.internal.utils.ImageUtil;
@@ -300,6 +302,14 @@ public final class ImageCapture extends UseCase {
*/
private boolean mUseSoftwareJpeg = false;
+ /**
+ * Whether the torch flash will be used.
+ *
+ * <p>When the flag is set, torch will be opened and closed to replace the flash fired by flash
+ * mode.
+ */
+ private final boolean mUseTorchFlash;
+
////////////////////////////////////////////////////////////////////////////////////////////
// [UseCase attached dynamic] - Can change but is only available when the UseCase is attached.
////////////////////////////////////////////////////////////////////////////////////////////
@@ -348,6 +358,11 @@ public final class ImageCapture extends UseCase {
} else {
mEnableCheck3AConverged = false; // skip 3A convergence in MIN_LATENCY mode
}
+
+ mUseTorchFlash = DeviceQuirks.get(ImageCaptureWashedOutImageQuirk.class) != null;
+ if (mUseTorchFlash) {
+ Logger.d(TAG, "Open and close torch to replace the flash fired by flash mode.");
+ }
}
@UiThread
@@ -1304,9 +1319,12 @@ public final class ImageCapture extends UseCase {
.transformAsync(captureResult -> {
state.mPreCaptureState = captureResult;
triggerAfIfNeeded(state);
- if (isAePrecaptureRequired(state)) {
- // trigger AE precapture and await the result.
- return triggerAePrecapture(state);
+ if (isFlashRequired(state)) {
+ if (mUseTorchFlash) {
+ return openTorch(state);
+ } else {
+ return triggerAePrecapture(state);
+ }
}
return Futures.immediateFuture(null);
}, mExecutor)
@@ -1321,10 +1339,37 @@ public final class ImageCapture extends UseCase {
* <p>For example, cancel 3A scan, close torch if necessary.
*/
void postTakePicture(final TakePictureState state) {
+ closeTorch(state);
cancelAfAeTrigger(state);
unlockFlashMode();
}
+ @NonNull
+ private ListenableFuture<Void> openTorch(@NonNull TakePictureState state) {
+ CameraInternal camera = getCamera();
+ if (camera != null && camera.getCameraInfo().getTorchState().getValue() == TorchState.ON) {
+ // Torch is already opened.
+ return Futures.immediateFuture(null);
+ }
+
+ Logger.d(TAG, "openTorch");
+
+ // Create a new future in order to ignore any fail from CameraControl.enableTorch().
+ return CallbackToFutureAdapter.getFuture(completer -> {
+ getCameraControl().enableTorch(state.mIsTorchOpened = true).addListener(
+ () -> completer.set(null), CameraXExecutors.directExecutor());
+ return "openTorch";
+ });
+ }
+
+ private void closeTorch(@NonNull TakePictureState state) {
+ if (state.mIsTorchOpened) {
+ // Add listener to avoid FutureReturnValueIgnored error.
+ getCameraControl().enableTorch(state.mIsTorchOpened = false).addListener(() -> {
+ }, CameraXExecutors.directExecutor());
+ }
+ }
+
/**
* Gets a capture result or not according to current configuration.
*
@@ -1357,7 +1402,7 @@ public final class ImageCapture extends UseCase {
return Futures.immediateFuture(null);
}
- boolean isAePrecaptureRequired(TakePictureState state) {
+ boolean isFlashRequired(@NonNull TakePictureState state) {
switch (getFlashMode()) {
case FLASH_MODE_ON:
return true;
@@ -1370,9 +1415,7 @@ public final class ImageCapture extends UseCase {
}
ListenableFuture<Boolean> check3AConverged(TakePictureState state) {
- // Skip the 3A converged check if enableCheck3AConverged is false and AE precapture is
- // not triggered.
- if (!mEnableCheck3AConverged && !state.mIsAePrecaptureTriggered) {
+ if (!mEnableCheck3AConverged && !state.mIsAePrecaptureTriggered && !state.mIsTorchOpened) {
return Futures.immediateFuture(false);
}
@@ -1451,10 +1494,12 @@ public final class ImageCapture extends UseCase {
}
/** Issues a request to start auto exposure scan. */
- ListenableFuture<CameraCaptureResult> triggerAePrecapture(TakePictureState state) {
+ ListenableFuture<Void> triggerAePrecapture(TakePictureState state) {
Logger.d(TAG, "triggerAePrecapture");
state.mIsAePrecaptureTriggered = true;
- return getCameraControl().triggerAePrecapture();
+ // Transform type from CameraCaptureResult to Void
+ return Futures.transform(getCameraControl().triggerAePrecapture(), captureResult -> null,
+ CameraXExecutors.directExecutor());
}
/** Issues a request to cancel auto focus and/or auto exposure scan. */
@@ -2045,6 +2090,7 @@ public final class ImageCapture extends UseCase {
*/
static final class TakePictureState {
CameraCaptureResult mPreCaptureState = EmptyCameraCaptureResult.create();
+ boolean mIsTorchOpened = false;
boolean mIsAfTriggered = false;
boolean mIsAePrecaptureTriggered = false;
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/DeviceQuirksLoader.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/DeviceQuirksLoader.java
index 0a15ab7d60b..debf4f3f6c6 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/DeviceQuirksLoader.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/DeviceQuirksLoader.java
@@ -47,6 +47,10 @@ public class DeviceQuirksLoader {
quirks.add(new ImageCaptureRotationOptionQuirk());
}
+ if (ImageCaptureWashedOutImageQuirk.load()) {
+ quirks.add(new ImageCaptureWashedOutImageQuirk());
+ }
+
return quirks;
}
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/ImageCaptureWashedOutImageQuirk.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/ImageCaptureWashedOutImageQuirk.java
new file mode 100644
index 00000000000..62fa918ea57
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/compat/quirk/ImageCaptureWashedOutImageQuirk.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2021 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 androidx.camera.core.internal.compat.quirk;
+
+import android.os.Build;
+
+import androidx.camera.core.impl.Quirk;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Quirk that prevents from getting washed out image while taking picture with flash ON/AUTO mode.
+ *
+ * <p>See b/176399765 and b/181966663.
+ */
+public class ImageCaptureWashedOutImageQuirk implements Quirk {
+
+ // List of devices with the issue. See b/181966663.
+ private static final List<String> DEVICE_MODELS = Arrays.asList(
+ // Galaxy S7
+ "SM-G9300",
+ "SM-G930R",
+ "SM-G930A",
+ "SM-G930V",
+ "SM-G930T",
+ "SM-G930U",
+ "SM-G930P",
+
+ // Galaxy S7+
+ "SM-SC02H",
+ "SM-SCV33",
+ "SM-G9350",
+ "SM-G935R",
+ "SM-G935A",
+ "SM-G935V",
+ "SM-G935T",
+ "SM-G935U",
+ "SM-G935P"
+ );
+
+ static boolean load() {
+ return "SAMSUNG".equals(Build.BRAND.toUpperCase(Locale.US))
+ && DEVICE_MODELS.contains(Build.MODEL.toUpperCase(Locale.US));
+ }
+}