diff --git a/res/layout/quick_camera_controls.xml b/res/layout/quick_camera_controls.xml index 345578c937..7f9693a63c 100644 --- a/res/layout/quick_camera_controls.xml +++ b/res/layout/quick_camera_controls.xml @@ -14,6 +14,7 @@ android:layout_centerHorizontal="true" android:background="@drawable/quick_camera_shutter_ring" android:src="@drawable/quick_shutter_button" + android:enabled="false" android:padding="20dp"/> @@ -30,8 +31,9 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" - android:background="#00000000" + android:background="@drawable/circle_touch_highlight_background" android:src="@drawable/quick_camera_rear" + android:enabled="false" android:padding="20dp" android:visibility="invisible" tools:visibility="visible" /> diff --git a/res/layout/quick_camera_controls_land.xml b/res/layout/quick_camera_controls_land.xml index b00711eb4d..48b4f21d83 100644 --- a/res/layout/quick_camera_controls_land.xml +++ b/res/layout/quick_camera_controls_land.xml @@ -14,6 +14,7 @@ android:layout_centerVertical="true" android:background="@drawable/quick_camera_shutter_ring" android:src="@drawable/quick_shutter_button" + android:enabled="false" android:padding="20dp"/> @@ -30,8 +31,9 @@ android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentRight="true" - android:background="#00000000" + android:background="@drawable/circle_touch_highlight_background" android:src="@drawable/quick_camera_rear" + android:enabled="false" android:padding="20dp" android:visibility="invisible" tools:visibility="visible"/> diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java index 312a9225a3..d07eace41c 100644 --- a/src/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationActivity.java @@ -1362,6 +1362,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity quickAttachmentToggle.disable(); } + @Override + public void onCameraStart() {} + + @Override + public void onCameraStop() {} + @Override public void onRecorderStarted() { Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); diff --git a/src/org/thoughtcrime/securesms/components/camera/CameraView.java b/src/org/thoughtcrime/securesms/components/camera/CameraView.java index aced10202f..6a7205995e 100644 --- a/src/org/thoughtcrime/securesms/components/camera/CameraView.java +++ b/src/org/thoughtcrime/securesms/components/camera/CameraView.java @@ -37,6 +37,8 @@ import android.view.OrientationEventListener; import android.view.ViewGroup; import java.io.IOException; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; import org.thoughtcrime.securesms.ApplicationContext; @@ -59,10 +61,10 @@ public class CameraView extends ViewGroup { private volatile int cameraId = CameraInfo.CAMERA_FACING_BACK; private volatile int displayOrientation = -1; - private @NonNull State state = State.PAUSED; - private @Nullable Size previewSize; - private @Nullable CameraViewListener listener; - private int outputOrientation = -1; + private @NonNull State state = State.PAUSED; + private @Nullable Size previewSize; + private @NonNull List listeners = Collections.synchronizedList(new LinkedList()); + private int outputOrientation = -1; public CameraView(Context context) { this(context, null); @@ -102,7 +104,9 @@ public class CameraView extends ViewGroup { @Nullable Void onRunBackground() { try { + long openStartMillis = System.currentTimeMillis(); camera = Optional.fromNullable(Camera.open(cameraId)); + Log.w(TAG, "camera.open() -> " + (System.currentTimeMillis() - openStartMillis) + "ms"); synchronized (CameraView.this) { CameraView.this.notifyAll(); } @@ -117,7 +121,9 @@ public class CameraView extends ViewGroup { protected void onPostMain(Void avoid) { if (!camera.isPresent()) { Log.w(TAG, "tried to open camera but got null"); - if (listener != null) listener.onCameraFail(); + for (CameraViewListener listener : listeners) { + listener.onCameraFail(); + } return; } @@ -167,6 +173,10 @@ public class CameraView extends ViewGroup { Log.w(TAG, "onPause() completed"); } }); + + for (CameraViewListener listener : listeners) { + listener.onCameraStop(); + } } public boolean isStarted() { @@ -215,8 +225,8 @@ public class CameraView extends ViewGroup { if (camera.isPresent()) startPreview(camera.get().getParameters()); } - public void setListener(@Nullable CameraViewListener listener) { - this.listener = listener; + public void addListener(@NonNull CameraViewListener listener) { + listeners.add(listener); } public void setPreviewCallback(final @NonNull PreviewCallback previewCallback) { @@ -308,9 +318,19 @@ public class CameraView extends ViewGroup { } else { previewSize = parameters.getPreviewSize(); } + long previewStartMillis = System.currentTimeMillis(); camera.startPreview(); - postRequestLayout(); + Log.w(TAG, "camera.startPreview() -> " + (System.currentTimeMillis() - previewStartMillis) + "ms"); state = State.ACTIVE; + Util.runOnMain(new Runnable() { + @Override + public void run() { + requestLayout(); + for (CameraViewListener listener : listeners) { + listener.onCameraStart(); + } + } + }); } catch (Exception e) { Log.w(TAG, e); } @@ -328,6 +348,7 @@ public class CameraView extends ViewGroup { } } + private Size getPreferredPreviewSize(@NonNull Parameters parameters) { return CameraUtils.getPreferredPreviewSize(displayOrientation, getMeasuredWidth(), @@ -349,15 +370,6 @@ public class CameraView extends ViewGroup { return outputOrientation; } - private void postRequestLayout() { - post(new Runnable() { - @Override - public void run() { - requestLayout(); - } - }); - } - private @NonNull CameraInfo getCameraInfo() { final CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(cameraId, info); @@ -553,7 +565,11 @@ public class CameraView extends ViewGroup { @Override 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 { void onImageCapture(@NonNull final byte[] imageBytes); void onCameraFail(); + void onCameraStart(); + void onCameraStop(); } public interface PreviewCallback { diff --git a/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java b/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java index e790aa9c05..cc58be771c 100644 --- a/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java +++ b/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java @@ -31,7 +31,7 @@ import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.Util; 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 final ViewDragHelper dragHelper; @@ -80,6 +80,7 @@ public class QuickAttachmentDrawer extends ViewGroup implements InputView { coverViewPosition = getChildCount(); controls.setVisibility(GONE); cameraView.setVisibility(GONE); + cameraView.addListener(this); } public static boolean isDeviceSupported(Context context) { @@ -337,7 +338,28 @@ public class QuickAttachmentDrawer extends ViewGroup implements InputView { public void setListener(AttachmentDrawerListener 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 {