Fix crash if sensors disabled in developer mode.

This commit is contained in:
Alex Hart
2021-09-07 16:03:12 -03:00
committed by Greyson Parrelli
parent 6b5f4ca8c2
commit 6a5aa089ae
4 changed files with 42 additions and 7 deletions

View File

@@ -60,6 +60,7 @@ import androidx.camera.core.impl.LensFacingConverter;
import androidx.camera.core.impl.utils.executor.CameraXExecutors; import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.core.impl.utils.futures.FutureCallback; import androidx.camera.core.impl.utils.futures.FutureCallback;
import androidx.camera.core.impl.utils.futures.Futures; import androidx.camera.core.impl.utils.futures.Futures;
import androidx.core.util.Consumer;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
@@ -130,6 +131,11 @@ public final class SignalCameraView extends FrameLayout {
// For accessibility event // For accessibility event
private MotionEvent mUpEvent; private MotionEvent mUpEvent;
// BEGIN Custom Signal Code Block
private Consumer<Throwable> errorConsumer;
private Throwable pendingError;
// END Custom Signal Code Block
public SignalCameraView(@NonNull Context context) { public SignalCameraView(@NonNull Context context) {
this(context, null); this(context, null);
} }
@@ -167,20 +173,33 @@ public final class SignalCameraView extends FrameLayout {
* androidx.lifecycle.Lifecycle.State#DESTROYED} state. * androidx.lifecycle.Lifecycle.State#DESTROYED} state.
* @throws IllegalStateException if camera permissions are not granted. * @throws IllegalStateException if camera permissions are not granted.
*/ */
// BEGIN Custom Signal Code Block
@RequiresPermission(permission.CAMERA) @RequiresPermission(permission.CAMERA)
public void bindToLifecycle(@NonNull LifecycleOwner lifecycleOwner) { public void bindToLifecycle(@NonNull LifecycleOwner lifecycleOwner, Consumer<Throwable> errorConsumer) {
mCameraModule.bindToLifecycle(lifecycleOwner); mCameraModule.bindToLifecycle(lifecycleOwner);
this.errorConsumer = errorConsumer;
if (pendingError != null) {
errorConsumer.accept(pendingError);
} }
}
// END Custom Signal Code Block
private void init(Context context, @Nullable AttributeSet attrs) { private void init(Context context, @Nullable AttributeSet attrs) {
addView(mPreviewView = new PreviewView(getContext()), 0 /* view position */); addView(mPreviewView = new PreviewView(getContext()), 0 /* view position */);
// Begin custom signal code block // Begin custom signal code block
mPreviewView.setImplementationMode(PreviewView.ImplementationMode.COMPATIBLE); mPreviewView.setImplementationMode(PreviewView.ImplementationMode.COMPATIBLE);
mCameraModule = new SignalCameraXModule(this, error -> {
if (errorConsumer != null) {
errorConsumer.accept(error);
} else {
pendingError = error;
}
});
// End custom signal code block // End custom signal code block
mCameraModule = new SignalCameraXModule(this);
if (attrs != null) { if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraView); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraView);
setScaleType( setScaleType(

View File

@@ -46,6 +46,7 @@ import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.core.impl.utils.futures.FutureCallback; import androidx.camera.core.impl.utils.futures.FutureCallback;
import androidx.camera.core.impl.utils.futures.Futures; import androidx.camera.core.impl.utils.futures.Futures;
import androidx.camera.lifecycle.ProcessCameraProvider; import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.util.Consumer;
import androidx.core.util.Preconditions; import androidx.core.util.Preconditions;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleObserver;
@@ -123,7 +124,9 @@ final class SignalCameraXModule {
@Nullable @Nullable
ProcessCameraProvider mCameraProvider; ProcessCameraProvider mCameraProvider;
SignalCameraXModule(SignalCameraView view) { // BEGIN Custom Signal Code Block
SignalCameraXModule(SignalCameraView view, Consumer<Throwable> errorConsumer) {
// END Custom Signal Code Block
mCameraView = view; mCameraView = view;
Futures.addCallback(ProcessCameraProvider.getInstance(view.getContext()), Futures.addCallback(ProcessCameraProvider.getInstance(view.getContext()),
@@ -141,7 +144,9 @@ final class SignalCameraXModule {
@Override @Override
public void onFailure(Throwable t) { public void onFailure(Throwable t) {
throw new RuntimeException("CameraX failed to initialize.", t); // BEGIN Custom Signal Code Block
errorConsumer.accept(t);
// END Custom Signal Code Block
} }
}, CameraXExecutors.mainThreadExecutor()); }, CameraXExecutors.mainThreadExecutor());

View File

@@ -18,6 +18,7 @@ import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
import android.view.animation.RotateAnimation; import android.view.animation.RotateAnimation;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -118,7 +119,7 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
this.controlsContainer = view.findViewById(R.id.camerax_controls_container); this.controlsContainer = view.findViewById(R.id.camerax_controls_container);
camera.setScaleType(PreviewView.ScaleType.FIT_CENTER); camera.setScaleType(PreviewView.ScaleType.FIT_CENTER);
camera.bindToLifecycle(getViewLifecycleOwner()); camera.bindToLifecycle(getViewLifecycleOwner(), this::handleCameraInitializationError);
camera.setCameraLensFacing(CameraXUtil.toLensFacing(TextSecurePreferences.getDirectCaptureCameraId(requireContext()))); camera.setCameraLensFacing(CameraXUtil.toLensFacing(TextSecurePreferences.getDirectCaptureCameraId(requireContext())));
onOrientationChanged(getResources().getConfiguration().orientation); onOrientationChanged(getResources().getConfiguration().orientation);
@@ -147,7 +148,7 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
camera.bindToLifecycle(getViewLifecycleOwner()); camera.bindToLifecycle(getViewLifecycleOwner(), this::handleCameraInitializationError);
requireActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); requireActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requireActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); requireActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
} }
@@ -195,6 +196,15 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
}); });
} }
private void handleCameraInitializationError(Throwable error) {
Log.w(TAG, "An error occurred", error);
Context context = getActivity();
if (context != null) {
Toast.makeText(context, R.string.CameraFragment__failed_to_open_camera, Toast.LENGTH_SHORT).show();
}
}
private void onOrientationChanged(int orientation) { private void onOrientationChanged(int orientation) {
int layout = orientation == Configuration.ORIENTATION_PORTRAIT ? R.layout.camera_controls_portrait int layout = orientation == Configuration.ORIENTATION_PORTRAIT ? R.layout.camera_controls_portrait
: R.layout.camera_controls_landscape; : R.layout.camera_controls_landscape;

View File

@@ -3813,6 +3813,7 @@
<string name="MediaReviewFragment__view_once_message">View once message</string> <string name="MediaReviewFragment__view_once_message">View once message</string>
<string name="MediaReviewImagePageFragment__youll_lose_any_changes">You\'ll lose any changes you\'ve made to this photo.</string> <string name="MediaReviewImagePageFragment__youll_lose_any_changes">You\'ll lose any changes you\'ve made to this photo.</string>
<string name="ImageEditorHud__delete">Delete</string> <string name="ImageEditorHud__delete">Delete</string>
<string name="CameraFragment__failed_to_open_camera">Failed to open camera</string>
<!-- EOF --> <!-- EOF -->