forked from mirror/monocles_chat_clean
hide button in video call after timeout
This commit is contained in:
parent
7897b2d1ca
commit
34b8722434
3 changed files with 116 additions and 23 deletions
|
@ -32,6 +32,7 @@ import androidx.annotation.RequiresApi;
|
|||
import androidx.annotation.StringRes;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
|
@ -100,7 +101,8 @@ public class RtpSessionActivity extends XmppActivity
|
|||
public static final String ACTION_MAKE_VOICE_CALL = "action_make_voice_call";
|
||||
public static final String ACTION_MAKE_VIDEO_CALL = "action_make_video_call";
|
||||
|
||||
private static final int CALL_DURATION_UPDATE_INTERVAL = 333;
|
||||
private static final int CALL_DURATION_UPDATE_INTERVAL = 250;
|
||||
private static final int BUTTON_VISIBILITY_TIMEOUT = 10_000;
|
||||
|
||||
public static final List<RtpEndUserState> END_CARD =
|
||||
Arrays.asList(
|
||||
|
@ -155,6 +157,8 @@ public class RtpSessionActivity extends XmppActivity
|
|||
mHandler.postDelayed(mTickExecutor, CALL_DURATION_UPDATE_INTERVAL);
|
||||
}
|
||||
};
|
||||
private boolean buttonsHiddenAfterTimeout = false;
|
||||
private final Runnable mVisibilityToggleExecutor = this::updateButtonInVideoCallVisibility;
|
||||
|
||||
public static Set<Media> actionToMedia(final String action) {
|
||||
if (ACTION_MAKE_VIDEO_CALL.equals(action)) {
|
||||
|
@ -191,6 +195,8 @@ public class RtpSessionActivity extends XmppActivity
|
|||
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|
||||
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_rtp_session);
|
||||
this.binding.remoteVideo.setOnClickListener(this::onVideoScreenClick);
|
||||
this.binding.localVideo.setOnClickListener(this::onVideoScreenClick);
|
||||
setSupportActionBar(binding.toolbar);
|
||||
|
||||
binding.dialpad.setClickConsumer(tag -> {
|
||||
|
@ -207,6 +213,10 @@ public class RtpSessionActivity extends XmppActivity
|
|||
Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
|
||||
}
|
||||
|
||||
private void onVideoScreenClick(final View view) {
|
||||
resetVisibilityExecutorShowButtons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.activity_rtp_session, menu);
|
||||
|
@ -655,12 +665,20 @@ public class RtpSessionActivity extends XmppActivity
|
|||
public void onStart() {
|
||||
super.onStart();
|
||||
mHandler.postDelayed(mTickExecutor, CALL_DURATION_UPDATE_INTERVAL);
|
||||
mHandler.postDelayed(mVisibilityToggleExecutor, BUTTON_VISIBILITY_TIMEOUT);
|
||||
this.binding.remoteVideo.setOnAspectRatioChanged(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
resetVisibilityExecutorShowButtons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
mHandler.removeCallbacks(mTickExecutor);
|
||||
mHandler.removeCallbacks(mVisibilityToggleExecutor);
|
||||
binding.remoteVideo.release();
|
||||
binding.remoteVideo.setOnAspectRatioChanged(null);
|
||||
binding.localVideo.release();
|
||||
|
@ -782,6 +800,17 @@ public class RtpSessionActivity extends XmppActivity
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isInConnectedVideoCall() {
|
||||
final JingleRtpConnection rtpConnection;
|
||||
try {
|
||||
rtpConnection = requireRtpConnection();
|
||||
} catch (final IllegalStateException e) {
|
||||
return false;
|
||||
}
|
||||
return rtpConnection.getMedia().contains(Media.VIDEO)
|
||||
&& rtpConnection.getEndUserState() == RtpEndUserState.CONNECTED;
|
||||
}
|
||||
|
||||
private boolean initializeActivityWithRunningRtpSession(
|
||||
final Account account, Jid with, String sessionId) {
|
||||
final WeakReference<JingleRtpConnection> reference =
|
||||
|
@ -885,7 +914,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
final ContentAddition contentAddition) {
|
||||
switch (state) {
|
||||
case INCOMING_CALL -> {
|
||||
Preconditions.checkArgument(media.size() > 0, "Media must not be empty");
|
||||
Preconditions.checkArgument(!media.isEmpty(), "Media must not be empty");
|
||||
if (media.contains(Media.VIDEO)) {
|
||||
setTitle(R.string.rtp_state_incoming_video_call);
|
||||
} else {
|
||||
|
@ -976,7 +1005,9 @@ public class RtpSessionActivity extends XmppActivity
|
|||
final RtpEndUserState state,
|
||||
final Set<Media> media,
|
||||
final ContentAddition contentAddition) {
|
||||
if (state == RtpEndUserState.ENDING_CALL || isPictureInPicture()) {
|
||||
if (state == RtpEndUserState.ENDING_CALL
|
||||
|| isPictureInPicture()
|
||||
|| this.buttonsHiddenAfterTimeout) {
|
||||
this.binding.rejectCall.setVisibility(View.INVISIBLE);
|
||||
this.binding.endCall.setVisibility(View.INVISIBLE);
|
||||
this.binding.acceptCall.setVisibility(View.INVISIBLE);
|
||||
|
@ -1033,12 +1064,17 @@ public class RtpSessionActivity extends XmppActivity
|
|||
this.binding.endCall.setContentDescription(getString(R.string.hang_up));
|
||||
this.binding.endCall.setOnClickListener(this::endCall);
|
||||
this.binding.endCall.setImageResource(R.drawable.ic_call_end_24dp);
|
||||
this.binding.endCall.setVisibility(View.VISIBLE);
|
||||
setVisibleAndShow(this.binding.endCall);
|
||||
this.binding.acceptCall.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
updateInCallButtonConfiguration(state, media);
|
||||
}
|
||||
|
||||
private static void setVisibleAndShow(final FloatingActionButton button) {
|
||||
button.show();
|
||||
button.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private boolean isPictureInPicture() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
return isInPictureInPictureMode();
|
||||
|
@ -1055,7 +1091,8 @@ public class RtpSessionActivity extends XmppActivity
|
|||
@SuppressLint("RestrictedApi")
|
||||
private void updateInCallButtonConfiguration(
|
||||
final RtpEndUserState state, final Set<Media> media) {
|
||||
if (STATES_CONSIDERED_CONNECTED.contains(state) && !isPictureInPicture()) {
|
||||
final var showButtons = !isPictureInPicture() && !buttonsHiddenAfterTimeout;
|
||||
if (STATES_CONSIDERED_CONNECTED.contains(state) && showButtons) {
|
||||
Preconditions.checkArgument(!media.isEmpty(), "Media must not be empty");
|
||||
if (media.contains(Media.VIDEO)) {
|
||||
final JingleRtpConnection rtpConnection = requireRtpConnection();
|
||||
|
@ -1075,7 +1112,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
this.binding.inCallActionLeft.setVisibility(View.GONE);
|
||||
}
|
||||
} else if (STATES_SHOWING_SPEAKER_CONFIGURATION.contains(state)
|
||||
&& !isPictureInPicture()
|
||||
&& showButtons
|
||||
&& Media.audioOnly(media)) {
|
||||
final CallIntegration callIntegration;
|
||||
try {
|
||||
|
@ -1140,17 +1177,17 @@ public class RtpSessionActivity extends XmppActivity
|
|||
this.binding.inCallActionRight.setClickable(false);
|
||||
}
|
||||
}
|
||||
this.binding.inCallActionRight.setVisibility(View.VISIBLE);
|
||||
setVisibleAndShow(this.binding.inCallActionRight);
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
private void updateInCallButtonConfigurationVideo(
|
||||
final boolean videoEnabled, final boolean isCameraSwitchable) {
|
||||
this.binding.inCallActionRight.setVisibility(View.VISIBLE);
|
||||
setVisibleAndShow(this.binding.inCallActionRight);
|
||||
if (isCameraSwitchable) {
|
||||
this.binding.inCallActionFarRight.setImageResource(
|
||||
R.drawable.ic_flip_camera_android_24dp);
|
||||
this.binding.inCallActionFarRight.setVisibility(View.VISIBLE);
|
||||
setVisibleAndShow(this.binding.inCallActionFarRight);
|
||||
this.binding.inCallActionFarRight.setOnClickListener(this::switchCamera);
|
||||
this.binding.inCallActionFarRight.setContentDescription(
|
||||
getString(R.string.flip_camera));
|
||||
|
@ -1171,6 +1208,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
}
|
||||
|
||||
private void switchCamera(final View view) {
|
||||
resetVisibilityToggleExecutor();
|
||||
Futures.addCallback(
|
||||
requireRtpConnection().switchCamera(),
|
||||
new FutureCallback<>() {
|
||||
|
@ -1196,6 +1234,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
}
|
||||
|
||||
private void enableVideo(final View view) {
|
||||
resetVisibilityToggleExecutor();
|
||||
try {
|
||||
requireRtpConnection().setVideoEnabled(true);
|
||||
} catch (final IllegalStateException e) {
|
||||
|
@ -1206,6 +1245,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
}
|
||||
|
||||
private void disableVideo(final View view) {
|
||||
resetVisibilityToggleExecutor();
|
||||
final JingleRtpConnection rtpConnection = requireRtpConnection();
|
||||
final ContentAddition pending = rtpConnection.getPendingContentAddition();
|
||||
if (pending != null && pending.direction == ContentAddition.Direction.OUTGOING) {
|
||||
|
@ -1230,7 +1270,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
this.binding.inCallActionLeft.setImageResource(R.drawable.ic_mic_off_24dp);
|
||||
this.binding.inCallActionLeft.setOnClickListener(this::enableMicrophone);
|
||||
}
|
||||
this.binding.inCallActionLeft.setVisibility(View.VISIBLE);
|
||||
setVisibleAndShow(this.binding.inCallActionLeft);
|
||||
}
|
||||
|
||||
private void updateCallDuration() {
|
||||
|
@ -1249,6 +1289,47 @@ public class RtpSessionActivity extends XmppActivity
|
|||
}
|
||||
}
|
||||
|
||||
private void resetVisibilityToggleExecutor() {
|
||||
mHandler.removeCallbacks(this.mVisibilityToggleExecutor);
|
||||
mHandler.postDelayed(this.mVisibilityToggleExecutor, BUTTON_VISIBILITY_TIMEOUT);
|
||||
}
|
||||
|
||||
private void updateButtonInVideoCallVisibility() {
|
||||
if (isInConnectedVideoCall()) {
|
||||
if (isPictureInPicture()) {
|
||||
return;
|
||||
}
|
||||
Log.d(Config.LOGTAG, "hiding in-call buttons after timeout was reached");
|
||||
hideInCallButtons();
|
||||
}
|
||||
}
|
||||
|
||||
private void hideInCallButtons() {
|
||||
binding.inCallActionLeft.hide();
|
||||
binding.endCall.hide();
|
||||
binding.inCallActionRight.hide();
|
||||
binding.inCallActionFarRight.hide();
|
||||
}
|
||||
|
||||
private void showInCallButtons() {
|
||||
this.buttonsHiddenAfterTimeout = false;
|
||||
final JingleRtpConnection rtpConnection;
|
||||
try {
|
||||
rtpConnection = requireRtpConnection();
|
||||
} catch (final IllegalStateException e) {
|
||||
return;
|
||||
}
|
||||
updateButtonConfiguration(
|
||||
rtpConnection.getEndUserState(),
|
||||
rtpConnection.getMedia(),
|
||||
rtpConnection.getPendingContentAddition());
|
||||
}
|
||||
|
||||
private void resetVisibilityExecutorShowButtons() {
|
||||
resetVisibilityToggleExecutor();
|
||||
showInCallButtons();
|
||||
}
|
||||
|
||||
private void updateVideoViews(final RtpEndUserState state) {
|
||||
if (END_CARD.contains(state) || state == RtpEndUserState.ENDING_CALL) {
|
||||
binding.localVideo.setVisibility(View.GONE);
|
||||
|
@ -1343,17 +1424,23 @@ public class RtpSessionActivity extends XmppActivity
|
|||
return connection.getRemoteVideoTrack();
|
||||
}
|
||||
|
||||
private void disableMicrophone(View view) {
|
||||
final JingleRtpConnection rtpConnection = requireRtpConnection();
|
||||
if (rtpConnection.setMicrophoneEnabled(false)) {
|
||||
updateInCallButtonConfiguration();
|
||||
}
|
||||
private void disableMicrophone(final View view) {
|
||||
setMicrophoneEnabled(false);
|
||||
}
|
||||
|
||||
private void enableMicrophone(View view) {
|
||||
final JingleRtpConnection rtpConnection = requireRtpConnection();
|
||||
if (rtpConnection.setMicrophoneEnabled(true)) {
|
||||
updateInCallButtonConfiguration();
|
||||
private void enableMicrophone(final View view) {
|
||||
setMicrophoneEnabled(true);
|
||||
}
|
||||
|
||||
private void setMicrophoneEnabled(final boolean enabled) {
|
||||
resetVisibilityExecutorShowButtons();
|
||||
try {
|
||||
final JingleRtpConnection rtpConnection = requireRtpConnection();
|
||||
if (rtpConnection.setMicrophoneEnabled(enabled)) {
|
||||
updateInCallButtonConfiguration();
|
||||
}
|
||||
} catch (final IllegalStateException e) {
|
||||
Toast.makeText(this, R.string.could_not_modify_call, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1362,7 +1449,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
requireCallIntegration().setAudioDevice(CallIntegration.AudioDevice.EARPIECE);
|
||||
acquireProximityWakeLock();
|
||||
} catch (final IllegalStateException e) {
|
||||
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(this, R.string.could_not_modify_call, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1371,7 +1458,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
requireCallIntegration().setAudioDevice(CallIntegration.AudioDevice.SPEAKER_PHONE);
|
||||
releaseProximityWakeLock();
|
||||
} catch (final IllegalStateException e) {
|
||||
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(this, R.string.could_not_modify_call, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1461,6 +1548,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
() -> getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON));
|
||||
}
|
||||
if (with.isBareJid()) {
|
||||
// TODO check for ENDED
|
||||
updateRtpSessionProposalState(account, with, state);
|
||||
return;
|
||||
}
|
||||
|
@ -1484,6 +1572,7 @@ public class RtpSessionActivity extends XmppActivity
|
|||
finish();
|
||||
return;
|
||||
}
|
||||
resetVisibilityToggleExecutor();
|
||||
runOnUiThread(
|
||||
() -> {
|
||||
updateStateDisplay(state, media, contentAddition);
|
||||
|
|
|
@ -121,7 +121,8 @@
|
|||
<eu.siacs.conversations.ui.widget.SurfaceViewRenderer
|
||||
android:id="@+id/remote_video"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:soundEffectsEnabled="false" />
|
||||
</LinearLayout>
|
||||
|
||||
<eu.siacs.conversations.ui.widget.SurfaceViewRenderer
|
||||
|
@ -132,6 +133,7 @@
|
|||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:soundEffectsEnabled="false"
|
||||
android:visibility="gone"
|
||||
app:elevation="4dp" />
|
||||
|
||||
|
@ -170,7 +172,8 @@
|
|||
<RelativeLayout
|
||||
android:layout_width="288dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true">
|
||||
android:layout_centerInParent="true"
|
||||
android:background="@android:color/transparent">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/reject_call"
|
||||
|
|
|
@ -1329,4 +1329,5 @@
|
|||
<string name="pref_export_settings_summary">Export the monocles chat app settings to the backup folder</string>
|
||||
<string name="success_import_settings">Settings successfully imported</string>
|
||||
<string name="error_import_settings">Error while importing the settings</string>
|
||||
<string name="could_not_modify_call">Could not modify call</string>
|
||||
</resources>
|
Loading…
Reference in a new issue