@@ -9,6 +9,7 @@ import android.content.pm.PackageManager;
import android.databinding.DataBindingUtil;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
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.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
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.MainThreadExecutor;
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.JingleRtpConnection;
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_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 List<RtpEndUserState> END_CARD = Arrays.asList(
RtpEndUserState.APPLICATION_ERROR,
RtpEndUserState.DECLINED_OR_BUSY,
@@ -79,6 +83,15 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
private ActivityRtpSessionBinding binding;
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) {
if (ACTION_MAKE_VIDEO_CALL.equals(action)) {
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
public void onStop() {
+ mHandler.removeCallbacks(mTickExecutor);
binding.remoteVideo.release();
binding.localVideo.release();
final WeakReference<JingleRtpConnection> weakReference = this.rtpConnectionReference;
@@ -655,7 +675,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
@Override
public void onFailure(@NonNull final Throwable throwable) {
- Log.d(Config.LOGTAG,"could not switch camera", Throwables.getRootCause(throwable));
+ Log.d(Config.LOGTAG, "could not switch camera", Throwables.getRootCause(throwable));
Toast.makeText(RtpSessionActivity.this, R.string.could_not_switch_camera, Toast.LENGTH_LONG).show();
}
}, MainThreadExecutor.getInstance());
@@ -684,6 +704,25 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
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) {
if (END_CARD.contains(state) || state == RtpEndUserState.ENDING_CALL) {
binding.localVideo.setVisibility(View.GONE);
@@ -125,6 +125,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
private RtpContentMap initiatorRtpContentMap;
private RtpContentMap responderRtpContentMap;
private long rtpConnectionStarted = 0; //time of 'connected'
+ private long rtpConnectionEnded = 0;
private ScheduledFuture<?> ringingTimeoutFuture;
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) {
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 exact syntax is yet to be determined but transport-replace sounds like the most reasonable
//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() {
return webRTCWrapper.getAudioManager();
}
@@ -62,21 +62,29 @@
</android.support.design.widget.AppBarLayout>
- <LinearLayout
+ <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/button_row"
- android:layout_below="@id/app_bar_layout"
- android:gravity="center"
- android:orientation="horizontal">
+ android:layout_below="@id/app_bar_layout">
+
+ <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
android:id="@+id/contact_photo"
android:layout_width="@dimen/publish_avatar_size"
android:layout_height="@dimen/publish_avatar_size"
+ android:layout_centerInParent="true"
app:riv_corner_radius="@dimen/incoming_call_radius" />
- </LinearLayout>
+ </RelativeLayout>
<org.webrtc.SurfaceViewRenderer
@@ -5,6 +5,11 @@
<item name="android:typeface">monospace</item>
</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">
<item name="android:textSize">?TextSizeDisplay2</item>
</style>