mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 04:28:35 +00:00
Fix crash if sensors disabled in developer mode.
This commit is contained in:
committed by
Greyson Parrelli
parent
6b5f4ca8c2
commit
6a5aa089ae
@@ -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(
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 -->
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user