JLChen
2021-01-04 ed86fe7ed952bb2151aac8841134246bbde152c9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package org.linphone.sample;
 
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.TextureView;
import android.view.View;
import android.widget.RelativeLayout;
 
import androidx.annotation.Nullable;
 
import org.linphone.core.Call;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.core.VideoDefinition;
import org.linphone.core.tools.Log;
import org.linphone.mediastream.Version;
 
public class CallActivity extends Activity {
    // We use 2 TextureView, one for remote video and one for local camera preview
    private TextureView mVideoView;
    private TextureView mCaptureView;
 
    private CoreListenerStub mCoreListener;
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        setContentView(R.layout.call);
 
        mVideoView = findViewById(R.id.videoSurface);
        mCaptureView = findViewById(R.id.videoCaptureSurface);
 
        Core core = LinphoneService.getCore();
        // We need to tell the core in which to display what
        core.setNativeVideoWindowId(mVideoView);
        core.setNativePreviewWindowId(mCaptureView);
 
        // Listen for call state changes
        mCoreListener = new CoreListenerStub() {
            @Override
            public void onCallStateChanged(Core core, Call call, Call.State state, String message) {
                if (state == Call.State.End || state == Call.State.Released) {
                    // Once call is finished (end state), terminate the activity
                    // We also check for released state (called a few seconds later) just in case
                    // we missed the first one
                    finish();
                }
            }
        };
 
        findViewById(R.id.terminate_call).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Core core = LinphoneService.getCore();
                if (core.getCallsNb() > 0) {
                    Call call = core.getCurrentCall();
                    if (call == null) {
                        // Current call can be null if paused for example
                        call = core.getCalls()[0];
                    }
                    call.terminate();
                }
            }
        });
    }
 
    @Override
    protected void onStart() {
        super.onStart();
    }
 
    @Override
    protected void onResume() {
        super.onResume();
 
        LinphoneService.getCore().addListener(mCoreListener);
        resizePreview();
    }
 
    @Override
    protected void onPause() {
        LinphoneService.getCore().removeListener(mCoreListener);
 
        super.onPause();
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
 
    @TargetApi(24)
    @Override
    public void onUserLeaveHint() {
        // If the device supports Picture in Picture let's use it
        boolean supportsPip =
                getPackageManager()
                        .hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
        Log.i("[Call] Is picture in picture supported: " + supportsPip);
        if (supportsPip && Version.sdkAboveOrEqual(24)) {
            enterPictureInPictureMode();
        }
    }
 
    @Override
    public void onPictureInPictureModeChanged(
            boolean isInPictureInPictureMode, Configuration newConfig) {
        if (isInPictureInPictureMode) {
            // Currently nothing to do has we only display video
            // But if we had controls or other UI elements we should hide them
        } else {
            // If we did hide something, let's make them visible again
        }
    }
 
    private void resizePreview() {
        Core core = LinphoneService.getCore();
        if (core.getCallsNb() > 0) {
            Call call = core.getCurrentCall();
            if (call == null) {
                call = core.getCalls()[0];
            }
            if (call == null) return;
 
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            int screenHeight = metrics.heightPixels;
            int maxHeight =
                    screenHeight / 4; // Let's take at most 1/4 of the screen for the camera preview
 
            VideoDefinition videoSize =
                    call.getCurrentParams()
                            .getSentVideoDefinition(); // It already takes care of rotation
            if (videoSize.getWidth() == 0 || videoSize.getHeight() == 0) {
                Log.w(
                        "[Video] Couldn't get sent video definition, using default video definition");
                videoSize = core.getPreferredVideoDefinition();
            }
            int width = videoSize.getWidth();
            int height = videoSize.getHeight();
 
            Log.d("[Video] Video height is " + height + ", width is " + width);
            width = width * maxHeight / height;
            height = maxHeight;
 
            if (mCaptureView == null) {
                Log.e("[Video] mCaptureView is null !");
                return;
            }
 
            RelativeLayout.LayoutParams newLp = new RelativeLayout.LayoutParams(width, height);
            newLp.addRule(
                    RelativeLayout.ALIGN_PARENT_BOTTOM,
                    1); // Clears the rule, as there is no removeRule until API 17.
            newLp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 1);
            mCaptureView.setLayoutParams(newLp);
            Log.d("[Video] Video preview size set to " + width + "x" + height);
        }
    }
}