mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-24 16:00:02 +00:00
committed by
Moxie Marlinspike
parent
47b21707be
commit
1a7ab6346f
@@ -19,7 +19,6 @@ import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.PreviewCallback;
|
||||
import android.os.Build;
|
||||
@@ -30,7 +29,6 @@ import android.util.Log;
|
||||
import android.view.OrientationEventListener;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -91,7 +89,7 @@ public class CameraView extends FrameLayout {
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
public void onResume() {
|
||||
Log.w(TAG, "onResume()");
|
||||
Log.w(TAG, "onResume() queued");
|
||||
final CameraHost host = getHost();
|
||||
submitTask(new SerializedAsyncTask<FailureReason>() {
|
||||
@Override protected FailureReason onRunBackground() {
|
||||
@@ -110,11 +108,11 @@ public class CameraView extends FrameLayout {
|
||||
}
|
||||
|
||||
@Override protected void onPostMain(FailureReason result) {
|
||||
cameraReady = true;
|
||||
if (result != null) {
|
||||
host.onCameraFail(result);
|
||||
return;
|
||||
}
|
||||
cameraReady = true;
|
||||
if (getActivity().getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
|
||||
onOrientationChange.enable();
|
||||
}
|
||||
@@ -126,12 +124,13 @@ public class CameraView extends FrameLayout {
|
||||
initPreview();
|
||||
requestLayout();
|
||||
invalidate();
|
||||
Log.w(TAG, "onResume() completed");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
Log.w(TAG, "onPause()");
|
||||
Log.w(TAG, "onPause() queued");
|
||||
submitTask(new SerializedAsyncTask<Void>() {
|
||||
@Override protected void onPreMain() {
|
||||
cameraReady = false;
|
||||
@@ -151,6 +150,7 @@ public class CameraView extends FrameLayout {
|
||||
outputOrientation = -1;
|
||||
cameraId = -1;
|
||||
lastPictureOrientation = -1;
|
||||
Log.w(TAG, "onPause() completed");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -255,6 +255,7 @@ public class CameraView extends FrameLayout {
|
||||
}
|
||||
|
||||
void previewCreated() {
|
||||
Log.w(TAG, "previewCreated() queued");
|
||||
final CameraHost host = getHost();
|
||||
submitTask(new PostInitializationTask<Void>() {
|
||||
@Override protected void onPostMain(Void avoid) {
|
||||
@@ -265,6 +266,7 @@ public class CameraView extends FrameLayout {
|
||||
} catch (IOException e) {
|
||||
host.handleException(e);
|
||||
}
|
||||
Log.w(TAG, "previewCreated() completed");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -277,11 +279,6 @@ public class CameraView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
void previewReset() {
|
||||
previewStopped();
|
||||
initPreview();
|
||||
}
|
||||
|
||||
private void previewStopped() {
|
||||
if (inPreview) {
|
||||
stopPreview();
|
||||
@@ -290,6 +287,7 @@ public class CameraView extends FrameLayout {
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
public void initPreview() {
|
||||
Log.w(TAG, "initPreview() queued");
|
||||
submitTask(new PostInitializationTask<Void>() {
|
||||
@Override protected void onPostMain(Void avoid) {
|
||||
if (camera != null && cameraReady) {
|
||||
@@ -305,20 +303,19 @@ public class CameraView extends FrameLayout {
|
||||
startPreview();
|
||||
requestLayout();
|
||||
invalidate();
|
||||
Log.w(TAG, "initPreview() completed");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startPreview() {
|
||||
Log.w(TAG, "startPreview()");
|
||||
camera.startPreview();
|
||||
inPreview = true;
|
||||
getHost().autoFocusAvailable();
|
||||
}
|
||||
|
||||
private void stopPreview() {
|
||||
Log.w(TAG, "stopPreview()");
|
||||
camera.startPreview();
|
||||
inPreview = false;
|
||||
getHost().autoFocusUnavailable();
|
||||
@@ -453,20 +450,24 @@ public class CameraView extends FrameLayout {
|
||||
@Override public void onAdded() {}
|
||||
|
||||
@Override public final void onRun() {
|
||||
onWait();
|
||||
runOnMainSync(new Runnable() {
|
||||
@Override public void run() {
|
||||
onPreMain();
|
||||
}
|
||||
});
|
||||
try {
|
||||
onWait();
|
||||
runOnMainSync(new Runnable() {
|
||||
@Override public void run() {
|
||||
onPreMain();
|
||||
}
|
||||
});
|
||||
|
||||
final Result result = onRunBackground();
|
||||
final Result result = onRunBackground();
|
||||
|
||||
runOnMainSync(new Runnable() {
|
||||
@Override public void run() {
|
||||
onPostMain(result);
|
||||
}
|
||||
});
|
||||
runOnMainSync(new Runnable() {
|
||||
@Override public void run() {
|
||||
onPostMain(result);
|
||||
}
|
||||
});
|
||||
} catch (PreconditionsNotMetException e) {
|
||||
Log.w(TAG, "skipping task, preconditions not met in onWait()");
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean onShouldRetry(Exception e) {
|
||||
@@ -493,19 +494,26 @@ public class CameraView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
protected void onWait() {}
|
||||
protected void onWait() throws PreconditionsNotMetException {}
|
||||
protected void onPreMain() {}
|
||||
protected Result onRunBackground() { return null; }
|
||||
protected void onPostMain(Result result) {}
|
||||
}
|
||||
|
||||
private abstract class PostInitializationTask<Result> extends SerializedAsyncTask<Result> {
|
||||
@Override protected void onWait() {
|
||||
@Override protected void onWait() throws PreconditionsNotMetException {
|
||||
synchronized (CameraView.this) {
|
||||
if (!cameraReady) {
|
||||
throw new PreconditionsNotMetException();
|
||||
}
|
||||
while (camera == null || previewSize == null || !previewStrategy.isReady()) {
|
||||
Log.w(TAG, String.format("waiting. camera? %s previewSize? %s prevewStrategy? %s",
|
||||
camera != null, previewSize != null, previewStrategy.isReady()));
|
||||
Util.wait(CameraView.this, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreconditionsNotMetException extends Exception {}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
||||
private float halfExpandedAnchorPoint = COLLAPSED_ANCHOR_POINT;
|
||||
private boolean halfModeUnsupported = VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
||||
private Rect drawChildrenRect = new Rect();
|
||||
private boolean paused = false;
|
||||
|
||||
public QuickAttachmentDrawer(Context context) {
|
||||
this(context, null);
|
||||
@@ -128,7 +129,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
||||
}
|
||||
shutterButton.setOnClickListener(new ShutterClickListener());
|
||||
fullScreenButton.setOnClickListener(new FullscreenClickListener());
|
||||
controls.setVisibility(GONE);
|
||||
controls.setVisibility(INVISIBLE);
|
||||
addView(controls, controlsIndex > -1 ? controlsIndex : indexOfChild(quickCamera) + 1);
|
||||
}
|
||||
|
||||
@@ -274,10 +275,10 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
||||
}
|
||||
|
||||
if (slideOffset == COLLAPSED_ANCHOR_POINT && quickCamera.isStarted()) {
|
||||
controls.setVisibility(GONE);
|
||||
quickCamera.setVisibility(GONE);
|
||||
quickCamera.onPause();
|
||||
} else if (slideOffset != COLLAPSED_ANCHOR_POINT && !quickCamera.isStarted()) {
|
||||
controls.setVisibility(INVISIBLE);
|
||||
quickCamera.setVisibility(INVISIBLE);
|
||||
} else if (slideOffset != COLLAPSED_ANCHOR_POINT && !quickCamera.isStarted() & !paused) {
|
||||
controls.setVisibility(VISIBLE);
|
||||
quickCamera.setVisibility(VISIBLE);
|
||||
quickCamera.onResume();
|
||||
@@ -507,10 +508,12 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
paused = true;
|
||||
quickCamera.onPause();
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
paused = false;
|
||||
if (drawerState.isVisible()) quickCamera.onResume();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.components.camera;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.CameraInfo;
|
||||
@@ -13,11 +12,10 @@ import android.os.Build.VERSION_CODES;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.commonsware.cwac.camera.CameraHost.FailureReason;
|
||||
import com.commonsware.cwac.camera.SimpleCameraHost;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -78,29 +76,33 @@ import java.util.List;
|
||||
setOneShotPreviewCallback(new Camera.PreviewCallback() {
|
||||
@Override
|
||||
public void onPreviewFrame(byte[] data, final Camera camera) {
|
||||
final int rotation = getCameraPictureOrientation();
|
||||
final int rotation = getCameraPictureOrientation();
|
||||
final Size previewSize = cameraParameters.getPreviewSize();
|
||||
final Rect croppingRect = getCroppedRect(previewSize, previewRect, rotation);
|
||||
|
||||
new AsyncTask<byte[], Void, Bitmap>() {
|
||||
Log.w(TAG, "previewSize: " + previewSize.width + "x" + previewSize.height);
|
||||
Log.w(TAG, "croppingRect: " + croppingRect.toString());
|
||||
Log.w(TAG, "rotation: " + rotation);
|
||||
new AsyncTask<byte[], Void, byte[]>() {
|
||||
@Override
|
||||
protected Bitmap doInBackground(byte[]... params) {
|
||||
protected byte[] doInBackground(byte[]... params) {
|
||||
byte[] data = params[0];
|
||||
try {
|
||||
Size previewSize = cameraParameters.getPreviewSize();
|
||||
|
||||
return BitmapUtil.createFromNV21(data,
|
||||
previewSize.width,
|
||||
previewSize.height,
|
||||
rotation,
|
||||
getCroppedRect(previewSize, previewRect, rotation));
|
||||
croppingRect);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Bitmap bitmap) {
|
||||
protected void onPostExecute(byte[] imageBytes) {
|
||||
capturing = false;
|
||||
if (bitmap != null && listener != null) listener.onImageCapture(bitmap);
|
||||
if (imageBytes != null && listener != null) listener.onImageCapture(imageBytes);
|
||||
}
|
||||
}.execute(data);
|
||||
}
|
||||
@@ -111,10 +113,7 @@ import java.util.List;
|
||||
final int previewWidth = cameraPreviewSize.width;
|
||||
final int previewHeight = cameraPreviewSize.height;
|
||||
|
||||
if (rotation % 180 > 0) {
|
||||
//noinspection SuspiciousNameCombination
|
||||
visibleRect.set(visibleRect.top, visibleRect.left, visibleRect.bottom, visibleRect.right);
|
||||
}
|
||||
if (rotation % 180 > 0) rotateRect(visibleRect);
|
||||
|
||||
float scale = (float) previewWidth / visibleRect.width();
|
||||
if (visibleRect.height() * scale > previewHeight) {
|
||||
@@ -128,9 +127,16 @@ import java.util.List;
|
||||
(int) (centerY - newHeight / 2),
|
||||
(int) (centerX + newWidth / 2),
|
||||
(int) (centerY + newHeight / 2));
|
||||
|
||||
if (rotation % 180 > 0) rotateRect(visibleRect);
|
||||
return visibleRect;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SuspiciousNameCombination")
|
||||
private void rotateRect(Rect rect) {
|
||||
rect.set(rect.top, rect.left, rect.bottom, rect.right);
|
||||
}
|
||||
|
||||
public void setQuickCameraListener(QuickCameraListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
@@ -150,7 +156,8 @@ import java.util.List;
|
||||
}
|
||||
|
||||
public interface QuickCameraListener {
|
||||
void onImageCapture(@NonNull final Bitmap bitmap);
|
||||
void onImageCapture(@NonNull final byte[] imageBytes);
|
||||
void onCameraFail(FailureReason reason);
|
||||
}
|
||||
|
||||
private class QuickCameraHost extends SimpleCameraHost {
|
||||
@@ -186,7 +193,7 @@ import java.util.List;
|
||||
@Override
|
||||
public void onCameraFail(FailureReason reason) {
|
||||
super.onCameraFail(reason);
|
||||
Toast.makeText(getContext(), R.string.quick_camera_unavailable, Toast.LENGTH_SHORT).show();
|
||||
if (listener != null) listener.onCameraFail(reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user