Clean up camera flipping, handle having missing cameras.

Did a refactor to better organize the camera flipping code. Also, I
wanted to make sure we handle the cases where the user doesn't have two
cameras (or no cameras, for that matter). In these cases, we just don't
show the appropriate buttons.
This commit is contained in:
Greyson Parrelli
2018-04-25 11:00:03 -07:00
parent f1c79eaebf
commit ca8fecea9c
11 changed files with 372 additions and 258 deletions

View File

@@ -5,8 +5,8 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.AccessibleToggleButton;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.webrtc.CameraState;
public class WebRtcCallControls extends LinearLayout {
@@ -27,9 +28,10 @@ public class WebRtcCallControls extends LinearLayout {
private AccessibleToggleButton audioMuteButton;
private AccessibleToggleButton videoMuteButton;
private AccessibleToggleButton cameraFlipButton;
private AccessibleToggleButton speakerButton;
private AccessibleToggleButton bluetoothButton;
private AccessibleToggleButton cameraFlipButton;
private boolean cameraFlipAvailable;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public WebRtcCallControls(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
@@ -62,7 +64,6 @@ public class WebRtcCallControls extends LinearLayout {
this.audioMuteButton = ViewUtil.findById(this, R.id.muteButton);
this.videoMuteButton = ViewUtil.findById(this, R.id.video_mute_button);
this.cameraFlipButton = ViewUtil.findById(this, R.id.camera_flip_button);
this.cameraFlipButton.setVisibility(View.INVISIBLE); // shown once video is enabled
}
public void setAudioMuteButtonListener(final MuteButtonListener listener) {
@@ -80,7 +81,7 @@ public class WebRtcCallControls extends LinearLayout {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
boolean videoMuted = !isChecked;
listener.onToggle(videoMuted);
cameraFlipButton.setVisibility(videoMuted ? View.INVISIBLE : View.VISIBLE);
cameraFlipButton.setVisibility(!videoMuted && cameraFlipAvailable ? View.VISIBLE : View.GONE);
}
});
}
@@ -89,7 +90,10 @@ public class WebRtcCallControls extends LinearLayout {
cameraFlipButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
listener.onToggle(isChecked);
listener.onToggle();
cameraFlipButton.setBackgroundResource(isChecked ? R.drawable.webrtc_camera_front_button
: R.drawable.webrtc_camera_rear_button);
cameraFlipButton.setEnabled(false);
}
});
}
@@ -143,40 +147,46 @@ public class WebRtcCallControls extends LinearLayout {
videoMuteButton.setChecked(enabled, false);
}
public void setVideoAvailable(boolean available) {
videoMuteButton.setVisibility(available ? VISIBLE : GONE);
}
public void setCameraFlipButtonEnabled(boolean enabled) {
cameraFlipButton.setChecked(enabled, false);
}
public void setCameraFlipAvailable(boolean available) {
cameraFlipAvailable = available;
}
public void setCameraFlipClickable(boolean clickable) {
setControlEnabled(cameraFlipButton, clickable);
}
public void setMicrophoneEnabled(boolean enabled) {
audioMuteButton.setChecked(!enabled, false);
}
public void setControlsEnabled(boolean enabled) {
if (enabled && Build.VERSION.SDK_INT >= 11) {
speakerButton.setAlpha(1.0f);
bluetoothButton.setAlpha(1.0f);
videoMuteButton.setAlpha(1.0f);
cameraFlipButton.setAlpha(1.0f);
audioMuteButton.setAlpha(1.0f);
setControlEnabled(speakerButton, enabled);
setControlEnabled(bluetoothButton, enabled);
setControlEnabled(videoMuteButton, enabled);
setControlEnabled(cameraFlipButton, enabled);
setControlEnabled(audioMuteButton, enabled);
}
speakerButton.setEnabled(true);
bluetoothButton.setEnabled(true);
videoMuteButton.setEnabled(true);
cameraFlipButton.setEnabled(true);
audioMuteButton.setEnabled(true);
} else if (!enabled && Build.VERSION.SDK_INT >= 11) {
speakerButton.setAlpha(0.3f);
bluetoothButton.setAlpha(0.3f);
videoMuteButton.setAlpha(0.3f);
cameraFlipButton.setAlpha(0.3f);
audioMuteButton.setAlpha(0.3f);
speakerButton.setEnabled(false);
bluetoothButton.setEnabled(false);
videoMuteButton.setEnabled(false);
cameraFlipButton.setEnabled(false);
audioMuteButton.setEnabled(false);
private void setControlEnabled(@NonNull View view, boolean enabled) {
if (enabled) {
view.setAlpha(1.0f);
view.setEnabled(true);
} else {
view.setAlpha(0.3f);
view.setEnabled(false);
}
}
public void displayVideoTooltip(ViewGroup viewGroup) {
if (Build.VERSION.SDK_INT > 15) {
if (Build.VERSION.SDK_INT > 15 && videoMuteButton.getVisibility() == VISIBLE) {
final ToolTipsManager toolTipsManager = new ToolTipsManager();
ToolTip toolTip = new ToolTip.Builder(getContext(), videoMuteButton, viewGroup,
@@ -184,12 +194,7 @@ public class WebRtcCallControls extends LinearLayout {
ToolTip.POSITION_BELOW).build();
toolTipsManager.show(toolTip);
videoMuteButton.postDelayed(new Runnable() {
@Override
public void run() {
toolTipsManager.findAndDismiss(videoMuteButton);
}
}, 4000);
videoMuteButton.postDelayed(() -> toolTipsManager.findAndDismiss(videoMuteButton), 4000);
}
}
@@ -198,7 +203,7 @@ public class WebRtcCallControls extends LinearLayout {
}
public static interface CameraFlipButtonListener {
public void onToggle(boolean isRear);
public void onToggle();
}
public static interface SpeakerButtonListener {

View File

@@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.service.WebRtcCallService;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.VerifySpan;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.webrtc.CameraState;
import org.webrtc.SurfaceViewRenderer;
import org.whispersystems.libsignal.IdentityKey;
@@ -62,6 +63,7 @@ public class WebRtcCallScreen extends FrameLayout implements RecipientModifiedLi
private static final String TAG = WebRtcCallScreen.class.getSimpleName();
private ImageView photo;
private SurfaceViewRenderer localRenderer;
private PercentFrameLayout localRenderLayout;
private PercentFrameLayout remoteRenderLayout;
private TextView name;
@@ -187,14 +189,19 @@ public class WebRtcCallScreen extends FrameLayout implements RecipientModifiedLi
this.controls.setControlsEnabled(enabled);
}
public void setLocalVideoEnabled(boolean enabled) {
if (enabled && this.localRenderLayout.isHidden()) {
this.controls.setVideoEnabled(true);
this.localRenderLayout.setHidden(false);
this.localRenderLayout.requestLayout();
} else if (!enabled && !this.localRenderLayout.isHidden()){
this.controls.setVideoEnabled(false);
this.localRenderLayout.setHidden(true);
public void setLocalVideoState(@NonNull CameraState cameraState) {
this.controls.setVideoAvailable(cameraState.getCameraCount() > 0);
this.controls.setVideoEnabled(cameraState.isEnabled());
this.controls.setCameraFlipAvailable(cameraState.getCameraCount() > 1);
this.controls.setCameraFlipClickable(cameraState.getActiveDirection() != CameraState.Direction.PENDING);
this.controls.setCameraFlipButtonEnabled(cameraState.getActiveDirection() == CameraState.Direction.BACK);
if (this.localRenderer != null) {
this.localRenderer.setMirror(cameraState.getActiveDirection() == CameraState.Direction.FRONT);
}
if (this.localRenderLayout.isHidden() == cameraState.isEnabled()) {
this.localRenderLayout.setHidden(!cameraState.isEnabled());
this.localRenderLayout.requestLayout();
}
}
@@ -276,6 +283,8 @@ public class WebRtcCallScreen extends FrameLayout implements RecipientModifiedLi
localRenderLayout.addView(localRenderer);
remoteRenderLayout.addView(remoteRenderer);
this.localRenderer = localRenderer;
}
}