voip-callkit 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/android/src/main/.DS_Store +0 -0
- package/android/src/main/AndroidManifest.xml +0 -55
- package/android/src/main/java/.DS_Store +0 -0
- package/android/src/main/java/com/.DS_Store +0 -0
- package/android/src/main/java/com/test/.DS_Store +0 -0
- package/android/src/main/java/com/test/callkit/.DS_Store +0 -0
- package/android/src/main/java/com/test/callkit/CallKitVoip.java +0 -12
- package/android/src/main/java/com/test/callkit/CallKitVoipPlugin.java +0 -81
- package/android/src/main/java/com/test/callkit/MyConnectionService.java +0 -200
- package/android/src/main/java/com/test/callkit/MyFirebaseMessagingService.java +0 -90
- package/android/src/main/java/com/test/callkit/androidcall/ApiCalls.java +0 -48
- package/android/src/main/java/com/test/callkit/androidcall/CallActivity.java +0 -1223
- package/android/src/main/java/com/test/callkit/androidcall/RetreivedTokenCallback.java +0 -5
- package/android/src/main/java/com/test/callkit/androidcall/SettingsActivity.java +0 -174
- package/android/src/main/java/com/test/callkit/androidcall/VoipBackgroundService.java +0 -103
- package/android/src/main/java/com/test/callkit/androidcall/VoipForegroundService.java +0 -210
- package/android/src/main/java/com/test/callkit/androidcall/VoipForegroundServiceActionReceiver.java +0 -77
- package/android/src/main/java/com/test/callkit/androidcall/util/CameraCapturerCompat.java +0 -185
- package/android/src/main/java/com/test/callkit/androidcall/util/CodecUtils.kt +0 -23
- package/android/src/main/java/com/test/callkit/androidcall/util/Dialog.java +0 -37
- package/android/src/main/res/.gitkeep +0 -0
@@ -1,1223 +0,0 @@
|
|
1
|
-
package com.test.callkit.androidcall;
|
2
|
-
|
3
|
-
import android.Manifest;
|
4
|
-
import android.annotation.SuppressLint;
|
5
|
-
import android.app.NotificationManager;
|
6
|
-
import android.app.PendingIntent;
|
7
|
-
import android.content.Context;
|
8
|
-
import android.content.Intent;
|
9
|
-
import android.content.SharedPreferences;
|
10
|
-
import android.content.pm.PackageManager;
|
11
|
-
import android.content.res.Resources;
|
12
|
-
import android.media.AudioManager;
|
13
|
-
import android.os.Build;
|
14
|
-
import android.os.Bundle;
|
15
|
-
import android.preference.PreferenceManager;
|
16
|
-
import android.util.Log;
|
17
|
-
import android.util.TypedValue;
|
18
|
-
import android.view.MenuItem;
|
19
|
-
import android.view.View;
|
20
|
-
import android.view.ViewGroup;
|
21
|
-
import android.widget.ImageView;
|
22
|
-
import android.widget.LinearLayout;
|
23
|
-
import android.widget.ProgressBar;
|
24
|
-
import android.widget.TextView;
|
25
|
-
import android.widget.Toast;
|
26
|
-
|
27
|
-
import androidx.annotation.NonNull;
|
28
|
-
import androidx.appcompat.app.AlertDialog;
|
29
|
-
import androidx.appcompat.app.AppCompatActivity;
|
30
|
-
import androidx.core.app.ActivityCompat;
|
31
|
-
import androidx.core.app.NotificationCompat;
|
32
|
-
import androidx.core.content.ContextCompat;
|
33
|
-
|
34
|
-
import com.test.callkit.CallKitVoipPlugin;
|
35
|
-
import com.test.callkit.R;
|
36
|
-
import com.test.callkit.androidcall.util.CameraCapturerCompat;
|
37
|
-
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
38
|
-
import com.google.android.material.snackbar.Snackbar;
|
39
|
-
import com.twilio.audioswitch.AudioDevice;
|
40
|
-
import com.twilio.audioswitch.AudioDevice.Earpiece;
|
41
|
-
import com.twilio.audioswitch.AudioDevice.Speakerphone;
|
42
|
-
import com.twilio.audioswitch.AudioDevice.WiredHeadset;
|
43
|
-
import com.twilio.audioswitch.AudioSwitch;
|
44
|
-
import com.twilio.video.AudioCodec;
|
45
|
-
import com.twilio.video.ConnectOptions;
|
46
|
-
import com.twilio.video.EncodingParameters;
|
47
|
-
import com.twilio.video.G722Codec;
|
48
|
-
import com.twilio.video.H264Codec;
|
49
|
-
import com.twilio.video.IsacCodec;
|
50
|
-
import com.twilio.video.LocalAudioTrack;
|
51
|
-
import com.twilio.video.LocalParticipant;
|
52
|
-
import com.twilio.video.LocalVideoTrack;
|
53
|
-
import com.twilio.video.OpusCodec;
|
54
|
-
import com.twilio.video.PcmaCodec;
|
55
|
-
import com.twilio.video.PcmuCodec;
|
56
|
-
import com.twilio.video.RemoteAudioTrack;
|
57
|
-
import com.twilio.video.RemoteAudioTrackPublication;
|
58
|
-
import com.twilio.video.RemoteDataTrack;
|
59
|
-
import com.twilio.video.RemoteDataTrackPublication;
|
60
|
-
import com.twilio.video.RemoteParticipant;
|
61
|
-
import com.twilio.video.RemoteVideoTrack;
|
62
|
-
import com.twilio.video.RemoteVideoTrackPublication;
|
63
|
-
import com.twilio.video.Room;
|
64
|
-
import com.twilio.video.TwilioException;
|
65
|
-
import com.twilio.video.Video;
|
66
|
-
import com.twilio.video.VideoCodec;
|
67
|
-
import com.twilio.video.VideoTrack;
|
68
|
-
import com.twilio.video.VideoView;
|
69
|
-
import com.twilio.video.Vp8Codec;
|
70
|
-
import com.twilio.video.Vp9Codec;
|
71
|
-
|
72
|
-
import java.util.ArrayList;
|
73
|
-
import java.util.Collections;
|
74
|
-
import java.util.List;
|
75
|
-
|
76
|
-
import kotlin.Unit;
|
77
|
-
import tvi.webrtc.VideoSink;
|
78
|
-
|
79
|
-
|
80
|
-
public class CallActivity extends AppCompatActivity {
|
81
|
-
private static final int CAMERA_MIC_PERMISSION_REQUEST_CODE = 1;
|
82
|
-
private static final int CAMERA_PERMISSION_INDEX = 0;
|
83
|
-
private static final int MIC_PERMISSION_INDEX = 1;
|
84
|
-
private static final String TAG = "VideoActivity";
|
85
|
-
boolean thumb_for_local = true;
|
86
|
-
|
87
|
-
/*
|
88
|
-
* Audio and video tracks can be created with names. This feature is useful for categorizing
|
89
|
-
* tracks of participants. For example, if one participant publishes a video track with
|
90
|
-
* ScreenCapturer and CameraCapturer with the names "screen" and "camera" respectively then
|
91
|
-
* other participants can use RemoteVideoTrack#getName to determine which video track is
|
92
|
-
* produced from the other participant's screen or camera.
|
93
|
-
*/
|
94
|
-
private static final String LOCAL_AUDIO_TRACK_NAME = "mic";
|
95
|
-
private static final String LOCAL_VIDEO_TRACK_NAME = "camera";
|
96
|
-
|
97
|
-
|
98
|
-
/*
|
99
|
-
* Access token used to connect. This field will be set either from the console generated token
|
100
|
-
* or the request to the token server.
|
101
|
-
*/
|
102
|
-
private String accessToken;
|
103
|
-
private String roomName;
|
104
|
-
private String username;
|
105
|
-
|
106
|
-
private Boolean auto_answer;
|
107
|
-
|
108
|
-
|
109
|
-
/*
|
110
|
-
* A Room represents communication between a local participant and one or more participants.
|
111
|
-
*/
|
112
|
-
private Room room;
|
113
|
-
private LocalParticipant localParticipant;
|
114
|
-
|
115
|
-
/*
|
116
|
-
* AudioCodec and VideoCodec represent the preferred codec for encoding and decoding audio and
|
117
|
-
* video.
|
118
|
-
*/
|
119
|
-
private AudioCodec audioCodec;
|
120
|
-
private VideoCodec videoCodec;
|
121
|
-
|
122
|
-
/*
|
123
|
-
* Encoding parameters represent the sender side bandwidth constraints.
|
124
|
-
*/
|
125
|
-
private EncodingParameters encodingParameters;
|
126
|
-
|
127
|
-
/*
|
128
|
-
* A VideoView receives frames from a local or remote video track and renders them
|
129
|
-
* to an associated view.
|
130
|
-
*/
|
131
|
-
private VideoView primaryVideoView;
|
132
|
-
private VideoView thumbnailVideoView;
|
133
|
-
|
134
|
-
/*
|
135
|
-
* Android shared preferences used for settings
|
136
|
-
*/
|
137
|
-
private SharedPreferences preferences;
|
138
|
-
|
139
|
-
/*
|
140
|
-
* Android application UI elements
|
141
|
-
*/
|
142
|
-
private CameraCapturerCompat cameraCapturerCompat;
|
143
|
-
private LocalAudioTrack localAudioTrack;
|
144
|
-
private LocalVideoTrack localVideoTrack;
|
145
|
-
private FloatingActionButton connectActionFab;
|
146
|
-
private FloatingActionButton switchCameraActionFab;
|
147
|
-
private FloatingActionButton localVideoActionFab;
|
148
|
-
private FloatingActionButton muteActionFab;
|
149
|
-
private FloatingActionButton answer;
|
150
|
-
private FloatingActionButton reject;
|
151
|
-
|
152
|
-
private ProgressBar reconnectingProgressBar;
|
153
|
-
private TextView callerUser;
|
154
|
-
private ImageView bcg;
|
155
|
-
private LinearLayout answered_actions,unanswered_actions;
|
156
|
-
private String remoteParticipantIdentity;
|
157
|
-
|
158
|
-
/*
|
159
|
-
* Audio management
|
160
|
-
*/
|
161
|
-
private AudioSwitch audioSwitch;
|
162
|
-
private int savedVolumeControlStream;
|
163
|
-
|
164
|
-
private VideoSink localVideoView;
|
165
|
-
private boolean disconnectedFromOnDestroy;
|
166
|
-
private boolean enableAutomaticSubscription;
|
167
|
-
|
168
|
-
@Override
|
169
|
-
protected void onCreate(Bundle savedInstanceState) {
|
170
|
-
super.onCreate(savedInstanceState);
|
171
|
-
setContentView(R.layout.activity_video);
|
172
|
-
|
173
|
-
primaryVideoView = findViewById(R.id.primary_video_view);
|
174
|
-
thumbnailVideoView = findViewById(R.id.thumbnail_video_view);
|
175
|
-
reconnectingProgressBar = findViewById(R.id.reconnecting_progress_bar);
|
176
|
-
callerUser = findViewById(R.id.callerUser);
|
177
|
-
bcg = findViewById(R.id.bcg);
|
178
|
-
thumbnailVideoView.setOnClickListener(new View.OnClickListener() {
|
179
|
-
@Override
|
180
|
-
public void onClick(View view) {
|
181
|
-
switch_views();
|
182
|
-
}
|
183
|
-
});
|
184
|
-
primaryVideoView.setOnClickListener(new View.OnClickListener() {
|
185
|
-
@Override
|
186
|
-
public void onClick(View view) {
|
187
|
-
switch_views();
|
188
|
-
}
|
189
|
-
});
|
190
|
-
connectActionFab = findViewById(R.id.connect_action_fab);
|
191
|
-
switchCameraActionFab = findViewById(R.id.switch_camera_action_fab);
|
192
|
-
localVideoActionFab = findViewById(R.id.local_video_action_fab);
|
193
|
-
muteActionFab = findViewById(R.id.mute_action_fab);
|
194
|
-
answer = findViewById(R.id.answer);
|
195
|
-
reject = findViewById(R.id.reject);
|
196
|
-
|
197
|
-
accessToken = getIntent().getStringExtra("token");
|
198
|
-
roomName = getIntent().getStringExtra("roomName");
|
199
|
-
answered_actions = findViewById(R.id.answered_actions);
|
200
|
-
unanswered_actions = findViewById(R.id.unanswered_actions);
|
201
|
-
if(getIntent().hasExtra("auto_answer") && getIntent().hasExtra("username")) {
|
202
|
-
auto_answer = getIntent().getBooleanExtra("auto_answer", false);
|
203
|
-
username = getIntent().getStringExtra("username");
|
204
|
-
}
|
205
|
-
/*
|
206
|
-
* Get shared preferences to read settings
|
207
|
-
*/
|
208
|
-
preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
209
|
-
|
210
|
-
/*
|
211
|
-
* Setup audio management and set the volume control stream
|
212
|
-
*/
|
213
|
-
audioSwitch = new AudioSwitch(getApplicationContext());
|
214
|
-
savedVolumeControlStream = getVolumeControlStream();
|
215
|
-
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
|
216
|
-
/*
|
217
|
-
* Check camera and microphone permissions. Needed in Android M. Also, request for bluetooth
|
218
|
-
* permissions for enablement of bluetooth audio routing.
|
219
|
-
*/
|
220
|
-
if (!checkPermissionForCameraAndMicrophone()) {
|
221
|
-
requestPermissionForCameraMicrophoneAndBluetooth();
|
222
|
-
} else {
|
223
|
-
audioSwitch.start(
|
224
|
-
(audioDevices, audioDevice) -> Unit.INSTANCE);
|
225
|
-
createAudioAndVideoTracks();
|
226
|
-
}
|
227
|
-
|
228
|
-
/*
|
229
|
-
* Set the initial state of the UI
|
230
|
-
*/
|
231
|
-
|
232
|
-
intializeUI();
|
233
|
-
audioCodec =
|
234
|
-
getAudioCodecPreference(
|
235
|
-
SettingsActivity.PREF_AUDIO_CODEC,
|
236
|
-
SettingsActivity.PREF_AUDIO_CODEC_DEFAULT);
|
237
|
-
videoCodec =
|
238
|
-
getVideoCodecPreference(
|
239
|
-
SettingsActivity.PREF_VIDEO_CODEC,
|
240
|
-
SettingsActivity.PREF_VIDEO_CODEC_DEFAULT);
|
241
|
-
enableAutomaticSubscription =
|
242
|
-
getAutomaticSubscriptionPreference(
|
243
|
-
SettingsActivity.PREF_ENABLE_AUTOMATIC_SUBSCRIPTION,
|
244
|
-
SettingsActivity.PREF_ENABLE_AUTOMATIC_SUBSCRIPTION_DEFAULT);
|
245
|
-
/*
|
246
|
-
* Get latest encoding parameters
|
247
|
-
*/
|
248
|
-
final EncodingParameters newEncodingParameters = getEncodingParameters();
|
249
|
-
|
250
|
-
/*
|
251
|
-
* If the local video track was released when the app was put in the background, recreate.
|
252
|
-
*/
|
253
|
-
if (localVideoTrack == null && checkPermissionForCameraAndMicrophone()) {
|
254
|
-
localVideoTrack =
|
255
|
-
LocalVideoTrack.create(
|
256
|
-
this, true, cameraCapturerCompat, LOCAL_VIDEO_TRACK_NAME);
|
257
|
-
localVideoTrack.addSink(localVideoView);
|
258
|
-
|
259
|
-
/*
|
260
|
-
* If connected to a Room then share the local video track.
|
261
|
-
*/
|
262
|
-
if (localParticipant != null) {
|
263
|
-
localParticipant.publishTrack(localVideoTrack);
|
264
|
-
|
265
|
-
/*
|
266
|
-
* Update encoding parameters if they have changed.
|
267
|
-
*/
|
268
|
-
if (!newEncodingParameters.equals(encodingParameters)) {
|
269
|
-
localParticipant.setEncodingParameters(newEncodingParameters);
|
270
|
-
}
|
271
|
-
}
|
272
|
-
}
|
273
|
-
|
274
|
-
/*
|
275
|
-
* Update encoding parameters
|
276
|
-
*/
|
277
|
-
encodingParameters = newEncodingParameters;
|
278
|
-
|
279
|
-
/*
|
280
|
-
* Update reconnecting UI
|
281
|
-
*/
|
282
|
-
if (room != null) {
|
283
|
-
reconnectingProgressBar.setVisibility(View.VISIBLE);
|
284
|
-
}
|
285
|
-
if(auto_answer) {
|
286
|
-
|
287
|
-
connectToRoom(roomName);
|
288
|
-
|
289
|
-
}
|
290
|
-
else {
|
291
|
-
answer.setOnClickListener(view -> connectToRoom(roomName));
|
292
|
-
reject.setOnClickListener(new View.OnClickListener() {
|
293
|
-
@Override
|
294
|
-
public void onClick(View view) {
|
295
|
-
CallKitVoipPlugin instance = CallKitVoipPlugin.getInstance();
|
296
|
-
instance.notifyEvent("RejectCall",username,roomName);
|
297
|
-
CallActivity.this.stopService(new Intent(CallActivity.this, VoipForegroundService.class));
|
298
|
-
Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
|
299
|
-
CallActivity.this.sendBroadcast(it);
|
300
|
-
|
301
|
-
finish();
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
}
|
306
|
-
});
|
307
|
-
callerUser.setVisibility(View.VISIBLE);
|
308
|
-
callerUser.setText(username);
|
309
|
-
answered_actions.setVisibility(View.GONE);
|
310
|
-
unanswered_actions.setVisibility(View.VISIBLE);
|
311
|
-
}
|
312
|
-
|
313
|
-
}
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
@Override
|
318
|
-
public void onRequestPermissionsResult(
|
319
|
-
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
320
|
-
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
321
|
-
if (requestCode == CAMERA_MIC_PERMISSION_REQUEST_CODE) {
|
322
|
-
/*
|
323
|
-
* The first two permissions are Camera & Microphone, bluetooth isn't required but
|
324
|
-
* enabling it enables bluetooth audio routing functionality.
|
325
|
-
*/
|
326
|
-
boolean cameraAndMicPermissionGranted =
|
327
|
-
(PackageManager.PERMISSION_GRANTED == grantResults[CAMERA_PERMISSION_INDEX])
|
328
|
-
& (PackageManager.PERMISSION_GRANTED
|
329
|
-
== grantResults[MIC_PERMISSION_INDEX]);
|
330
|
-
|
331
|
-
/*
|
332
|
-
* Due to bluetooth permissions being requested at the same time as camera and mic
|
333
|
-
* permissions, AudioSwitch should be started after providing the user the option
|
334
|
-
* to grant the necessary permissions for bluetooth.
|
335
|
-
*/
|
336
|
-
audioSwitch.start(
|
337
|
-
(audioDevices, audioDevice) -> Unit.INSTANCE);
|
338
|
-
|
339
|
-
if (cameraAndMicPermissionGranted) {
|
340
|
-
createAudioAndVideoTracks();
|
341
|
-
} else {
|
342
|
-
Toast.makeText(this, R.string.permissions_needed, Toast.LENGTH_LONG).show();
|
343
|
-
}
|
344
|
-
}
|
345
|
-
}
|
346
|
-
|
347
|
-
|
348
|
-
@Override
|
349
|
-
protected void onPause() {
|
350
|
-
/*
|
351
|
-
* Release the local video track before going in the background. This ensures that the
|
352
|
-
* camera can be used by other applications while this app is in the background.
|
353
|
-
*/
|
354
|
-
if (localVideoTrack != null) {
|
355
|
-
/*
|
356
|
-
* If this local video track is being shared in a Room, unpublish from room before
|
357
|
-
* releasing the video track. Participants will be notified that the track has been
|
358
|
-
* unpublished.
|
359
|
-
*/
|
360
|
-
if (localParticipant != null) {
|
361
|
-
localParticipant.unpublishTrack(localVideoTrack);
|
362
|
-
}
|
363
|
-
|
364
|
-
localVideoTrack.release();
|
365
|
-
localVideoTrack = null;
|
366
|
-
}
|
367
|
-
super.onPause();
|
368
|
-
}
|
369
|
-
|
370
|
-
@Override
|
371
|
-
protected void onDestroy() {
|
372
|
-
/*
|
373
|
-
* Tear down audio management and restore previous volume stream
|
374
|
-
*/
|
375
|
-
audioSwitch.stop();
|
376
|
-
setVolumeControlStream(savedVolumeControlStream);
|
377
|
-
|
378
|
-
/*
|
379
|
-
* Always disconnect from the room before leaving the Activity to
|
380
|
-
* ensure any memory allocated to the Room resource is freed.
|
381
|
-
*/
|
382
|
-
if (room != null && room.getState() != Room.State.DISCONNECTED) {
|
383
|
-
room.disconnect();
|
384
|
-
disconnectedFromOnDestroy = true;
|
385
|
-
}
|
386
|
-
|
387
|
-
/*
|
388
|
-
* Release the local audio and video tracks ensuring any memory allocated to audio
|
389
|
-
* or video is freed.
|
390
|
-
*/
|
391
|
-
if (localAudioTrack != null) {
|
392
|
-
localAudioTrack.release();
|
393
|
-
localAudioTrack = null;
|
394
|
-
}
|
395
|
-
if (localVideoTrack != null) {
|
396
|
-
localVideoTrack.release();
|
397
|
-
localVideoTrack = null;
|
398
|
-
}
|
399
|
-
|
400
|
-
super.onDestroy();
|
401
|
-
}
|
402
|
-
|
403
|
-
private boolean checkPermissions(String[] permissions) {
|
404
|
-
boolean shouldCheck = true;
|
405
|
-
for (String permission : permissions) {
|
406
|
-
shouldCheck &=
|
407
|
-
(PackageManager.PERMISSION_GRANTED
|
408
|
-
== ContextCompat.checkSelfPermission(this, permission));
|
409
|
-
}
|
410
|
-
return shouldCheck;
|
411
|
-
}
|
412
|
-
|
413
|
-
private void requestPermissions(String[] permissions) {
|
414
|
-
boolean displayRational = false;
|
415
|
-
for (String permission : permissions) {
|
416
|
-
displayRational |=
|
417
|
-
ActivityCompat.shouldShowRequestPermissionRationale(this, permission);
|
418
|
-
}
|
419
|
-
if (displayRational) {
|
420
|
-
Toast.makeText(this, R.string.permissions_needed, Toast.LENGTH_LONG).show();
|
421
|
-
} else {
|
422
|
-
ActivityCompat.requestPermissions(
|
423
|
-
this, permissions, CAMERA_MIC_PERMISSION_REQUEST_CODE);
|
424
|
-
}
|
425
|
-
}
|
426
|
-
|
427
|
-
private boolean checkPermissionForCameraAndMicrophone() {
|
428
|
-
return checkPermissions(
|
429
|
-
new String[] {Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO});
|
430
|
-
}
|
431
|
-
|
432
|
-
private void requestPermissionForCameraMicrophoneAndBluetooth() {
|
433
|
-
String[] permissionsList;
|
434
|
-
permissionsList =
|
435
|
-
new String[] {Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
|
436
|
-
requestPermissions(permissionsList);
|
437
|
-
}
|
438
|
-
|
439
|
-
private void createAudioAndVideoTracks() {
|
440
|
-
// Share your microphone
|
441
|
-
localAudioTrack = LocalAudioTrack.create(this, true, LOCAL_AUDIO_TRACK_NAME);
|
442
|
-
// Share your camera
|
443
|
-
cameraCapturerCompat =
|
444
|
-
new CameraCapturerCompat(this, CameraCapturerCompat.Source.FRONT_CAMERA);
|
445
|
-
localVideoTrack =
|
446
|
-
LocalVideoTrack.create(this, true, cameraCapturerCompat, LOCAL_VIDEO_TRACK_NAME);
|
447
|
-
primaryVideoView.setMirror(true);
|
448
|
-
localVideoTrack.addSink(primaryVideoView);
|
449
|
-
localVideoView = primaryVideoView;
|
450
|
-
}
|
451
|
-
|
452
|
-
|
453
|
-
private void connectToRoom(String roomName) {
|
454
|
-
answered_actions.setVisibility(View.VISIBLE);
|
455
|
-
unanswered_actions.setVisibility(View.GONE);
|
456
|
-
callerUser.setVisibility(View.GONE);
|
457
|
-
bcg.setVisibility(View.GONE);
|
458
|
-
|
459
|
-
Intent serviceIntent = new Intent(this, VoipForegroundService.class);
|
460
|
-
serviceIntent.setAction("answered");
|
461
|
-
|
462
|
-
|
463
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
464
|
-
|
465
|
-
CallActivity.this.startForegroundService(serviceIntent);
|
466
|
-
|
467
|
-
} else {
|
468
|
-
CallActivity.this.startService(serviceIntent);
|
469
|
-
}
|
470
|
-
audioSwitch.activate();
|
471
|
-
ConnectOptions.Builder connectOptionsBuilder =
|
472
|
-
new ConnectOptions.Builder(accessToken).roomName(roomName);
|
473
|
-
|
474
|
-
/*
|
475
|
-
* Add local audio track to connect options to share with participants.
|
476
|
-
*/
|
477
|
-
if (localAudioTrack != null) {
|
478
|
-
connectOptionsBuilder.audioTracks(Collections.singletonList(localAudioTrack));
|
479
|
-
}
|
480
|
-
|
481
|
-
/*
|
482
|
-
* Add local video track to connect options to share with participants.
|
483
|
-
*/
|
484
|
-
if (localVideoTrack != null) {
|
485
|
-
connectOptionsBuilder.videoTracks(Collections.singletonList(localVideoTrack));
|
486
|
-
}
|
487
|
-
|
488
|
-
/*
|
489
|
-
* Set the preferred audio and video codec for media.
|
490
|
-
*/
|
491
|
-
connectOptionsBuilder.preferAudioCodecs(Collections.singletonList(audioCodec));
|
492
|
-
connectOptionsBuilder.preferVideoCodecs(Collections.singletonList(videoCodec));
|
493
|
-
|
494
|
-
/*
|
495
|
-
* Set the sender side encoding parameters.
|
496
|
-
*/
|
497
|
-
Log.d("connectToRoom",connectOptionsBuilder.toString());
|
498
|
-
Log.d("connectToRoom",encodingParameters.toString());
|
499
|
-
|
500
|
-
connectOptionsBuilder.encodingParameters(encodingParameters);
|
501
|
-
|
502
|
-
/*
|
503
|
-
* Toggles automatic track subscription. If set to false, the LocalParticipant will receive
|
504
|
-
* notifications of track publish events, but will not automatically subscribe to them. If
|
505
|
-
* set to true, the LocalParticipant will automatically subscribe to tracks as they are
|
506
|
-
* published. If unset, the default is true. Note: This feature is only available for Group
|
507
|
-
* Rooms. Toggling the flag in a P2P room does not modify subscription behavior.
|
508
|
-
*/
|
509
|
-
connectOptionsBuilder.enableAutomaticSubscription(enableAutomaticSubscription);
|
510
|
-
|
511
|
-
room = Video.connect(this, connectOptionsBuilder.build(), roomListener());
|
512
|
-
setDisconnectAction();
|
513
|
-
}
|
514
|
-
|
515
|
-
/*
|
516
|
-
* The initial state when there is no active room.
|
517
|
-
*/
|
518
|
-
private void intializeUI() {
|
519
|
-
|
520
|
-
switchCameraActionFab.show();
|
521
|
-
switchCameraActionFab.setOnClickListener(switchCameraClickListener());
|
522
|
-
localVideoActionFab.show();
|
523
|
-
localVideoActionFab.setOnClickListener(localVideoClickListener());
|
524
|
-
muteActionFab.show();
|
525
|
-
muteActionFab.setOnClickListener(muteClickListener());
|
526
|
-
}
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
/*
|
531
|
-
* Get the preferred audio codec from shared preferences
|
532
|
-
*/
|
533
|
-
private AudioCodec getAudioCodecPreference(String key, String defaultValue) {
|
534
|
-
final String audioCodecName = preferences.getString(key, defaultValue);
|
535
|
-
|
536
|
-
switch (audioCodecName) {
|
537
|
-
case IsacCodec.NAME:
|
538
|
-
return new IsacCodec();
|
539
|
-
case OpusCodec.NAME:
|
540
|
-
return new OpusCodec();
|
541
|
-
case PcmaCodec.NAME:
|
542
|
-
return new PcmaCodec();
|
543
|
-
case PcmuCodec.NAME:
|
544
|
-
return new PcmuCodec();
|
545
|
-
case G722Codec.NAME:
|
546
|
-
return new G722Codec();
|
547
|
-
default:
|
548
|
-
return new OpusCodec();
|
549
|
-
}
|
550
|
-
}
|
551
|
-
|
552
|
-
/*
|
553
|
-
* Get the preferred video codec from shared preferences
|
554
|
-
*/
|
555
|
-
private VideoCodec getVideoCodecPreference(String key, String defaultValue) {
|
556
|
-
final String videoCodecName = preferences.getString(key, defaultValue);
|
557
|
-
|
558
|
-
switch (videoCodecName) {
|
559
|
-
case Vp8Codec.NAME:
|
560
|
-
boolean simulcast =
|
561
|
-
preferences.getBoolean(
|
562
|
-
SettingsActivity.PREF_VP8_SIMULCAST,
|
563
|
-
SettingsActivity.PREF_VP8_SIMULCAST_DEFAULT);
|
564
|
-
return new Vp8Codec(simulcast);
|
565
|
-
case H264Codec.NAME:
|
566
|
-
return new H264Codec();
|
567
|
-
case Vp9Codec.NAME:
|
568
|
-
return new Vp9Codec();
|
569
|
-
default:
|
570
|
-
return new Vp8Codec();
|
571
|
-
}
|
572
|
-
}
|
573
|
-
|
574
|
-
private boolean getAutomaticSubscriptionPreference(String key, boolean defaultValue) {
|
575
|
-
return preferences.getBoolean(key, defaultValue);
|
576
|
-
}
|
577
|
-
|
578
|
-
private EncodingParameters getEncodingParameters() {
|
579
|
-
final int maxAudioBitrate =
|
580
|
-
Integer.parseInt(
|
581
|
-
preferences.getString(
|
582
|
-
SettingsActivity.PREF_SENDER_MAX_AUDIO_BITRATE,
|
583
|
-
SettingsActivity.PREF_SENDER_MAX_AUDIO_BITRATE_DEFAULT));
|
584
|
-
final int maxVideoBitrate =
|
585
|
-
Integer.parseInt(
|
586
|
-
preferences.getString(
|
587
|
-
SettingsActivity.PREF_SENDER_MAX_VIDEO_BITRATE,
|
588
|
-
SettingsActivity.PREF_SENDER_MAX_VIDEO_BITRATE_DEFAULT));
|
589
|
-
|
590
|
-
return new EncodingParameters(maxAudioBitrate, maxVideoBitrate);
|
591
|
-
}
|
592
|
-
|
593
|
-
/*
|
594
|
-
* The actions performed during disconnect.
|
595
|
-
*/
|
596
|
-
private void setDisconnectAction() {
|
597
|
-
connectActionFab.setImageDrawable(
|
598
|
-
ContextCompat.getDrawable(this, R.drawable.ic_hangup));
|
599
|
-
connectActionFab.show();
|
600
|
-
connectActionFab.setOnClickListener(disconnectClickListener());
|
601
|
-
}
|
602
|
-
|
603
|
-
/*
|
604
|
-
* Called when remote participant joins the room
|
605
|
-
*/
|
606
|
-
@SuppressLint("SetTextI18n")
|
607
|
-
private void addRemoteParticipant(RemoteParticipant remoteParticipant) {
|
608
|
-
/*
|
609
|
-
* This app only displays video for one additional participant per Room
|
610
|
-
*/
|
611
|
-
if (thumbnailVideoView.getVisibility() == View.VISIBLE) {
|
612
|
-
Snackbar.make(
|
613
|
-
connectActionFab,
|
614
|
-
"Multiple participants are not currently support in this UI",
|
615
|
-
Snackbar.LENGTH_LONG)
|
616
|
-
.setAction("Action", null)
|
617
|
-
.show();
|
618
|
-
return;
|
619
|
-
}
|
620
|
-
remoteParticipantIdentity = remoteParticipant.getIdentity();
|
621
|
-
|
622
|
-
/*
|
623
|
-
* Add remote participant renderer
|
624
|
-
*/
|
625
|
-
if (remoteParticipant.getRemoteVideoTracks().size() > 0) {
|
626
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication =
|
627
|
-
remoteParticipant.getRemoteVideoTracks().get(0);
|
628
|
-
|
629
|
-
/*
|
630
|
-
* Only render video tracks that are subscribed to
|
631
|
-
*/
|
632
|
-
if (remoteVideoTrackPublication.isTrackSubscribed()) {
|
633
|
-
addRemoteParticipantVideo(remoteVideoTrackPublication.getRemoteVideoTrack());
|
634
|
-
}
|
635
|
-
}
|
636
|
-
|
637
|
-
/*
|
638
|
-
* Start listening for participant events
|
639
|
-
*/
|
640
|
-
remoteParticipant.setListener(remoteParticipantListener());
|
641
|
-
}
|
642
|
-
|
643
|
-
/*
|
644
|
-
* Set primary view as renderer for participant video track
|
645
|
-
*/
|
646
|
-
private void addRemoteParticipantVideo(VideoTrack videoTrack) {
|
647
|
-
moveLocalVideoToThumbnailView();
|
648
|
-
primaryVideoView.setMirror(false);
|
649
|
-
videoTrack.addSink(primaryVideoView);
|
650
|
-
}
|
651
|
-
public static int dpToPx(int dp)
|
652
|
-
{
|
653
|
-
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
|
654
|
-
}
|
655
|
-
private void switch_views()
|
656
|
-
{
|
657
|
-
Log.d("switch_views","called");
|
658
|
-
if (thumbnailVideoView.getVisibility() == View.VISIBLE) {
|
659
|
-
if (thumb_for_local)
|
660
|
-
{
|
661
|
-
thumb_for_local = false;
|
662
|
-
ViewGroup.MarginLayoutParams params1 = (ViewGroup.MarginLayoutParams)primaryVideoView.getLayoutParams();
|
663
|
-
ViewGroup.MarginLayoutParams params2 = (ViewGroup.MarginLayoutParams)thumbnailVideoView.getLayoutParams();
|
664
|
-
|
665
|
-
params1.height = dpToPx(96);
|
666
|
-
params1.width = dpToPx(96);
|
667
|
-
params2.height = ViewGroup.LayoutParams.MATCH_PARENT;
|
668
|
-
params2.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
669
|
-
params2.leftMargin = 0;
|
670
|
-
params2.rightMargin = 0;
|
671
|
-
params2.topMargin = 0;
|
672
|
-
params2.bottomMargin = 0;
|
673
|
-
params1.leftMargin = dpToPx(16);
|
674
|
-
params1.rightMargin = dpToPx(16);
|
675
|
-
params1.topMargin = dpToPx(16);
|
676
|
-
params1.bottomMargin = dpToPx(16);
|
677
|
-
|
678
|
-
primaryVideoView.setLayoutParams(params1);
|
679
|
-
primaryVideoView.setMirror(true);
|
680
|
-
primaryVideoView.setZOrderMediaOverlay(true);
|
681
|
-
thumbnailVideoView.setLayoutParams(params2);
|
682
|
-
thumbnailVideoView.setMirror(false);
|
683
|
-
thumbnailVideoView.setZOrderMediaOverlay(false);
|
684
|
-
}
|
685
|
-
else {
|
686
|
-
thumb_for_local = true;
|
687
|
-
|
688
|
-
ViewGroup.MarginLayoutParams params1 = (ViewGroup.MarginLayoutParams)primaryVideoView.getLayoutParams();
|
689
|
-
ViewGroup.MarginLayoutParams params2 = (ViewGroup.MarginLayoutParams)thumbnailVideoView.getLayoutParams();
|
690
|
-
|
691
|
-
params1.height = dpToPx(96);
|
692
|
-
params1.width = dpToPx(96);
|
693
|
-
params2.height = ViewGroup.LayoutParams.MATCH_PARENT;
|
694
|
-
params2.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
695
|
-
params2.leftMargin = 0;
|
696
|
-
params2.rightMargin = 0;
|
697
|
-
params2.topMargin = 0;
|
698
|
-
params2.bottomMargin = 0;
|
699
|
-
params1.leftMargin = dpToPx(16);
|
700
|
-
params1.rightMargin = dpToPx(16);
|
701
|
-
params1.topMargin = dpToPx(16);
|
702
|
-
params1.bottomMargin = dpToPx(16);
|
703
|
-
|
704
|
-
primaryVideoView.setLayoutParams(params2);
|
705
|
-
primaryVideoView.setMirror(false);
|
706
|
-
primaryVideoView.setZOrderMediaOverlay(false);
|
707
|
-
thumbnailVideoView.setLayoutParams(params1);
|
708
|
-
thumbnailVideoView.setMirror(true);
|
709
|
-
thumbnailVideoView.setZOrderMediaOverlay(true);
|
710
|
-
}
|
711
|
-
|
712
|
-
}
|
713
|
-
}
|
714
|
-
private void moveLocalVideoToThumbnailView() {
|
715
|
-
if (thumbnailVideoView.getVisibility() == View.GONE) {
|
716
|
-
try {
|
717
|
-
thumbnailVideoView.setVisibility(View.VISIBLE);
|
718
|
-
localVideoTrack.removeSink(primaryVideoView);
|
719
|
-
localVideoTrack.addSink(thumbnailVideoView);
|
720
|
-
localVideoView = thumbnailVideoView;
|
721
|
-
thumbnailVideoView.setMirror(
|
722
|
-
cameraCapturerCompat.getCameraSource()
|
723
|
-
== CameraCapturerCompat.Source.FRONT_CAMERA);
|
724
|
-
}
|
725
|
-
catch (Exception e)
|
726
|
-
{
|
727
|
-
|
728
|
-
}
|
729
|
-
}
|
730
|
-
}
|
731
|
-
|
732
|
-
/*
|
733
|
-
* Called when remote participant leaves the room
|
734
|
-
*/
|
735
|
-
@SuppressLint("SetTextI18n")
|
736
|
-
private void removeRemoteParticipant(RemoteParticipant remoteParticipant) {
|
737
|
-
if (!remoteParticipant.getIdentity().equals(remoteParticipantIdentity)) {
|
738
|
-
return;
|
739
|
-
}
|
740
|
-
|
741
|
-
/*
|
742
|
-
* Remove remote participant renderer
|
743
|
-
*/
|
744
|
-
if (!remoteParticipant.getRemoteVideoTracks().isEmpty()) {
|
745
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication =
|
746
|
-
remoteParticipant.getRemoteVideoTracks().get(0);
|
747
|
-
|
748
|
-
/*
|
749
|
-
* Remove video only if subscribed to participant track
|
750
|
-
*/
|
751
|
-
if (remoteVideoTrackPublication.isTrackSubscribed()) {
|
752
|
-
removeParticipantVideo(remoteVideoTrackPublication.getRemoteVideoTrack());
|
753
|
-
}
|
754
|
-
}
|
755
|
-
moveLocalVideoToPrimaryView();
|
756
|
-
}
|
757
|
-
|
758
|
-
private void removeParticipantVideo(VideoTrack videoTrack) {
|
759
|
-
videoTrack.removeSink(primaryVideoView);
|
760
|
-
}
|
761
|
-
|
762
|
-
private void moveLocalVideoToPrimaryView() {
|
763
|
-
if (thumbnailVideoView.getVisibility() == View.VISIBLE) {
|
764
|
-
thumbnailVideoView.setVisibility(View.GONE);
|
765
|
-
if (localVideoTrack != null) {
|
766
|
-
localVideoTrack.removeSink(thumbnailVideoView);
|
767
|
-
localVideoTrack.addSink(primaryVideoView);
|
768
|
-
}
|
769
|
-
localVideoView = primaryVideoView;
|
770
|
-
primaryVideoView.setMirror(
|
771
|
-
cameraCapturerCompat.getCameraSource()
|
772
|
-
== CameraCapturerCompat.Source.FRONT_CAMERA);
|
773
|
-
}
|
774
|
-
}
|
775
|
-
|
776
|
-
/*
|
777
|
-
* Room events listener
|
778
|
-
*/
|
779
|
-
@SuppressLint("SetTextI18n")
|
780
|
-
private Room.Listener roomListener() {
|
781
|
-
return new Room.Listener() {
|
782
|
-
@Override
|
783
|
-
public void onConnected(Room room) {
|
784
|
-
localParticipant = room.getLocalParticipant();
|
785
|
-
setTitle(room.getName());
|
786
|
-
reconnectingProgressBar.setVisibility(View.GONE);
|
787
|
-
|
788
|
-
for (RemoteParticipant remoteParticipant : room.getRemoteParticipants()) {
|
789
|
-
addRemoteParticipant(remoteParticipant);
|
790
|
-
break;
|
791
|
-
}
|
792
|
-
}
|
793
|
-
|
794
|
-
@Override
|
795
|
-
public void onReconnecting(
|
796
|
-
@NonNull Room room, @NonNull TwilioException twilioException) {
|
797
|
-
reconnectingProgressBar.setVisibility(View.VISIBLE);
|
798
|
-
}
|
799
|
-
|
800
|
-
@Override
|
801
|
-
public void onReconnected(@NonNull Room room) {
|
802
|
-
reconnectingProgressBar.setVisibility(View.GONE);
|
803
|
-
}
|
804
|
-
|
805
|
-
@Override
|
806
|
-
public void onConnectFailure(Room room, TwilioException e) {
|
807
|
-
audioSwitch.deactivate();
|
808
|
-
intializeUI();
|
809
|
-
}
|
810
|
-
|
811
|
-
@Override
|
812
|
-
public void onDisconnected(Room room, TwilioException e) {
|
813
|
-
localParticipant = null;
|
814
|
-
reconnectingProgressBar.setVisibility(View.GONE);
|
815
|
-
CallActivity.this.room = null;
|
816
|
-
// Only reinitialize the UI if disconnect was not called from onDestroy()
|
817
|
-
if (!disconnectedFromOnDestroy) {
|
818
|
-
audioSwitch.deactivate();
|
819
|
-
intializeUI();
|
820
|
-
moveLocalVideoToPrimaryView();
|
821
|
-
}
|
822
|
-
finish();
|
823
|
-
}
|
824
|
-
|
825
|
-
@Override
|
826
|
-
public void onParticipantConnected(Room room, RemoteParticipant remoteParticipant) {
|
827
|
-
addRemoteParticipant(remoteParticipant);
|
828
|
-
}
|
829
|
-
|
830
|
-
@Override
|
831
|
-
public void onParticipantDisconnected(Room room, RemoteParticipant remoteParticipant) {
|
832
|
-
finish();
|
833
|
-
removeRemoteParticipant(remoteParticipant);
|
834
|
-
}
|
835
|
-
|
836
|
-
@Override
|
837
|
-
public void onRecordingStarted(Room room) {
|
838
|
-
/*
|
839
|
-
* Indicates when media shared to a Room is being recorded. Note that
|
840
|
-
* recording is only available in our Group Rooms developer preview.
|
841
|
-
*/
|
842
|
-
Log.d(TAG, "onRecordingStarted");
|
843
|
-
}
|
844
|
-
|
845
|
-
@Override
|
846
|
-
public void onRecordingStopped(Room room) {
|
847
|
-
/*
|
848
|
-
* Indicates when media shared to a Room is no longer being recorded. Note that
|
849
|
-
* recording is only available in our Group Rooms developer preview.
|
850
|
-
*/
|
851
|
-
Log.d(TAG, "onRecordingStopped");
|
852
|
-
}
|
853
|
-
};
|
854
|
-
}
|
855
|
-
|
856
|
-
@SuppressLint("SetTextI18n")
|
857
|
-
private RemoteParticipant.Listener remoteParticipantListener() {
|
858
|
-
return new RemoteParticipant.Listener() {
|
859
|
-
@Override
|
860
|
-
public void onAudioTrackPublished(
|
861
|
-
RemoteParticipant remoteParticipant,
|
862
|
-
RemoteAudioTrackPublication remoteAudioTrackPublication) {
|
863
|
-
Log.i(
|
864
|
-
TAG,
|
865
|
-
String.format(
|
866
|
-
"onAudioTrackPublished: "
|
867
|
-
+ "[RemoteParticipant: identity=%s], "
|
868
|
-
+ "[RemoteAudioTrackPublication: sid=%s, enabled=%b, "
|
869
|
-
+ "subscribed=%b, name=%s]",
|
870
|
-
remoteParticipant.getIdentity(),
|
871
|
-
remoteAudioTrackPublication.getTrackSid(),
|
872
|
-
remoteAudioTrackPublication.isTrackEnabled(),
|
873
|
-
remoteAudioTrackPublication.isTrackSubscribed(),
|
874
|
-
remoteAudioTrackPublication.getTrackName()));
|
875
|
-
}
|
876
|
-
|
877
|
-
@Override
|
878
|
-
public void onAudioTrackUnpublished(
|
879
|
-
RemoteParticipant remoteParticipant,
|
880
|
-
RemoteAudioTrackPublication remoteAudioTrackPublication) {
|
881
|
-
Log.i(
|
882
|
-
TAG,
|
883
|
-
String.format(
|
884
|
-
"onAudioTrackUnpublished: "
|
885
|
-
+ "[RemoteParticipant: identity=%s], "
|
886
|
-
+ "[RemoteAudioTrackPublication: sid=%s, enabled=%b, "
|
887
|
-
+ "subscribed=%b, name=%s]",
|
888
|
-
remoteParticipant.getIdentity(),
|
889
|
-
remoteAudioTrackPublication.getTrackSid(),
|
890
|
-
remoteAudioTrackPublication.isTrackEnabled(),
|
891
|
-
remoteAudioTrackPublication.isTrackSubscribed(),
|
892
|
-
remoteAudioTrackPublication.getTrackName()));
|
893
|
-
}
|
894
|
-
|
895
|
-
@Override
|
896
|
-
public void onDataTrackPublished(
|
897
|
-
RemoteParticipant remoteParticipant,
|
898
|
-
RemoteDataTrackPublication remoteDataTrackPublication) {
|
899
|
-
Log.i(
|
900
|
-
TAG,
|
901
|
-
String.format(
|
902
|
-
"onDataTrackPublished: "
|
903
|
-
+ "[RemoteParticipant: identity=%s], "
|
904
|
-
+ "[RemoteDataTrackPublication: sid=%s, enabled=%b, "
|
905
|
-
+ "subscribed=%b, name=%s]",
|
906
|
-
remoteParticipant.getIdentity(),
|
907
|
-
remoteDataTrackPublication.getTrackSid(),
|
908
|
-
remoteDataTrackPublication.isTrackEnabled(),
|
909
|
-
remoteDataTrackPublication.isTrackSubscribed(),
|
910
|
-
remoteDataTrackPublication.getTrackName()));
|
911
|
-
}
|
912
|
-
|
913
|
-
@Override
|
914
|
-
public void onDataTrackUnpublished(
|
915
|
-
RemoteParticipant remoteParticipant,
|
916
|
-
RemoteDataTrackPublication remoteDataTrackPublication) {
|
917
|
-
Log.i(
|
918
|
-
TAG,
|
919
|
-
String.format(
|
920
|
-
"onDataTrackUnpublished: "
|
921
|
-
+ "[RemoteParticipant: identity=%s], "
|
922
|
-
+ "[RemoteDataTrackPublication: sid=%s, enabled=%b, "
|
923
|
-
+ "subscribed=%b, name=%s]",
|
924
|
-
remoteParticipant.getIdentity(),
|
925
|
-
remoteDataTrackPublication.getTrackSid(),
|
926
|
-
remoteDataTrackPublication.isTrackEnabled(),
|
927
|
-
remoteDataTrackPublication.isTrackSubscribed(),
|
928
|
-
remoteDataTrackPublication.getTrackName()));
|
929
|
-
}
|
930
|
-
|
931
|
-
@Override
|
932
|
-
public void onVideoTrackPublished(
|
933
|
-
RemoteParticipant remoteParticipant,
|
934
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication) {
|
935
|
-
Log.i(
|
936
|
-
TAG,
|
937
|
-
String.format(
|
938
|
-
"onVideoTrackPublished: "
|
939
|
-
+ "[RemoteParticipant: identity=%s], "
|
940
|
-
+ "[RemoteVideoTrackPublication: sid=%s, enabled=%b, "
|
941
|
-
+ "subscribed=%b, name=%s]",
|
942
|
-
remoteParticipant.getIdentity(),
|
943
|
-
remoteVideoTrackPublication.getTrackSid(),
|
944
|
-
remoteVideoTrackPublication.isTrackEnabled(),
|
945
|
-
remoteVideoTrackPublication.isTrackSubscribed(),
|
946
|
-
remoteVideoTrackPublication.getTrackName()));
|
947
|
-
}
|
948
|
-
|
949
|
-
@Override
|
950
|
-
public void onVideoTrackUnpublished(
|
951
|
-
RemoteParticipant remoteParticipant,
|
952
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication) {
|
953
|
-
Log.i(
|
954
|
-
TAG,
|
955
|
-
String.format(
|
956
|
-
"onVideoTrackUnpublished: "
|
957
|
-
+ "[RemoteParticipant: identity=%s], "
|
958
|
-
+ "[RemoteVideoTrackPublication: sid=%s, enabled=%b, "
|
959
|
-
+ "subscribed=%b, name=%s]",
|
960
|
-
remoteParticipant.getIdentity(),
|
961
|
-
remoteVideoTrackPublication.getTrackSid(),
|
962
|
-
remoteVideoTrackPublication.isTrackEnabled(),
|
963
|
-
remoteVideoTrackPublication.isTrackSubscribed(),
|
964
|
-
remoteVideoTrackPublication.getTrackName()));
|
965
|
-
}
|
966
|
-
|
967
|
-
@Override
|
968
|
-
public void onAudioTrackSubscribed(
|
969
|
-
RemoteParticipant remoteParticipant,
|
970
|
-
RemoteAudioTrackPublication remoteAudioTrackPublication,
|
971
|
-
RemoteAudioTrack remoteAudioTrack) {
|
972
|
-
Log.i(
|
973
|
-
TAG,
|
974
|
-
String.format(
|
975
|
-
"onAudioTrackSubscribed: "
|
976
|
-
+ "[RemoteParticipant: identity=%s], "
|
977
|
-
+ "[RemoteAudioTrack: enabled=%b, playbackEnabled=%b, name=%s]",
|
978
|
-
remoteParticipant.getIdentity(),
|
979
|
-
remoteAudioTrack.isEnabled(),
|
980
|
-
remoteAudioTrack.isPlaybackEnabled(),
|
981
|
-
remoteAudioTrack.getName()));
|
982
|
-
}
|
983
|
-
|
984
|
-
@Override
|
985
|
-
public void onAudioTrackUnsubscribed(
|
986
|
-
RemoteParticipant remoteParticipant,
|
987
|
-
RemoteAudioTrackPublication remoteAudioTrackPublication,
|
988
|
-
RemoteAudioTrack remoteAudioTrack) {
|
989
|
-
Log.i(
|
990
|
-
TAG,
|
991
|
-
String.format(
|
992
|
-
"onAudioTrackUnsubscribed: "
|
993
|
-
+ "[RemoteParticipant: identity=%s], "
|
994
|
-
+ "[RemoteAudioTrack: enabled=%b, playbackEnabled=%b, name=%s]",
|
995
|
-
remoteParticipant.getIdentity(),
|
996
|
-
remoteAudioTrack.isEnabled(),
|
997
|
-
remoteAudioTrack.isPlaybackEnabled(),
|
998
|
-
remoteAudioTrack.getName()));
|
999
|
-
}
|
1000
|
-
|
1001
|
-
@Override
|
1002
|
-
public void onAudioTrackSubscriptionFailed(
|
1003
|
-
RemoteParticipant remoteParticipant,
|
1004
|
-
RemoteAudioTrackPublication remoteAudioTrackPublication,
|
1005
|
-
TwilioException twilioException) {
|
1006
|
-
Log.i(
|
1007
|
-
TAG,
|
1008
|
-
String.format(
|
1009
|
-
"onAudioTrackSubscriptionFailed: "
|
1010
|
-
+ "[RemoteParticipant: identity=%s], "
|
1011
|
-
+ "[RemoteAudioTrackPublication: sid=%b, name=%s]"
|
1012
|
-
+ "[TwilioException: code=%d, message=%s]",
|
1013
|
-
remoteParticipant.getIdentity(),
|
1014
|
-
remoteAudioTrackPublication.getTrackSid(),
|
1015
|
-
remoteAudioTrackPublication.getTrackName(),
|
1016
|
-
twilioException.getCode(),
|
1017
|
-
twilioException.getMessage()));
|
1018
|
-
}
|
1019
|
-
|
1020
|
-
@Override
|
1021
|
-
public void onDataTrackSubscribed(
|
1022
|
-
RemoteParticipant remoteParticipant,
|
1023
|
-
RemoteDataTrackPublication remoteDataTrackPublication,
|
1024
|
-
RemoteDataTrack remoteDataTrack) {
|
1025
|
-
Log.i(
|
1026
|
-
TAG,
|
1027
|
-
String.format(
|
1028
|
-
"onDataTrackSubscribed: "
|
1029
|
-
+ "[RemoteParticipant: identity=%s], "
|
1030
|
-
+ "[RemoteDataTrack: enabled=%b, name=%s]",
|
1031
|
-
remoteParticipant.getIdentity(),
|
1032
|
-
remoteDataTrack.isEnabled(),
|
1033
|
-
remoteDataTrack.getName()));
|
1034
|
-
}
|
1035
|
-
|
1036
|
-
@Override
|
1037
|
-
public void onDataTrackUnsubscribed(
|
1038
|
-
RemoteParticipant remoteParticipant,
|
1039
|
-
RemoteDataTrackPublication remoteDataTrackPublication,
|
1040
|
-
RemoteDataTrack remoteDataTrack) {
|
1041
|
-
Log.i(
|
1042
|
-
TAG,
|
1043
|
-
String.format(
|
1044
|
-
"onDataTrackUnsubscribed: "
|
1045
|
-
+ "[RemoteParticipant: identity=%s], "
|
1046
|
-
+ "[RemoteDataTrack: enabled=%b, name=%s]",
|
1047
|
-
remoteParticipant.getIdentity(),
|
1048
|
-
remoteDataTrack.isEnabled(),
|
1049
|
-
remoteDataTrack.getName()));
|
1050
|
-
}
|
1051
|
-
|
1052
|
-
@Override
|
1053
|
-
public void onDataTrackSubscriptionFailed(
|
1054
|
-
RemoteParticipant remoteParticipant,
|
1055
|
-
RemoteDataTrackPublication remoteDataTrackPublication,
|
1056
|
-
TwilioException twilioException) {
|
1057
|
-
Log.i(
|
1058
|
-
TAG,
|
1059
|
-
String.format(
|
1060
|
-
"onDataTrackSubscriptionFailed: "
|
1061
|
-
+ "[RemoteParticipant: identity=%s], "
|
1062
|
-
+ "[RemoteDataTrackPublication: sid=%b, name=%s]"
|
1063
|
-
+ "[TwilioException: code=%d, message=%s]",
|
1064
|
-
remoteParticipant.getIdentity(),
|
1065
|
-
remoteDataTrackPublication.getTrackSid(),
|
1066
|
-
remoteDataTrackPublication.getTrackName(),
|
1067
|
-
twilioException.getCode(),
|
1068
|
-
twilioException.getMessage()));
|
1069
|
-
}
|
1070
|
-
|
1071
|
-
@Override
|
1072
|
-
public void onVideoTrackSubscribed(
|
1073
|
-
RemoteParticipant remoteParticipant,
|
1074
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication,
|
1075
|
-
RemoteVideoTrack remoteVideoTrack) {
|
1076
|
-
Log.i(
|
1077
|
-
TAG,
|
1078
|
-
String.format(
|
1079
|
-
"onVideoTrackSubscribed: "
|
1080
|
-
+ "[RemoteParticipant: identity=%s], "
|
1081
|
-
+ "[RemoteVideoTrack: enabled=%b, name=%s]",
|
1082
|
-
remoteParticipant.getIdentity(),
|
1083
|
-
remoteVideoTrack.isEnabled(),
|
1084
|
-
remoteVideoTrack.getName()));
|
1085
|
-
addRemoteParticipantVideo(remoteVideoTrack);
|
1086
|
-
}
|
1087
|
-
|
1088
|
-
@Override
|
1089
|
-
public void onVideoTrackUnsubscribed(
|
1090
|
-
RemoteParticipant remoteParticipant,
|
1091
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication,
|
1092
|
-
RemoteVideoTrack remoteVideoTrack) {
|
1093
|
-
Log.i(
|
1094
|
-
TAG,
|
1095
|
-
String.format(
|
1096
|
-
"onVideoTrackUnsubscribed: "
|
1097
|
-
+ "[RemoteParticipant: identity=%s], "
|
1098
|
-
+ "[RemoteVideoTrack: enabled=%b, name=%s]",
|
1099
|
-
remoteParticipant.getIdentity(),
|
1100
|
-
remoteVideoTrack.isEnabled(),
|
1101
|
-
remoteVideoTrack.getName()));
|
1102
|
-
removeParticipantVideo(remoteVideoTrack);
|
1103
|
-
}
|
1104
|
-
|
1105
|
-
@Override
|
1106
|
-
public void onVideoTrackSubscriptionFailed(
|
1107
|
-
RemoteParticipant remoteParticipant,
|
1108
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication,
|
1109
|
-
TwilioException twilioException) {
|
1110
|
-
Log.i(
|
1111
|
-
TAG,
|
1112
|
-
String.format(
|
1113
|
-
"onVideoTrackSubscriptionFailed: "
|
1114
|
-
+ "[RemoteParticipant: identity=%s], "
|
1115
|
-
+ "[RemoteVideoTrackPublication: sid=%b, name=%s]"
|
1116
|
-
+ "[TwilioException: code=%d, message=%s]",
|
1117
|
-
remoteParticipant.getIdentity(),
|
1118
|
-
remoteVideoTrackPublication.getTrackSid(),
|
1119
|
-
remoteVideoTrackPublication.getTrackName(),
|
1120
|
-
twilioException.getCode(),
|
1121
|
-
twilioException.getMessage()));
|
1122
|
-
Snackbar.make(
|
1123
|
-
connectActionFab,
|
1124
|
-
String.format(
|
1125
|
-
"Failed to subscribe to %s video track",
|
1126
|
-
remoteParticipant.getIdentity()),
|
1127
|
-
Snackbar.LENGTH_LONG)
|
1128
|
-
.show();
|
1129
|
-
}
|
1130
|
-
|
1131
|
-
@Override
|
1132
|
-
public void onAudioTrackEnabled(
|
1133
|
-
RemoteParticipant remoteParticipant,
|
1134
|
-
RemoteAudioTrackPublication remoteAudioTrackPublication) {}
|
1135
|
-
|
1136
|
-
@Override
|
1137
|
-
public void onAudioTrackDisabled(
|
1138
|
-
RemoteParticipant remoteParticipant,
|
1139
|
-
RemoteAudioTrackPublication remoteAudioTrackPublication) {}
|
1140
|
-
|
1141
|
-
@Override
|
1142
|
-
public void onVideoTrackEnabled(
|
1143
|
-
RemoteParticipant remoteParticipant,
|
1144
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication) {}
|
1145
|
-
|
1146
|
-
@Override
|
1147
|
-
public void onVideoTrackDisabled(
|
1148
|
-
RemoteParticipant remoteParticipant,
|
1149
|
-
RemoteVideoTrackPublication remoteVideoTrackPublication) {}
|
1150
|
-
};
|
1151
|
-
}
|
1152
|
-
|
1153
|
-
|
1154
|
-
private View.OnClickListener disconnectClickListener() {
|
1155
|
-
return v -> {
|
1156
|
-
/*
|
1157
|
-
* Disconnect from room
|
1158
|
-
*/
|
1159
|
-
if (room != null) {
|
1160
|
-
room.disconnect();
|
1161
|
-
}
|
1162
|
-
intializeUI();
|
1163
|
-
};
|
1164
|
-
}
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
private View.OnClickListener switchCameraClickListener() {
|
1169
|
-
return v -> {
|
1170
|
-
if (cameraCapturerCompat != null) {
|
1171
|
-
CameraCapturerCompat.Source cameraSource = cameraCapturerCompat.getCameraSource();
|
1172
|
-
cameraCapturerCompat.switchCamera();
|
1173
|
-
if (thumbnailVideoView.getVisibility() == View.VISIBLE) {
|
1174
|
-
thumbnailVideoView.setMirror(
|
1175
|
-
cameraSource == CameraCapturerCompat.Source.BACK_CAMERA);
|
1176
|
-
} else {
|
1177
|
-
primaryVideoView.setMirror(
|
1178
|
-
cameraSource == CameraCapturerCompat.Source.BACK_CAMERA);
|
1179
|
-
}
|
1180
|
-
}
|
1181
|
-
};
|
1182
|
-
}
|
1183
|
-
|
1184
|
-
private View.OnClickListener localVideoClickListener() {
|
1185
|
-
return v -> {
|
1186
|
-
/*
|
1187
|
-
* Enable/disable the local video track
|
1188
|
-
*/
|
1189
|
-
if (localVideoTrack != null) {
|
1190
|
-
boolean enable = !localVideoTrack.isEnabled();
|
1191
|
-
localVideoTrack.enable(enable);
|
1192
|
-
int icon;
|
1193
|
-
if (enable) {
|
1194
|
-
icon = R.drawable.ic_disable_camera;
|
1195
|
-
switchCameraActionFab.show();
|
1196
|
-
} else {
|
1197
|
-
icon = R.drawable.ic_enable_camera;
|
1198
|
-
switchCameraActionFab.hide();
|
1199
|
-
}
|
1200
|
-
localVideoActionFab.setImageDrawable(
|
1201
|
-
ContextCompat.getDrawable(CallActivity.this, icon));
|
1202
|
-
}
|
1203
|
-
};
|
1204
|
-
}
|
1205
|
-
|
1206
|
-
private View.OnClickListener muteClickListener() {
|
1207
|
-
return v -> {
|
1208
|
-
/*
|
1209
|
-
* Enable/disable the local audio track. The results of this operation are
|
1210
|
-
* signaled to other Participants in the same Room. When an audio track is
|
1211
|
-
* disabled, the audio is muted.
|
1212
|
-
*/
|
1213
|
-
if (localAudioTrack != null) {
|
1214
|
-
boolean enable = !localAudioTrack.isEnabled();
|
1215
|
-
localAudioTrack.enable(enable);
|
1216
|
-
int icon = enable ? R.drawable.ic_mic : R.drawable.ic_mic_disabled;
|
1217
|
-
muteActionFab.setImageDrawable(ContextCompat.getDrawable(CallActivity.this, icon));
|
1218
|
-
}
|
1219
|
-
};
|
1220
|
-
}
|
1221
|
-
|
1222
|
-
|
1223
|
-
}
|