-
-
Notifications
You must be signed in to change notification settings - Fork 176
Android calls UI #3785
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Android calls UI #3785
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
src/main/java/org/thoughtcrime/securesms/videochat/VideochatUtil.java
Outdated
Show resolved
Hide resolved
the dialog that appears when inviting someone says that you need to have an app installed, we probably need a new string |
To test the changes in this pull request, install this apk: |
for now, we can just not use the string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great that you figured out all that!
if needed, we can merge that roughly as is to move forward.
the only thing we should necessarily change is to not show the call option by default, maybe we need a switch for that, as we introduced a default string, but any other way that comes in mind would do as well
To test the changes in this pull request, install this apk: |
To test the changes in this pull request, install this apk: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the "the other participant's video freezing" issue:
I think I have found the suspect: it might be the thing where Android (or is it Chromium) pauses all media when you're on a call (or receive an "incoming call" notification?)
If you go to "saved messages" and start a call there, and then open your browser and try to play another video, you'll notice that it behaves in the same way. If you try to start playing the video, it will play for a moment, and then pause again. This is also the case for the incoming stream in our "calls" app.
Then, if you forcefully stop Delta Chat, you are able to play the media again.
However, I honestly have no idea why you can still play the video of your own camera inside the app, even when it's unmuted.
I have been debugging this with Eruda. Here is my little debug script, if you're interested:
Script
// Hide the "Ringing..." div that covers the rest of the app.
document.querySelectorAll('div')[4].style.display =''
vids = document.querySelectorAll('video')
// Having this makes the new `localVideo` play.
if (1) {
vids[0].srcObject = null
vids[1].srcObject = null
vids[0].remove()
vids[1].remove()
}
// This makes both videos play.
const enableAudio = 1
const setSrcObjectOnEventIndex = 1
let localVideo
if (1) {
localVideo = document.createElement('video');
localVideo.autoplay = true;
localVideo.muted = true;
localVideo.controls = true;
localVideo.style.width = '320px';
localVideo.style.marginRight = '10px';
document.body.appendChild(localVideo);
} else {
localVideo = vids[1]
}
let remoteVideo
if (1) {
remoteVideo = document.createElement('video');
remoteVideo.autoplay = true;
remoteVideo.controls = true;
remoteVideo.style.width = '320px';
document.body.appendChild(remoteVideo);
} else {
remoteVideo = vids[0]
remoteVideo.controls = true
}
let localStream;
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
// When pc2 receives a track, display it in remoteVideo
let onTrackCount = 0
pc2.ontrack = (event) => {
onTrackCount++
if (onTrackCount !== setSrcObjectOnEventIndex) {
console.log('onTrackCount !== setSrcObjectOnEventIndex')
return
}
remoteVideo.srcObject = event.streams[0];
};
// Get local media and start the connection
navigator.mediaDevices.getUserMedia({ video: true, audio: enableAudio }).then(stream => {
localStream = stream;
localVideo.srcObject = localStream;
if (0) {
return
}
// Add local tracks to pc1
localStream.getTracks().forEach(track => {
pc1.addTrack(track, localStream);
});
// ICE candidates
pc1.onicecandidate = e => {
if (e.candidate) pc2.addIceCandidate(e.candidate);
};
pc2.onicecandidate = e => {
if (e.candidate) pc1.addIceCandidate(e.candidate);
};
// Start offer/answer exchange
pc1.createOffer().then(offer => {
return pc1.setLocalDescription(offer);
}).then(() => {
return pc2.setRemoteDescription(pc1.localDescription);
}).then(() => {
return pc2.createAnswer();
}).then(answer => {
return pc2.setLocalDescription(answer);
}).then(() => {
return pc1.setRemoteDescription(pc2.localDescription);
});
});
if ((Boolean)newValue) { | ||
new AlertDialog.Builder(requireActivity()) | ||
.setTitle("Thanks for trying out \"Video Calls\"!") | ||
.setMessage("• You can now call contacts\n\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to mean that you could call anyone except contacts previously.
Or this might be this thing called "audio focus": https://developer.android.com/media/optimize/audio-focus |
in fact I tried disabling the use of the calls integration and now the video works, a bit weird because this used to work in the past, but I think for now I will not use the Android Telecom API at all, it is almost useless, only useful for calling from cars or Bluetooth devices |
case DcContext.DC_EVENT_OUTGOING_CALL_ACCEPTED: | ||
if (event.getData1Int() == callId) { | ||
String hash = "#answer=" + event.getData2Str(); | ||
webView.evaluateJavascript("window.location.hash = `"+hash+"`", null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gets the answer from the network and injects it directly into javascript, may result in executing anything in the webview.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SDP sent over the wire should be not URL-encoded. Instead, base64 or whatever encoding should happen here before injecting into JS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI we do the same (base64) in desktop, for such untrusted content.
I looked into the payload sent in a place_call_info, and it is an SDP offer, but unnecessarily URL-encoded. Should be a plain SDP instead, there is no need to send all the Fixing this needs a fix chatmail/core#7191 in the core first, because it turned out newlines were not tested and break the header. |
counterpart of deltachat/deltachat-ios#2638