Browse Source

Reworked UI & Voice-only calls

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 7 years ago
parent
commit
f2aee50a74

+ 122 - 83
app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

@@ -198,10 +198,12 @@ public class CallActivity extends AppCompatActivity {
     private String credentials;
     private List<MagicPeerConnectionWrapper> magicPeerConnectionWrapperList = new ArrayList<>();
 
+    private List<String> basicUISetupList = new ArrayList<>();
     private boolean videoOn = false;
     private boolean audioOn = false;
 
     private boolean isMultiSession = false;
+    private boolean isVoiceOnlyCall = false;
 
     private Handler handler = new Handler();
 
@@ -211,8 +213,6 @@ public class CallActivity extends AppCompatActivity {
 
     private String baseUrl;
 
-    private boolean initialPermissionsCheck = true;
-
     private SpotlightView spotlightView;
 
     private static int getSystemUiVisibility() {
@@ -249,6 +249,7 @@ public class CallActivity extends AppCompatActivity {
         userEntity = Parcels.unwrap(getIntent().getExtras().getParcelable(BundleKeys.KEY_USER_ENTITY));
         callSession = getIntent().getExtras().getString(BundleKeys.KEY_CALL_SESSION, "0");
         credentials = ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken());
+        isVoiceOnlyCall = getIntent().getExtras().getBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, false);
 
         if (getIntent().getExtras().containsKey(BundleKeys.KEY_MODIFIED_BASE_URL)) {
             credentials = null;
@@ -442,6 +443,10 @@ public class CallActivity extends AppCompatActivity {
                 toggleMedia(true, false);
             }
 
+            if (isVoiceOnlyCall && !inCall) {
+                startCall();
+            }
+
         } else if (EffortlessPermissions.somePermissionPermanentlyDenied(this, PERMISSIONS_MICROPHONE)) {
             // Microphone permission is permanently denied so we cannot request it normally.
             OpenAppDetailsDialogFragment.show(
@@ -547,29 +552,39 @@ public class CallActivity extends AppCompatActivity {
     }
 
     public void initViews() {
-        if (cameraEnumerator.getDeviceNames().length < 2) {
+        if (isVoiceOnlyCall) {
             cameraSwitchButton.setVisibility(View.GONE);
-        }
+            cameraControlButton.setVisibility(View.GONE);
+            pipVideoView.setVisibility(View.GONE);
+        } else {
+            if (cameraEnumerator.getDeviceNames().length < 2) {
+                cameraSwitchButton.setVisibility(View.GONE);
+            }
 
-        // setting this to true because it's not shown by default
-        pipVideoView.setMirror(true);
-        pipVideoView.init(rootEglBase.getEglBaseContext(), null);
-        pipVideoView.setZOrderMediaOverlay(true);
-        // disabled because it causes some devices to crash
-        pipVideoView.setEnableHardwareScaler(false);
-        pipVideoView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
+            // setting this to true because it's not shown by default
+            pipVideoView.setMirror(true);
+            pipVideoView.init(rootEglBase.getEglBaseContext(), null);
+            pipVideoView.setZOrderMediaOverlay(true);
+            // disabled because it causes some devices to crash
+            pipVideoView.setEnableHardwareScaler(false);
+            pipVideoView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
+        }
     }
 
     private void checkPermissions() {
-        EffortlessPermissions.requestPermissions(this, R.string.nc_permissions,
-                R.string.nc_proceed, R.string.nc_empty, 100, PERMISSIONS_CALL);
+        if (isVoiceOnlyCall) {
+            onMicrophoneClick();
+        } else {
+            EffortlessPermissions.requestPermissions(this, R.string.nc_permissions,
+                    R.string.nc_proceed, R.string.nc_empty, 100, PERMISSIONS_CALL);
+        }
 
     }
 
     @AfterPermissionGranted(100)
     private void onPermissionsGranted() {
         if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CALL)) {
-            if (!videoOn && !initialPermissionsCheck) {
+            if (!videoOn && !isVoiceOnlyCall) {
                 onCameraClick();
             }
 
@@ -577,15 +592,13 @@ public class CallActivity extends AppCompatActivity {
                 onMicrophoneClick();
             }
 
-            if (cameraEnumerator.getDeviceNames().length == 0) {
-                cameraControlButton.setVisibility(View.GONE);
-            }
+            if (!isVoiceOnlyCall) {
+                if (cameraEnumerator.getDeviceNames().length == 0) {
+                    cameraControlButton.setVisibility(View.GONE);
+                }
 
-            if (cameraEnumerator.getDeviceNames().length > 1) {
-                if (!initialPermissionsCheck) {
+                if (cameraEnumerator.getDeviceNames().length > 1) {
                     cameraSwitchButton.setVisibility(View.VISIBLE);
-                } else {
-                    cameraSwitchButton.setVisibility(View.GONE);
                 }
             }
 
@@ -597,26 +610,27 @@ public class CallActivity extends AppCompatActivity {
             checkIfSomeAreApproved();
         }
 
-        initialPermissionsCheck = false;
     }
 
     private void checkIfSomeAreApproved() {
-        if (cameraEnumerator.getDeviceNames().length == 0) {
-            cameraControlButton.setVisibility(View.GONE);
-        }
+        if (!isVoiceOnlyCall) {
+            if (cameraEnumerator.getDeviceNames().length == 0) {
+                cameraControlButton.setVisibility(View.GONE);
+            }
 
-        if (cameraEnumerator.getDeviceNames().length > 1) {
-            cameraSwitchButton.setVisibility(View.VISIBLE);
-        }
+            if (cameraEnumerator.getDeviceNames().length > 1) {
+                cameraSwitchButton.setVisibility(View.VISIBLE);
+            }
 
-        if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA) && !initialPermissionsCheck) {
-            if (!videoOn) {
-                onCameraClick();
+            if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA)) {
+                if (!videoOn) {
+                    onCameraClick();
+                }
+            } else {
+                cameraControlButton.getFrontImageView().setImageResource(R.drawable.ic_videocam_off_white_24px);
+                cameraControlButton.setAlpha(0.7f);
+                cameraSwitchButton.setVisibility(View.GONE);
             }
-        } else {
-            cameraControlButton.getFrontImageView().setImageResource(R.drawable.ic_videocam_off_white_24px);
-            cameraControlButton.setAlpha(0.7f);
-            cameraSwitchButton.setVisibility(View.GONE);
         }
 
         if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_MICROPHONE)) {
@@ -634,11 +648,12 @@ public class CallActivity extends AppCompatActivity {
 
     @AfterPermissionDenied(100)
     private void onPermissionsDenied() {
-        initialPermissionsCheck = false;
-        if (cameraEnumerator.getDeviceNames().length == 0) {
-            cameraControlButton.setVisibility(View.GONE);
-        } else if (cameraEnumerator.getDeviceNames().length == 1) {
-            cameraSwitchButton.setVisibility(View.GONE);
+        if (!isVoiceOnlyCall) {
+            if (cameraEnumerator.getDeviceNames().length == 0) {
+                cameraControlButton.setVisibility(View.GONE);
+            } else if (cameraEnumerator.getDeviceNames().length == 1) {
+                cameraSwitchButton.setVisibility(View.GONE);
+            }
         }
 
         if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA) ||
@@ -685,11 +700,20 @@ public class CallActivity extends AppCompatActivity {
         //create sdpConstraints
         sdpConstraints = new MediaConstraints();
         sdpConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
-        sdpConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
+        String offerToReceiveVideoString = "true";
+
+        if (isVoiceOnlyCall) {
+            offerToReceiveVideoString = "false";
+        }
+
+        sdpConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo",
+                offerToReceiveVideoString));
         sdpConstraints.optional.add(new MediaConstraints.KeyValuePair("internalSctpDataChannels", "true"));
         sdpConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
 
-        cameraInitialization();
+        if (!isVoiceOnlyCall) {
+            cameraInitialization();
+        }
         microphoneInitialization();
     }
 
@@ -1163,31 +1187,7 @@ public class CallActivity extends AppCompatActivity {
 
                     @Override
                     public void onNext(GenericOverall genericOverall) {
-                        ncApi.leaveRoom(credentials, ApiUtils.getUrlForRoomParticipants(baseUrl, roomToken))
-                                .subscribeOn(Schedulers.newThread())
-                                .observeOn(AndroidSchedulers.mainThread())
-                                .subscribe(new Observer<GenericOverall>() {
-                                    @Override
-                                    public void onSubscribe(Disposable d) {
-
-                                    }
-
-                                    @Override
-                                    public void onNext(GenericOverall genericOverall) {
-                                        finish();
-                                    }
-
-                                    @Override
-                                    public void onError(Throwable e) {
-
-                                    }
-
-                                    @Override
-                                    public void onComplete() {
-
-                                    }
-                                });
-
+                        finish();
                     }
 
                     @Override
@@ -1214,8 +1214,19 @@ public class CallActivity extends AppCompatActivity {
         RelativeLayout relativeLayout = remoteRenderersLayout.findViewWithTag(sessionId);
         if (relativeLayout != null) {
             ImageView imageView;
+            ImageView avatarImageView = relativeLayout.findViewById(R.id.avatarImageView);
+            SurfaceViewRenderer surfaceViewRenderer = relativeLayout.findViewById(R.id.surface_view);
+
             if (video) {
                 imageView = relativeLayout.findViewById(R.id.remote_video_off);
+
+                if (change) {
+                    avatarImageView.setVisibility(View.INVISIBLE);
+                    surfaceViewRenderer.setVisibility(View.VISIBLE);
+                } else {
+                    avatarImageView.setVisibility(View.VISIBLE);
+                    surfaceViewRenderer.setVisibility(View.INVISIBLE);
+                }
             } else {
                 imageView = relativeLayout.findViewById(R.id.remote_audio_off);
             }
@@ -1228,14 +1239,12 @@ public class CallActivity extends AppCompatActivity {
         }
     }
 
-    private void gotRemoteStream(MediaStream stream, String session) {
-        removeMediaStream(session);
-
-        if (stream.videoTracks.size() == 1) {
-            VideoTrack videoTrack = stream.videoTracks.get(0);
-            try {
+    private void setupNewPeerLayout(String session) {
+        if (remoteRenderersLayout.findViewWithTag(session) == null) {
+            basicUISetupList.add(session);
+            runOnUiThread(() -> {
                 RelativeLayout relativeLayout = (RelativeLayout)
-                        getLayoutInflater().inflate(R.layout.surface_renderer, remoteRenderersLayout,
+                        getLayoutInflater().inflate(R.layout.call_item, remoteRenderersLayout,
                                 false);
                 relativeLayout.setTag(session);
                 SurfaceViewRenderer surfaceViewRenderer = relativeLayout.findViewById(R.id
@@ -1247,12 +1256,40 @@ public class CallActivity extends AppCompatActivity {
                 surfaceViewRenderer.setEnableHardwareScaler(false);
                 surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
                 surfaceViewRenderer.setOnClickListener(videoOnClickListener);
-                VideoRenderer remoteRenderer = new VideoRenderer(surfaceViewRenderer);
-                videoTrack.addRenderer(remoteRenderer);
                 remoteRenderersLayout.addView(relativeLayout);
                 gotNick(session, getPeerConnectionWrapperForSessionId(session).getNick());
-            } catch (Exception e) {
-                Log.d(TAG, "Failed to create a new video view");
+
+                basicUISetupList.remove(session);
+                callControls.setZ(100.0f);
+            });
+        }
+    }
+
+    private void setupVideoStreamForLayout(@Nullable MediaStream mediaStream, String session, boolean enable) {
+        boolean isInitialLayoutSetupForPeer = false;
+        if (remoteRenderersLayout.findViewWithTag(session) == null) {
+            setupNewPeerLayout(session);
+            isInitialLayoutSetupForPeer = true;
+        }
+
+        RelativeLayout relativeLayout = remoteRenderersLayout.findViewWithTag(session);
+        SurfaceViewRenderer surfaceViewRenderer = relativeLayout.findViewById(R.id.surface_view);
+        ImageView imageView = relativeLayout.findViewById(R.id.avatarImageView);
+
+        if (mediaStream != null && mediaStream.videoTracks != null && mediaStream.videoTracks.size() > 0 && enable) {
+            VideoTrack videoTrack = mediaStream.videoTracks.get(0);
+
+            VideoRenderer remoteRenderer = new VideoRenderer(surfaceViewRenderer);
+            videoTrack.addRenderer(remoteRenderer);
+
+            imageView.setVisibility(View.INVISIBLE);
+            surfaceViewRenderer.setVisibility(View.VISIBLE);
+        } else {
+            imageView.setVisibility(View.VISIBLE);
+            surfaceViewRenderer.setVisibility(View.INVISIBLE);
+
+            if (isInitialLayoutSetupForPeer && isVoiceOnlyCall) {
+                gotAudioOrVideoChange(true, session, false);
             }
         }
 
@@ -1310,8 +1347,8 @@ public class CallActivity extends AppCompatActivity {
 
     @Subscribe(threadMode = ThreadMode.BACKGROUND)
     public void onMessageEvent(PeerConnectionEvent peerConnectionEvent) {
-        if (peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent.PeerConnectionEventType
-                .CLOSE_PEER)) {
+ if (peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent.PeerConnectionEventType
+                .PEER_CLOSED)) {
             endPeerConnection(peerConnectionEvent.getSessionId());
         } else if (peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent
                 .PeerConnectionEventType.SENSOR_FAR) ||
@@ -1327,7 +1364,7 @@ public class CallActivity extends AppCompatActivity {
                 .PeerConnectionEventType.NICK_CHANGE)) {
             runOnUiThread(() -> gotNick(peerConnectionEvent.getSessionId(), peerConnectionEvent.getNick()));
         } else if (peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent
-                .PeerConnectionEventType.VIDEO_CHANGE)) {
+                .PeerConnectionEventType.VIDEO_CHANGE) && !isVoiceOnlyCall) {
             runOnUiThread(() -> gotAudioOrVideoChange(true, peerConnectionEvent.getSessionId(),
                     peerConnectionEvent.getChangeValue()));
         } else if (peerConnectionEvent.getPeerConnectionEventType().equals(PeerConnectionEvent
@@ -1362,9 +1399,11 @@ public class CallActivity extends AppCompatActivity {
     @Subscribe(threadMode = ThreadMode.MAIN)
     public void onMessageEvent(MediaStreamEvent mediaStreamEvent) {
         if (mediaStreamEvent.getMediaStream() != null) {
-            gotRemoteStream(mediaStreamEvent.getMediaStream(), mediaStreamEvent.getSession());
+            setupVideoStreamForLayout(mediaStreamEvent.getMediaStream(), mediaStreamEvent.getSession(),
+                    mediaStreamEvent.getMediaStream().videoTracks != null
+                            && mediaStreamEvent.getMediaStream().videoTracks.size() > 0);
         } else {
-            removeMediaStream(mediaStreamEvent.getSession());
+            setupVideoStreamForLayout(null, mediaStreamEvent.getSession(), false);
         }
     }
 

+ 1 - 1
app/src/main/java/com/nextcloud/talk/events/PeerConnectionEvent.java

@@ -40,6 +40,6 @@ public class PeerConnectionEvent {
     }
 
     public enum PeerConnectionEventType {
-        CLOSE_PEER, SENSOR_FAR, SENSOR_NEAR, NICK_CHANGE, AUDIO_CHANGE, VIDEO_CHANGE
+        PEER_CONNECTED, PEER_CLOSED, SENSOR_FAR, SENSOR_NEAR, NICK_CHANGE, AUDIO_CHANGE, VIDEO_CHANGE
     }
 }

+ 8 - 3
app/src/main/java/com/nextcloud/talk/webrtc/MagicPeerConnectionWrapper.java

@@ -55,6 +55,7 @@ public class MagicPeerConnectionWrapper {
     private PeerConnection peerConnection;
     private String sessionId;
     private String nick;
+    private String userId;
     private MediaConstraints mediaConstraints;
     private DataChannel magicDataChannel;
     private MagicSdpObserver magicSdpObserver;
@@ -248,11 +249,15 @@ public class MagicPeerConnectionWrapper {
 
         @Override
         public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
-            if (iceConnectionState.equals(PeerConnection.IceConnectionState.CONNECTED) && hasInitiated) {
-                sendInitialMediaStatus();
+            if (iceConnectionState.equals(PeerConnection.IceConnectionState.CONNECTED)) {
+                EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
+                        .PEER_CONNECTED, sessionId, null, null));
+                if (hasInitiated) {
+                    sendInitialMediaStatus();
+                }
             } else if (iceConnectionState.equals(PeerConnection.IceConnectionState.CLOSED)) {
                 EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
-                        .CLOSE_PEER, sessionId, null, null));
+                        .PEER_CLOSED, sessionId, null, null));
             }
         }
 

+ 0 - 1
app/src/main/res/layout/activity_call.xml

@@ -74,7 +74,6 @@
             android:layout_width="60dp"
             android:layout_height="60dp"
             android:layout_marginEnd="20dp"
-            android:alpha="0.7"
             android:visibility="gone"
             app:checked="false"
             app:enableInitialAnimation="false"

+ 9 - 1
app/src/main/res/layout/surface_renderer.xml → app/src/main/res/layout/call_item.xml

@@ -29,7 +29,15 @@
     <org.webrtc.SurfaceViewRenderer
         android:id="@+id/surface_view"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
+        android:layout_height="match_parent"
+        android:visibility="invisible"/>
+
+    <ImageView
+        android:layout_width="80dp"
+        android:layout_height="80dp"
+        android:id="@+id/avatarImageView"
+        android:layout_centerInParent="true"
+        android:src="@drawable/ic_baseline_arrow_downward_24px"/>
 
     <ImageView
         android:id="@+id/remote_video_off"

+ 0 - 1
app/src/main/res/menu/menu_conversation.xml

@@ -26,7 +26,6 @@
         android:id="@+id/conversation_voice_call"
         android:icon="@drawable/ic_call_white_24dp"
         android:title="@string/nc_conversation_menu_voice_call"
-        android:visible="false"
         app:showAsAction="always"/>
 
     <item