mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-15 07:28:30 +00:00
Upgrade CameraX to 1.3.0-rc01
This commit is contained in:
committed by
Alex Hart
parent
f959543c19
commit
b19aedd17c
@@ -3,12 +3,9 @@ package org.thoughtcrime.securesms.mediasend;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.camera.view.video.ExperimentalVideo;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
@@ -30,10 +30,12 @@ import androidx.camera.core.CameraSelector;
|
||||
import androidx.camera.core.ImageCapture;
|
||||
import androidx.camera.core.ImageCaptureException;
|
||||
import androidx.camera.core.ImageProxy;
|
||||
import androidx.camera.video.FallbackStrategy;
|
||||
import androidx.camera.video.Quality;
|
||||
import androidx.camera.video.QualitySelector;
|
||||
import androidx.camera.view.CameraController;
|
||||
import androidx.camera.view.LifecycleCameraController;
|
||||
import androidx.camera.view.PreviewView;
|
||||
import androidx.camera.view.video.ExperimentalVideo;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.constraintlayout.widget.ConstraintSet;
|
||||
import androidx.core.content.ContextCompat;
|
||||
@@ -71,7 +73,6 @@ import io.reactivex.rxjava3.disposables.Disposable;
|
||||
* Camera captured implemented using the CameraX SDK, which uses Camera2 under the hood. Should be
|
||||
* preferred whenever possible.
|
||||
*/
|
||||
@ExperimentalVideo
|
||||
public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||
|
||||
private static final String TAG = Log.tag(CameraXFragment.class);
|
||||
@@ -239,7 +240,7 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||
CameraController.OutputSize outputSize = new CameraController.OutputSize(size);
|
||||
|
||||
cameraController.setImageCaptureTargetSize(outputSize);
|
||||
cameraController.setVideoCaptureTargetSize(new CameraController.OutputSize(VideoUtil.getVideoRecordingSize()));
|
||||
cameraController.setVideoCaptureQualitySelector(QualitySelector.from(Quality.HD, FallbackStrategy.lowerQualityThan(Quality.HD)));
|
||||
|
||||
controlsContainer.removeAllViews();
|
||||
controlsContainer.addView(LayoutInflater.from(getContext()).inflate(layout, controlsContainer, false));
|
||||
|
||||
@@ -14,12 +14,13 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.camera.core.ZoomState;
|
||||
import androidx.camera.video.FileDescriptorOutputOptions;
|
||||
import androidx.camera.video.Recording;
|
||||
import androidx.camera.video.VideoRecordEvent;
|
||||
import androidx.camera.view.CameraController;
|
||||
import androidx.camera.view.PreviewView;
|
||||
import androidx.camera.view.video.ExperimentalVideo;
|
||||
import androidx.camera.view.video.OnVideoSavedCallback;
|
||||
import androidx.camera.view.video.OutputFileOptions;
|
||||
import androidx.camera.view.video.OutputFileResults;
|
||||
import androidx.camera.view.video.AudioConfig;
|
||||
import androidx.core.util.Consumer;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.bumptech.glide.util.Executors;
|
||||
@@ -39,7 +40,6 @@ import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RequiresApi(26)
|
||||
@ExperimentalVideo
|
||||
class CameraXVideoCaptureHelper implements CameraButtonView.VideoCaptureListener {
|
||||
|
||||
private static final String TAG = CameraXVideoCaptureHelper.class.getName();
|
||||
@@ -57,25 +57,31 @@ class CameraXVideoCaptureHelper implements CameraButtonView.VideoCaptureListener
|
||||
|
||||
private ValueAnimator cameraMetricsAnimator;
|
||||
|
||||
private final OnVideoSavedCallback videoSavedListener = new OnVideoSavedCallback() {
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public void onVideoSaved(@NonNull OutputFileResults outputFileResults) {
|
||||
try {
|
||||
debouncer.clear();
|
||||
cameraController.setZoomRatio(Objects.requireNonNull(cameraController.getZoomState().getValue()).getMinZoomRatio());
|
||||
memoryFileDescriptor.seek(0);
|
||||
callback.onVideoSaved(memoryFileDescriptor.getFileDescriptor());
|
||||
} catch (IOException e) {
|
||||
callback.onVideoError(e);
|
||||
}
|
||||
}
|
||||
private @Nullable Recording activeRecording = null;
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
private final Consumer<VideoRecordEvent> videoSavedListener = new Consumer<>() {
|
||||
@Override
|
||||
public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) {
|
||||
debouncer.clear();
|
||||
callback.onVideoError(cause);
|
||||
public void accept(VideoRecordEvent videoRecordEvent) {
|
||||
Log.d(TAG, "Received recording event: " + videoRecordEvent.getClass().getSimpleName());
|
||||
|
||||
if (videoRecordEvent instanceof VideoRecordEvent.Finalize) {
|
||||
VideoRecordEvent.Finalize event = (VideoRecordEvent.Finalize) videoRecordEvent;
|
||||
|
||||
if (event.hasError()) {
|
||||
Log.w(TAG, "Hit an error while recording! Error code: " + event.getError(), event.getCause());
|
||||
debouncer.clear();
|
||||
callback.onVideoError(event.getCause());
|
||||
} else {
|
||||
try {
|
||||
debouncer.clear();
|
||||
cameraController.setZoomRatio(Objects.requireNonNull(cameraController.getZoomState().getValue()).getMinZoomRatio());
|
||||
memoryFileDescriptor.seek(0);
|
||||
callback.onVideoSaved(memoryFileDescriptor.getFileDescriptor());
|
||||
} catch (IOException e) {
|
||||
callback.onVideoError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -140,9 +146,11 @@ class CameraXVideoCaptureHelper implements CameraButtonView.VideoCaptureListener
|
||||
callback.onVideoRecordStarted();
|
||||
shrinkCaptureArea();
|
||||
|
||||
OutputFileOptions options = OutputFileOptions.builder(memoryFileDescriptor.getParcelFileDescriptor()).build();
|
||||
FileDescriptorOutputOptions outputOptions = new FileDescriptorOutputOptions.Builder(memoryFileDescriptor.getParcelFileDescriptor()).build();
|
||||
AudioConfig audioConfig = AudioConfig.create(true);
|
||||
|
||||
activeRecording = cameraController.startRecording(outputOptions, audioConfig, Executors.mainThreadExecutor(), videoSavedListener);
|
||||
|
||||
cameraController.startRecording(options, Executors.mainThreadExecutor(), videoSavedListener);
|
||||
updateProgressAnimator.start();
|
||||
debouncer.publish(this::onVideoCaptureComplete);
|
||||
}
|
||||
@@ -198,10 +206,19 @@ class CameraXVideoCaptureHelper implements CameraButtonView.VideoCaptureListener
|
||||
|
||||
@Override
|
||||
public void onVideoCaptureComplete() {
|
||||
if (!canRecordAudio()) return;
|
||||
if (!canRecordAudio()) {
|
||||
Log.w(TAG, "Can't record audio!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeRecording == null) {
|
||||
Log.w(TAG, "No active recording!");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d(TAG, "onVideoCaptureComplete");
|
||||
cameraController.stopRecording();
|
||||
activeRecording.close();
|
||||
activeRecording = null;
|
||||
|
||||
if (cameraMetricsAnimator != null && cameraMetricsAnimator.isRunning()) {
|
||||
cameraMetricsAnimator.reverse();
|
||||
@@ -219,6 +236,16 @@ class CameraXVideoCaptureHelper implements CameraButtonView.VideoCaptureListener
|
||||
cameraController.setZoomRatio((range * increment) + zoomState.getMinZoomRatio());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (activeRecording != null) {
|
||||
Log.w(TAG, "Dangling recording left open in finalize()! Attempting to close.");
|
||||
activeRecording.close();
|
||||
}
|
||||
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
static MemoryFileDescriptor createFileDescriptor(@NonNull Context context) throws MemoryFileDescriptor.MemoryFileException {
|
||||
return MemoryFileDescriptor.newMemoryFileDescriptor(
|
||||
context,
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.mediasend.camerax
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.camera.view.CameraController
|
||||
import androidx.camera.view.video.ExperimentalVideo
|
||||
import org.signal.core.util.asListContains
|
||||
import org.thoughtcrime.securesms.mms.MediaConstraints
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
@@ -12,7 +11,6 @@ import org.thoughtcrime.securesms.video.VideoUtil
|
||||
/**
|
||||
* Describes device capabilities
|
||||
*/
|
||||
@ExperimentalVideo
|
||||
sealed class CameraXModePolicy {
|
||||
|
||||
abstract val isVideoSupported: Boolean
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* A set of {@link android.os.Build#MODEL} that are known to both benefit from
|
||||
* {@link androidx.camera.core.ImageCapture.CaptureMode#MAX_QUALITY} and execute it quickly.
|
||||
* {@link androidx.camera.core.ImageCapture.CaptureMode#CAPTURE_MODE_MAXIMIZE_QUALITY} and execute it quickly.
|
||||
*
|
||||
*/
|
||||
public class FastCameraModels {
|
||||
@@ -19,6 +19,7 @@ public class FastCameraModels {
|
||||
add("Pixel 3 XL");
|
||||
add("Pixel 3a");
|
||||
add("Pixel 3a XL");
|
||||
add("SM-S911U1");
|
||||
}};
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@ dependencyResolutionManagement {
|
||||
libs {
|
||||
version('androidx-appcompat', '1.6.1')
|
||||
version('androidx-activity', '1.7.2')
|
||||
version('androidx-camera', '1.2.3')
|
||||
version('androidx-camera', '1.3.0-rc01')
|
||||
version('androidx-fragment', '1.6.1')
|
||||
version('androidx-lifecycle', '2.6.1')
|
||||
version('androidx-media3', '1.1.0')
|
||||
|
||||
@@ -144,6 +144,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
||||
<sha256 value="5eebeaff01d042e06dcf292abf8964ad391e4b0159f0090f16253d6045d38da0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.annotation" name="annotation-experimental" version="1.3.1">
|
||||
<artifact name="annotation-experimental-1.3.1.aar">
|
||||
<sha256 value="e4d49dc3880b7b7437ea54ce71461e02897faa4e1ecc53e63ecadb1a14c20c9c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="annotation-experimental-1.3.1.module">
|
||||
<sha256 value="9b6974a7dfe26d3c209dd63e16f8ee2461b57a091789160ca1eb492bb1bf3f84" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.annotation" name="annotation-jvm" version="1.6.0">
|
||||
<artifact name="annotation-jvm-1.6.0.jar">
|
||||
<sha256 value="60b10b5ef5769b79570172e015b8159405c92f034ba88b9391a977589c9deb4e" origin="Generated by Gradle"/>
|
||||
@@ -289,6 +297,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
||||
<sha256 value="6838c8fa96f6efdac3294aa8a01c7d7ac30e2c8b634c6e08470de7aadebc5304" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-camera2" version="1.3.0-rc01">
|
||||
<artifact name="camera-camera2-1.3.0-rc01.aar">
|
||||
<sha256 value="a0fb0e8fca8e4f9f2d20dc55ee8021372acac4123f6d3f66365e29cfb5b70498" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-camera2-1.3.0-rc01.module">
|
||||
<sha256 value="fcc7250a3edb08e1a2952fbb2dc488dbeadd1c15ada1e138ec3742d2ea99a78c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-core" version="1.2.3">
|
||||
<artifact name="camera-core-1.2.3.aar">
|
||||
<sha256 value="b4aeb070c0026cf15b0c24f60c72c5947c7e8ba48d392de6f5e3ecf188d5e3f7" origin="Generated by Gradle"/>
|
||||
@@ -297,6 +313,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
||||
<sha256 value="6aed3917c7992365a6dace91ddc620f7826c1033ca558c647a8ab3cb5ebf5ae7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-core" version="1.3.0-rc01">
|
||||
<artifact name="camera-core-1.3.0-rc01.aar">
|
||||
<sha256 value="b00447a46a878f77551c70de5f532d87811b92fec70934203ab3c2e51a10f4fb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-core-1.3.0-rc01.module">
|
||||
<sha256 value="b52cbeb710747adf2ea4e36eceaa9f7560ef783a000a6b23ebd3b82948ddefa1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-lifecycle" version="1.2.3">
|
||||
<artifact name="camera-lifecycle-1.2.3.aar">
|
||||
<sha256 value="899f45a21a81eaea2e2291bb4f4061c3afe2ea3df474cc1fedc94b6940a719cb" origin="Generated by Gradle"/>
|
||||
@@ -305,6 +329,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
||||
<sha256 value="07084c793e9fdfd6c700559fbf736548a50d64337f0c6053bbb9a8646848c6c2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-lifecycle" version="1.3.0-rc01">
|
||||
<artifact name="camera-lifecycle-1.3.0-rc01.aar">
|
||||
<sha256 value="8d3ec866d2a9013289a637eacdc64f1d3378852d76a1ba6edc6e8ab95b014246" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-lifecycle-1.3.0-rc01.module">
|
||||
<sha256 value="8679ef6fec733657051dd32d26342d776427e4418e584af7aa44d66813da3e1f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-video" version="1.3.0-rc01">
|
||||
<artifact name="camera-video-1.3.0-rc01.aar">
|
||||
<sha256 value="b766ca808bd347341f5554296e96eed2a0412605c8f2ee02f0edcaf9ecb1dcc2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-video-1.3.0-rc01.module">
|
||||
<sha256 value="bc71cff4ba1680ec648192eb826c6a59202117eb73064424dd1c14810bb00c2f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-view" version="1.2.3">
|
||||
<artifact name="camera-view-1.2.3.aar">
|
||||
<sha256 value="08c0f162f75d859334e3233daaf4fcd9b80035bac8e9cd99b05681e4c68e1173" origin="Generated by Gradle"/>
|
||||
@@ -313,6 +353,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
||||
<sha256 value="b9b191f1914ddcaae57124f01bc427ece346a8b83d122467faa3ab1bf08837e3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.camera" name="camera-view" version="1.3.0-rc01">
|
||||
<artifact name="camera-view-1.3.0-rc01.aar">
|
||||
<sha256 value="cc4004ed2d8b3a0666a741c870425b512bef9e4a089ddef8693e63664cf8cc91" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="camera-view-1.3.0-rc01.module">
|
||||
<sha256 value="d8017f0f6d5d0f0b09b8ffcd9e519d7cb21ffb3ba728dd6fa8dd84114d0cd734" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.cardview" name="cardview" version="1.0.0">
|
||||
<artifact name="cardview-1.0.0.aar">
|
||||
<sha256 value="1193c04c22a3d6b5946dae9f4e8c59d6adde6a71b6bd5d87fb99d82dda1afec7" origin="Generated by Gradle"/>
|
||||
@@ -4653,6 +4701,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
||||
<sha256 value="042a1cd1ac976cdcfe5eb63f1d8e0b0b892c9248e15a69c8cfba495d546ea52a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="1.8.22">
|
||||
<artifact name="kotlin-stdlib-1.8.22.jar">
|
||||
<sha256 value="03a5c3965cc37051128e64e46748e394b6bd4c97fa81c6de6fc72bfd44e3421b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-common" version="1.4.21">
|
||||
<artifact name="kotlin-stdlib-common-1.4.21.jar">
|
||||
<sha256 value="812cf197d9c4c67e1f47f95e2d72a9b600f0d1124560617bfe9850773eccbcff" origin="Generated by Gradle"/>
|
||||
@@ -4693,6 +4746,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
||||
<sha256 value="6a44c9ecc9d7754d9e943fb1e3588c74d4a3f1785be51074f49d6c5723682a73" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-common" version="1.8.22">
|
||||
<artifact name="kotlin-stdlib-common-1.8.22.jar">
|
||||
<sha256 value="d0c2365e2437ef70f34586d50f055743f79716bcfe65e4bc7239cdd2669ef7c5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.4.10">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.4.10.jar">
|
||||
<sha256 value="f9566380c08722c780ce33ceee23e98ddf765ca98fabd3e2fabae7975c8d232b" origin="Generated by Gradle"/>
|
||||
|
||||
Reference in New Issue
Block a user