OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 package org.appspot.apprtc; | 11 package org.appspot.apprtc; |
12 | 12 |
13 import android.util.Log; | 13 import android.util.Log; |
14 | 14 |
15 import org.appspot.apprtc.util.LooperExecutor; | 15 import org.webrtc.ThreadUtils; |
16 | 16 |
17 import java.io.BufferedReader; | 17 import java.io.BufferedReader; |
18 import java.io.IOException; | 18 import java.io.IOException; |
19 import java.io.InputStreamReader; | 19 import java.io.InputStreamReader; |
20 import java.io.PrintWriter; | 20 import java.io.PrintWriter; |
21 import java.net.InetAddress; | 21 import java.net.InetAddress; |
22 import java.net.ServerSocket; | 22 import java.net.ServerSocket; |
23 import java.net.Socket; | 23 import java.net.Socket; |
24 import java.net.UnknownHostException; | 24 import java.net.UnknownHostException; |
| 25 import java.util.concurrent.ExecutorService; |
25 | 26 |
26 /** | 27 /** |
27 * Replacement for WebSocketChannelClient for direct communication between two I
P addresses. Handles | 28 * Replacement for WebSocketChannelClient for direct communication between two I
P addresses. Handles |
28 * the signaling between the two clients using a TCP connection. | 29 * the signaling between the two clients using a TCP connection. |
29 * | 30 * |
30 * <p>All public methods should be called from a looper executor thread | 31 * <p>All public methods should be called from a looper executor thread |
31 * passed in a constructor, otherwise exception will be thrown. | 32 * passed in a constructor, otherwise exception will be thrown. |
32 * All events are dispatched on the same thread. | 33 * All events are dispatched on the same thread. |
33 */ | 34 */ |
34 public class TCPChannelClient { | 35 public class TCPChannelClient { |
35 private static final String TAG = "TCPChannelClient"; | 36 private static final String TAG = "TCPChannelClient"; |
36 | 37 |
37 private final LooperExecutor executor; | 38 private final ExecutorService executor; |
| 39 private final ThreadUtils.ThreadChecker executorThreadCheck; |
38 private final TCPChannelEvents eventListener; | 40 private final TCPChannelEvents eventListener; |
39 private TCPSocket socket; | 41 private TCPSocket socket; |
40 | 42 |
41 /** | 43 /** |
42 * Callback interface for messages delivered on TCP Connection. All callbacks
are invoked from the | 44 * Callback interface for messages delivered on TCP Connection. All callbacks
are invoked from the |
43 * looper executor thread. | 45 * looper executor thread. |
44 */ | 46 */ |
45 public interface TCPChannelEvents { | 47 public interface TCPChannelEvents { |
46 void onTCPConnected(boolean server); | 48 void onTCPConnected(boolean server); |
47 void onTCPMessage(String message); | 49 void onTCPMessage(String message); |
48 void onTCPError(String description); | 50 void onTCPError(String description); |
49 void onTCPClose(); | 51 void onTCPClose(); |
50 } | 52 } |
51 | 53 |
52 /** | 54 /** |
53 * Initializes the TCPChannelClient. If IP is a local IP address, starts a lis
tening server on | 55 * Initializes the TCPChannelClient. If IP is a local IP address, starts a lis
tening server on |
54 * that IP. If not, instead connects to the IP. | 56 * that IP. If not, instead connects to the IP. |
55 * | 57 * |
56 * @param eventListener Listener that will receive events from the client. | 58 * @param eventListener Listener that will receive events from the client. |
57 * @param ip IP address to listen on or connect to. | 59 * @param ip IP address to listen on or connect to. |
58 * @param port Port to listen on or connect to. | 60 * @param port Port to listen on or connect to. |
59 */ | 61 */ |
60 public TCPChannelClient( | 62 public TCPChannelClient( |
61 LooperExecutor executor, TCPChannelEvents eventListener, String ip, int po
rt) { | 63 ExecutorService executor, TCPChannelEvents eventListener, String ip, int p
ort) { |
62 this.executor = executor; | 64 this.executor = executor; |
| 65 executorThreadCheck = new ThreadUtils.ThreadChecker(); |
| 66 executorThreadCheck.detachThread(); |
63 this.eventListener = eventListener; | 67 this.eventListener = eventListener; |
64 | 68 |
65 InetAddress address; | 69 InetAddress address; |
66 try { | 70 try { |
67 address = InetAddress.getByName(ip); | 71 address = InetAddress.getByName(ip); |
68 } catch (UnknownHostException e) { | 72 } catch (UnknownHostException e) { |
69 reportError("Invalid IP address."); | 73 reportError("Invalid IP address."); |
70 return; | 74 return; |
71 } | 75 } |
72 | 76 |
73 if (address.isAnyLocalAddress()) { | 77 if (address.isAnyLocalAddress()) { |
74 socket = new TCPSocketServer(address, port); | 78 socket = new TCPSocketServer(address, port); |
75 } else { | 79 } else { |
76 socket = new TCPSocketClient(address, port); | 80 socket = new TCPSocketClient(address, port); |
77 } | 81 } |
78 | 82 |
79 socket.start(); | 83 socket.start(); |
80 } | 84 } |
81 | 85 |
82 /** | 86 /** |
83 * Disconnects the client if not already disconnected. This will fire the onTC
PClose event. | 87 * Disconnects the client if not already disconnected. This will fire the onTC
PClose event. |
84 */ | 88 */ |
85 public void disconnect() { | 89 public void disconnect() { |
86 checkIfCalledOnValidThread(); | 90 executorThreadCheck.checkIsOnValidThread(); |
87 | 91 |
88 socket.disconnect(); | 92 socket.disconnect(); |
89 } | 93 } |
90 | 94 |
91 /** | 95 /** |
92 * Sends a message on the socket. | 96 * Sends a message on the socket. |
93 * | 97 * |
94 * @param message Message to be sent. | 98 * @param message Message to be sent. |
95 */ | 99 */ |
96 public void send(String message) { | 100 public void send(String message) { |
97 checkIfCalledOnValidThread(); | 101 executorThreadCheck.checkIsOnValidThread(); |
98 | 102 |
99 socket.send(message); | 103 socket.send(message); |
100 } | 104 } |
101 | 105 |
102 /** | 106 /** |
103 * Helper method for firing onTCPError events. Calls onTCPError on the executo
r thread. | 107 * Helper method for firing onTCPError events. Calls onTCPError on the executo
r thread. |
104 */ | 108 */ |
105 private void reportError(final String message) { | 109 private void reportError(final String message) { |
106 Log.e(TAG, "TCP Error: " + message); | 110 Log.e(TAG, "TCP Error: " + message); |
107 executor.execute(new Runnable() { | 111 executor.execute(new Runnable() { |
108 @Override | 112 @Override |
109 public void run() { | 113 public void run() { |
110 eventListener.onTCPError(message); | 114 eventListener.onTCPError(message); |
111 } | 115 } |
112 }); | 116 }); |
113 } | 117 } |
114 | 118 |
115 /** | |
116 * Helper method for debugging purposes. | |
117 * Ensures that TCPChannelClient method is called on a looper thread. | |
118 */ | |
119 private void checkIfCalledOnValidThread() { | |
120 if (!executor.checkOnLooperThread()) { | |
121 throw new IllegalStateException( | |
122 "TCPChannelClient method is not called on valid thread"); | |
123 } | |
124 } | |
125 | |
126 | 119 |
127 /** | 120 /** |
128 * Base class for server and client sockets. Contains a listening thread that
will call | 121 * Base class for server and client sockets. Contains a listening thread that
will call |
129 * eventListener.onTCPMessage on new messages. | 122 * eventListener.onTCPMessage on new messages. |
130 */ | 123 */ |
131 private abstract class TCPSocket extends Thread { | 124 private abstract class TCPSocket extends Thread { |
132 // Lock for editing out and rawSocket | 125 // Lock for editing out and rawSocket |
133 protected final Object rawSocketLock; | 126 protected final Object rawSocketLock; |
134 private PrintWriter out; | 127 private PrintWriter out; |
135 private Socket rawSocket; | 128 private Socket rawSocket; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 return null; | 346 return null; |
354 } | 347 } |
355 } | 348 } |
356 | 349 |
357 @Override | 350 @Override |
358 public boolean isServer() { | 351 public boolean isServer() { |
359 return false; | 352 return false; |
360 } | 353 } |
361 } | 354 } |
362 } | 355 } |
OLD | NEW |