fix false camera captures

// FREEBIE
This commit is contained in:
Jake McGinty 2015-11-23 15:19:05 -08:00 committed by Moxie Marlinspike
parent 3a5d4e7ebe
commit b4e28e219b
5 changed files with 74 additions and 24 deletions

View File

@ -14,6 +14,7 @@
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:background="@drawable/quick_camera_shutter_ring" android:background="@drawable/quick_camera_shutter_ring"
android:src="@drawable/quick_shutter_button" android:src="@drawable/quick_shutter_button"
android:enabled="false"
android:padding="20dp"/> android:padding="20dp"/>
<ImageButton android:id="@+id/fullscreen_button" <ImageButton android:id="@+id/fullscreen_button"
@ -21,7 +22,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:background="#00000000" android:background="@drawable/circle_touch_highlight_background"
android:src="@drawable/quick_camera_fullscreen" android:src="@drawable/quick_camera_fullscreen"
android:padding="20dp" /> android:padding="20dp" />
@ -30,8 +31,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:background="#00000000" android:background="@drawable/circle_touch_highlight_background"
android:src="@drawable/quick_camera_rear" android:src="@drawable/quick_camera_rear"
android:enabled="false"
android:padding="20dp" android:padding="20dp"
android:visibility="invisible" android:visibility="invisible"
tools:visibility="visible" /> tools:visibility="visible" />

View File

@ -14,6 +14,7 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:background="@drawable/quick_camera_shutter_ring" android:background="@drawable/quick_camera_shutter_ring"
android:src="@drawable/quick_shutter_button" android:src="@drawable/quick_shutter_button"
android:enabled="false"
android:padding="20dp"/> android:padding="20dp"/>
<ImageButton android:id="@+id/fullscreen_button" <ImageButton android:id="@+id/fullscreen_button"
@ -21,7 +22,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:background="#00000000" android:background="@drawable/circle_touch_highlight_background"
android:src="@drawable/quick_camera_fullscreen" android:src="@drawable/quick_camera_fullscreen"
android:padding="20dp"/> android:padding="20dp"/>
@ -30,8 +31,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:background="#00000000" android:background="@drawable/circle_touch_highlight_background"
android:src="@drawable/quick_camera_rear" android:src="@drawable/quick_camera_rear"
android:enabled="false"
android:padding="20dp" android:padding="20dp"
android:visibility="invisible" android:visibility="invisible"
tools:visibility="visible"/> tools:visibility="visible"/>

View File

@ -1362,6 +1362,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
quickAttachmentToggle.disable(); quickAttachmentToggle.disable();
} }
@Override
public void onCameraStart() {}
@Override
public void onCameraStop() {}
@Override @Override
public void onRecorderStarted() { public void onRecorderStarted() {
Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);

View File

@ -37,6 +37,8 @@ import android.view.OrientationEventListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.ApplicationContext;
@ -61,7 +63,7 @@ public class CameraView extends ViewGroup {
private @NonNull State state = State.PAUSED; private @NonNull State state = State.PAUSED;
private @Nullable Size previewSize; private @Nullable Size previewSize;
private @Nullable CameraViewListener listener; private @NonNull List<CameraViewListener> listeners = Collections.synchronizedList(new LinkedList<CameraViewListener>());
private int outputOrientation = -1; private int outputOrientation = -1;
public CameraView(Context context) { public CameraView(Context context) {
@ -102,7 +104,9 @@ public class CameraView extends ViewGroup {
@Nullable @Nullable
Void onRunBackground() { Void onRunBackground() {
try { try {
long openStartMillis = System.currentTimeMillis();
camera = Optional.fromNullable(Camera.open(cameraId)); camera = Optional.fromNullable(Camera.open(cameraId));
Log.w(TAG, "camera.open() -> " + (System.currentTimeMillis() - openStartMillis) + "ms");
synchronized (CameraView.this) { synchronized (CameraView.this) {
CameraView.this.notifyAll(); CameraView.this.notifyAll();
} }
@ -117,7 +121,9 @@ public class CameraView extends ViewGroup {
protected void onPostMain(Void avoid) { protected void onPostMain(Void avoid) {
if (!camera.isPresent()) { if (!camera.isPresent()) {
Log.w(TAG, "tried to open camera but got null"); Log.w(TAG, "tried to open camera but got null");
if (listener != null) listener.onCameraFail(); for (CameraViewListener listener : listeners) {
listener.onCameraFail();
}
return; return;
} }
@ -167,6 +173,10 @@ public class CameraView extends ViewGroup {
Log.w(TAG, "onPause() completed"); Log.w(TAG, "onPause() completed");
} }
}); });
for (CameraViewListener listener : listeners) {
listener.onCameraStop();
}
} }
public boolean isStarted() { public boolean isStarted() {
@ -215,8 +225,8 @@ public class CameraView extends ViewGroup {
if (camera.isPresent()) startPreview(camera.get().getParameters()); if (camera.isPresent()) startPreview(camera.get().getParameters());
} }
public void setListener(@Nullable CameraViewListener listener) { public void addListener(@NonNull CameraViewListener listener) {
this.listener = listener; listeners.add(listener);
} }
public void setPreviewCallback(final @NonNull PreviewCallback previewCallback) { public void setPreviewCallback(final @NonNull PreviewCallback previewCallback) {
@ -308,9 +318,19 @@ public class CameraView extends ViewGroup {
} else { } else {
previewSize = parameters.getPreviewSize(); previewSize = parameters.getPreviewSize();
} }
long previewStartMillis = System.currentTimeMillis();
camera.startPreview(); camera.startPreview();
postRequestLayout(); Log.w(TAG, "camera.startPreview() -> " + (System.currentTimeMillis() - previewStartMillis) + "ms");
state = State.ACTIVE; state = State.ACTIVE;
Util.runOnMain(new Runnable() {
@Override
public void run() {
requestLayout();
for (CameraViewListener listener : listeners) {
listener.onCameraStart();
}
}
});
} catch (Exception e) { } catch (Exception e) {
Log.w(TAG, e); Log.w(TAG, e);
} }
@ -328,6 +348,7 @@ public class CameraView extends ViewGroup {
} }
} }
private Size getPreferredPreviewSize(@NonNull Parameters parameters) { private Size getPreferredPreviewSize(@NonNull Parameters parameters) {
return CameraUtils.getPreferredPreviewSize(displayOrientation, return CameraUtils.getPreferredPreviewSize(displayOrientation,
getMeasuredWidth(), getMeasuredWidth(),
@ -349,15 +370,6 @@ public class CameraView extends ViewGroup {
return outputOrientation; return outputOrientation;
} }
private void postRequestLayout() {
post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
}
private @NonNull CameraInfo getCameraInfo() { private @NonNull CameraInfo getCameraInfo() {
final CameraInfo info = new Camera.CameraInfo(); final CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info); Camera.getCameraInfo(cameraId, info);
@ -553,7 +565,11 @@ public class CameraView extends ViewGroup {
@Override @Override
protected void onPostExecute(byte[] imageBytes) { protected void onPostExecute(byte[] imageBytes) {
if (imageBytes != null && listener != null) listener.onImageCapture(imageBytes); if (imageBytes != null) {
for (CameraViewListener listener : listeners) {
listener.onImageCapture(imageBytes);
}
}
} }
} }
@ -562,6 +578,8 @@ public class CameraView extends ViewGroup {
public interface CameraViewListener { public interface CameraViewListener {
void onImageCapture(@NonNull final byte[] imageBytes); void onImageCapture(@NonNull final byte[] imageBytes);
void onCameraFail(); void onCameraFail();
void onCameraStart();
void onCameraStop();
} }
public interface PreviewCallback { public interface PreviewCallback {

View File

@ -31,7 +31,7 @@ import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.ViewUtil;
public class QuickAttachmentDrawer extends ViewGroup implements InputView { public class QuickAttachmentDrawer extends ViewGroup implements InputView, CameraViewListener {
private static final String TAG = QuickAttachmentDrawer.class.getSimpleName(); private static final String TAG = QuickAttachmentDrawer.class.getSimpleName();
private final ViewDragHelper dragHelper; private final ViewDragHelper dragHelper;
@ -80,6 +80,7 @@ public class QuickAttachmentDrawer extends ViewGroup implements InputView {
coverViewPosition = getChildCount(); coverViewPosition = getChildCount();
controls.setVisibility(GONE); controls.setVisibility(GONE);
cameraView.setVisibility(GONE); cameraView.setVisibility(GONE);
cameraView.addListener(this);
} }
public static boolean isDeviceSupported(Context context) { public static boolean isDeviceSupported(Context context) {
@ -337,7 +338,28 @@ public class QuickAttachmentDrawer extends ViewGroup implements InputView {
public void setListener(AttachmentDrawerListener listener) { public void setListener(AttachmentDrawerListener listener) {
this.listener = listener; this.listener = listener;
if (cameraView != null) cameraView.setListener(listener); cameraView.addListener(listener);
}
@Override
public void onImageCapture(@NonNull byte[] imageBytes) {}
@Override
public void onCameraFail() {
swapCameraButton.setEnabled(false);
shutterButton.setEnabled(false);
}
@Override
public void onCameraStart() {
swapCameraButton.setEnabled(true);
shutterButton.setEnabled(true);
}
@Override
public void onCameraStop() {
swapCameraButton.setEnabled(false);
shutterButton.setEnabled(false);
} }
public interface AttachmentDrawerListener extends CameraViewListener { public interface AttachmentDrawerListener extends CameraViewListener {