show call duration in audio calls. fixes #3708
This commit is contained in:
parent
6daaca496b
commit
92fc22b313
|
@ -9,6 +9,7 @@ import android.content.pm.PackageManager;
|
||||||
import android.databinding.DataBindingUtil;
|
import android.databinding.DataBindingUtil;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
@ -27,7 +28,6 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
|
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
|
||||||
import org.webrtc.SurfaceViewRenderer;
|
import org.webrtc.SurfaceViewRenderer;
|
||||||
|
@ -49,6 +49,7 @@ import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
||||||
import eu.siacs.conversations.ui.util.MainThreadExecutor;
|
import eu.siacs.conversations.ui.util.MainThreadExecutor;
|
||||||
import eu.siacs.conversations.utils.PermissionUtils;
|
import eu.siacs.conversations.utils.PermissionUtils;
|
||||||
|
import eu.siacs.conversations.utils.TimeFrameUtils;
|
||||||
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
|
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
|
||||||
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
|
import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection;
|
||||||
import eu.siacs.conversations.xmpp.jingle.Media;
|
import eu.siacs.conversations.xmpp.jingle.Media;
|
||||||
|
@ -67,6 +68,9 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
public static final String ACTION_ACCEPT_CALL = "action_accept_call";
|
public static final String ACTION_ACCEPT_CALL = "action_accept_call";
|
||||||
public static final String ACTION_MAKE_VOICE_CALL = "action_make_voice_call";
|
public static final String ACTION_MAKE_VOICE_CALL = "action_make_voice_call";
|
||||||
public static final String ACTION_MAKE_VIDEO_CALL = "action_make_video_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 List<RtpEndUserState> END_CARD = Arrays.asList(
|
private static final List<RtpEndUserState> END_CARD = Arrays.asList(
|
||||||
RtpEndUserState.APPLICATION_ERROR,
|
RtpEndUserState.APPLICATION_ERROR,
|
||||||
RtpEndUserState.DECLINED_OR_BUSY,
|
RtpEndUserState.DECLINED_OR_BUSY,
|
||||||
|
@ -79,6 +83,15 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
private ActivityRtpSessionBinding binding;
|
private ActivityRtpSessionBinding binding;
|
||||||
private PowerManager.WakeLock mProximityWakeLock;
|
private PowerManager.WakeLock mProximityWakeLock;
|
||||||
|
|
||||||
|
private Handler mHandler = new Handler();
|
||||||
|
private Runnable mTickExecutor = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
updateCallDuration();
|
||||||
|
mHandler.postDelayed(mTickExecutor, CALL_DURATION_UPDATE_INTERVAL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private static Set<Media> actionToMedia(final String action) {
|
private static Set<Media> actionToMedia(final String action) {
|
||||||
if (ACTION_MAKE_VIDEO_CALL.equals(action)) {
|
if (ACTION_MAKE_VIDEO_CALL.equals(action)) {
|
||||||
return ImmutableSet.of(Media.AUDIO, Media.VIDEO);
|
return ImmutableSet.of(Media.AUDIO, Media.VIDEO);
|
||||||
|
@ -308,8 +321,15 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
mHandler.postDelayed(mTickExecutor, CALL_DURATION_UPDATE_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
|
mHandler.removeCallbacks(mTickExecutor);
|
||||||
binding.remoteVideo.release();
|
binding.remoteVideo.release();
|
||||||
binding.localVideo.release();
|
binding.localVideo.release();
|
||||||
final WeakReference<JingleRtpConnection> weakReference = this.rtpConnectionReference;
|
final WeakReference<JingleRtpConnection> weakReference = this.rtpConnectionReference;
|
||||||
|
@ -684,6 +704,25 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
this.binding.inCallActionLeft.setVisibility(View.VISIBLE);
|
this.binding.inCallActionLeft.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateCallDuration() {
|
||||||
|
Log.d(Config.LOGTAG,"updateCallDuration()");
|
||||||
|
final JingleRtpConnection connection = this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null;
|
||||||
|
if (connection == null || connection.getMedia().contains(Media.VIDEO)) {
|
||||||
|
Log.d(Config.LOGTAG,"rtpConnection was null or contained video");
|
||||||
|
this.binding.duration.setVisibility(View.GONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final long rtpConnectionStarted = connection.getRtpConnectionStarted();
|
||||||
|
final long rtpConnectionEnded = connection.getRtpConnectionEnded();
|
||||||
|
if (rtpConnectionStarted != 0) {
|
||||||
|
final long ended = rtpConnectionEnded == 0 ? SystemClock.elapsedRealtime() : rtpConnectionEnded;
|
||||||
|
this.binding.duration.setText(TimeFrameUtils.formatTimePassed(rtpConnectionStarted, ended, false));
|
||||||
|
this.binding.duration.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
this.binding.duration.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateVideoViews(final RtpEndUserState state) {
|
private void updateVideoViews(final RtpEndUserState state) {
|
||||||
if (END_CARD.contains(state) || state == RtpEndUserState.ENDING_CALL) {
|
if (END_CARD.contains(state) || state == RtpEndUserState.ENDING_CALL) {
|
||||||
binding.localVideo.setVisibility(View.GONE);
|
binding.localVideo.setVisibility(View.GONE);
|
||||||
|
|
|
@ -125,6 +125,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
private RtpContentMap initiatorRtpContentMap;
|
private RtpContentMap initiatorRtpContentMap;
|
||||||
private RtpContentMap responderRtpContentMap;
|
private RtpContentMap responderRtpContentMap;
|
||||||
private long rtpConnectionStarted = 0; //time of 'connected'
|
private long rtpConnectionStarted = 0; //time of 'connected'
|
||||||
|
private long rtpConnectionEnded = 0;
|
||||||
private ScheduledFuture<?> ringingTimeoutFuture;
|
private ScheduledFuture<?> ringingTimeoutFuture;
|
||||||
|
|
||||||
JingleRtpConnection(JingleConnectionManager jingleConnectionManager, Id id, Jid initiator) {
|
JingleRtpConnection(JingleConnectionManager jingleConnectionManager, Id id, Jid initiator) {
|
||||||
|
@ -1006,6 +1007,9 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
if (newState == PeerConnection.PeerConnectionState.CONNECTED && this.rtpConnectionStarted == 0) {
|
if (newState == PeerConnection.PeerConnectionState.CONNECTED && this.rtpConnectionStarted == 0) {
|
||||||
this.rtpConnectionStarted = SystemClock.elapsedRealtime();
|
this.rtpConnectionStarted = SystemClock.elapsedRealtime();
|
||||||
}
|
}
|
||||||
|
if (newState == PeerConnection.PeerConnectionState.CLOSED && this.rtpConnectionEnded == 0) {
|
||||||
|
this.rtpConnectionEnded = SystemClock.elapsedRealtime();
|
||||||
|
}
|
||||||
//TODO 'DISCONNECTED' might be an opportunity to renew the offer and send a transport-replace
|
//TODO 'DISCONNECTED' might be an opportunity to renew the offer and send a transport-replace
|
||||||
//TODO exact syntax is yet to be determined but transport-replace sounds like the most reasonable
|
//TODO exact syntax is yet to be determined but transport-replace sounds like the most reasonable
|
||||||
//as there is no content-replace
|
//as there is no content-replace
|
||||||
|
@ -1031,6 +1035,14 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getRtpConnectionStarted() {
|
||||||
|
return this.rtpConnectionStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRtpConnectionEnded() {
|
||||||
|
return this.rtpConnectionEnded;
|
||||||
|
}
|
||||||
|
|
||||||
public AppRTCAudioManager getAudioManager() {
|
public AppRTCAudioManager getAudioManager() {
|
||||||
return webRTCWrapper.getAudioManager();
|
return webRTCWrapper.getAudioManager();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,21 +62,29 @@
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_above="@+id/button_row"
|
android:layout_above="@+id/button_row"
|
||||||
android:layout_below="@id/app_bar_layout"
|
android:layout_below="@id/app_bar_layout">
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal">
|
<TextView
|
||||||
|
android:id="@+id/duration"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_margin="24dp"
|
||||||
|
android:textAppearance="@style/TextAppearance.Conversations.Title.Monospace"
|
||||||
|
tools:text="01:23" />
|
||||||
|
|
||||||
<com.makeramen.roundedimageview.RoundedImageView
|
<com.makeramen.roundedimageview.RoundedImageView
|
||||||
android:id="@+id/contact_photo"
|
android:id="@+id/contact_photo"
|
||||||
android:layout_width="@dimen/publish_avatar_size"
|
android:layout_width="@dimen/publish_avatar_size"
|
||||||
android:layout_height="@dimen/publish_avatar_size"
|
android:layout_height="@dimen/publish_avatar_size"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
app:riv_corner_radius="@dimen/incoming_call_radius" />
|
app:riv_corner_radius="@dimen/incoming_call_radius" />
|
||||||
|
|
||||||
</LinearLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
<org.webrtc.SurfaceViewRenderer
|
<org.webrtc.SurfaceViewRenderer
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
<item name="android:typeface">monospace</item>
|
<item name="android:typeface">monospace</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="TextAppearance.Conversations.Title.Monospace" parent="TextAppearance.Conversations.Title">
|
||||||
|
<item name="android:fontFamily" tools:targetApi="jelly_bean">monospace</item>
|
||||||
|
<item name="android:typeface">monospace</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="TextAppearance.Conversations.Display2" parent="TextAppearance.AppCompat.Display2">
|
<style name="TextAppearance.Conversations.Display2" parent="TextAppearance.AppCompat.Display2">
|
||||||
<item name="android:textSize">?TextSizeDisplay2</item>
|
<item name="android:textSize">?TextSizeDisplay2</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue