forked from ob-f/OpenBot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPhoneController.java
228 lines (188 loc) · 7.21 KB
/
PhoneController.java
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
package org.openbot.env;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import com.google.firebase.auth.FirebaseAuth;
import org.json.JSONException;
import org.json.JSONObject;
import org.openbot.R;
import org.openbot.customview.AutoFitSurfaceGlView;
import org.openbot.customview.WebRTCSurfaceView;
import org.openbot.utils.CameraUtils;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
import timber.log.Timber;
@SuppressWarnings("ResultOfMethodCallIgnored")
public class PhoneController {
private static final String TAG = "PhoneController";
private static PhoneController _phoneController;
private ConnectionSelector connectionSelector;
private IVideoServer videoServer;
private View view = null;
private WebSocket webSocket;
public static PhoneController getInstance(Context context) {
if (_phoneController == null) { // Check for the first time
synchronized (PhoneController.class) { // Check for the second time.
// if there is no instance available... create new one
if (_phoneController == null) _phoneController = new PhoneController();
_phoneController.init(context);
}
}
return _phoneController;
}
class DataReceived implements IDataReceived {
@Override
public void dataReceived(String commandStr) {
ControllerToBotEventBus.emitEvent(commandStr);
}
}
private void init(Context context) {
ControllerConfig.getInstance().init(context);
videoServer =
"RTSP".equals(ControllerConfig.getInstance().getVideoServerType())
? new RtspServer()
: new WebRtcServer();
videoServer.init(context);
videoServer.setCanStart(true);
this.connectionSelector = ConnectionSelector.getInstance(context);
connectionSelector.getConnection().setDataCallback(new DataReceived());
android.util.Size resolution =
CameraUtils.getClosestCameraResolution(context, new android.util.Size(640, 360));
videoServer.setResolution(resolution.getWidth(), resolution.getHeight());
handleBotEvents();
createAndSetView(context);
monitorConnection();
}
private void createAndSetView(Context context) {
if (videoServer instanceof WebRtcServer) {
view = new org.openbot.customview.WebRTCSurfaceView(context);
} else if (videoServer instanceof RtspServer) {
view = new org.openbot.customview.AutoFitSurfaceGlView(context);
}
if (view != null) {
addVideoView(view, context);
}
}
private void addVideoView(View videoView, Context context) {
ViewGroup viewGroup = (ViewGroup) ((Activity) context).getWindow().getDecorView();
ViewGroup.LayoutParams layoutParams =
new ViewGroup.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
videoView.setLayoutParams(layoutParams);
videoView.setId(R.id.video_window);
videoView.setAlpha(0f);
viewGroup.addView(videoView, 0); // send to back
if (videoView instanceof WebRTCSurfaceView) {
videoServer.setView((WebRTCSurfaceView) videoView);
} else if (videoView instanceof AutoFitSurfaceGlView) {
videoServer.setView((AutoFitSurfaceGlView) videoView);
}
}
public void connect(Context context) {
ILocalConnection connection = connectionSelector.getConnection();
if (!connection.isConnected()) {
connection.init(context);
connection.connect(context);
} else {
connection.start();
}
}
public void connectWebServer(){
nodeServerConnect();
}
private void nodeServerConnect() {
// String serverUrl = "ws://verdant-imported-peanut.glitch.me";
String serverUrl = "ws://192.168.1.6:8080";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(serverUrl).build();
WebSocketListener webSocketListener = new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, @NonNull okhttp3.Response response) {
ControllerToBotEventBus.emitEvent("{command: \"CONNECTED\"}");
}
@Override
public void onMessage(@NonNull WebSocket webSocket, @NonNull String text) {
// Called when text message is received from the server
ControllerToBotEventBus.emitEvent(text);
}
@Override
public void onMessage(@NonNull WebSocket webSocket, @NonNull ByteString bytes) {
// Called when binary message is received from the server
}
@Override
public void onClosing(@NonNull WebSocket webSocket, int code, @NonNull String reason) {
// Called when the connection is closing
}
@Override
public void onClosed(@NonNull WebSocket webSocket, int code, @NonNull String reason) {
// Called when the connection is closed
}
@Override
public void onFailure(@NonNull WebSocket webSocket, Throwable t, okhttp3.Response response) {
// Called when an error occurs
}
};
webSocket = client.newWebSocket(request, webSocketListener);
}
public void disconnect() {
connectionSelector.getConnection().stop();
}
public void send(JSONObject info) {
if (webSocket != null && FirebaseAuth.getInstance().getCurrentUser() != null)
try {
info.put("roomId", FirebaseAuth.getInstance().getCurrentUser().getEmail()); // Add the roomId to the JSON object
String messageString = info.toString();
webSocket.send(messageString);
} catch (JSONException e) {
throw new RuntimeException(e);
}
if (connectionSelector.getConnection().isConnected())
connectionSelector.getConnection().sendMessage(info.toString());
}
public boolean isConnected() {
return connectionSelector.getConnection().isConnected();
}
private void handleBotEvents() {
BotToControllerEventBus.subscribe(
this::send, error -> Timber.d("Error occurred in BotToControllerEventBus: %s", error));
}
private void monitorConnection() {
ControllerToBotEventBus.subscribe(
this.getClass().getSimpleName(),
event -> {
switch (event.getString("command")) {
case "CONNECTED":
new Handler(Looper.getMainLooper()).post(() -> videoServer.setConnected(true));
// videoServer.setConnected(true);
break;
case "DISCONNECTED":
new Handler(Looper.getMainLooper()).post(() -> videoServer.setConnected(false));
// videoServer.setConnected(false);
break;
}
},
error -> {
Log.d(null, "Error occurred in monitorConnection: " + error);
},
event ->
event.has("command")
&& ("CONNECTED".equals(event.getString("command"))
|| "DISCONNECTED".equals(event.getString("command"))) // filter everything else
);
}
private PhoneController() {
if (_phoneController != null) {
throw new RuntimeException(
"Use getInstance() method to get the single instance of this class.");
}
}
}