summaryrefslogtreecommitdiff
path: root/android/sdl_android/src/main/java/com/smartdevicelink/transport
diff options
context:
space:
mode:
authorShinichi Watanabe <swatanabe@uievolution.com>2019-09-25 12:23:48 +0900
committerShinichi Watanabe <swatanabe@uievolution.com>2019-09-25 12:23:48 +0900
commit352fdbd221beac30c4ead9237c5ecc662a22e976 (patch)
tree6976c024b8af706c78795516faf802368008bcee /android/sdl_android/src/main/java/com/smartdevicelink/transport
parent568ffd7de0132f7577692af84cde36ddfb07de55 (diff)
parent1b57bdc3c71475a9b2c071ebdfdc805cc1dff32e (diff)
downloadsdl_android-352fdbd221beac30c4ead9237c5ecc662a22e976.tar.gz
Merge remote-tracking branch 'upstream/develop' into feature/issue-1079
Diffstat (limited to 'android/sdl_android/src/main/java/com/smartdevicelink/transport')
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java80
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java10
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransportManager.java135
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java18
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java4
5 files changed, 211 insertions, 36 deletions
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java
index d5843f4c2..63766f0b1 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java
@@ -47,6 +47,8 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
import static com.smartdevicelink.util.DebugTool.logError;
import static com.smartdevicelink.util.NativeLogTool.logInfo;
@@ -354,8 +356,46 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport {
}
private class WriterThread extends Thread {
- private boolean mCancelled = false;
+ private boolean isHalted = false;
private boolean mVerbose = false;
+ final BlockingQueue<OutPacket> packetQueue = new LinkedBlockingQueue<>();
+
+ @Override
+ public void run() {
+ while(!isHalted){
+ try{
+ OutPacket packet = packetQueue.take();
+ if(packet == null){
+ continue;
+ }
+
+ OutputStream out;
+ synchronized (MultiplexTcpTransport.this) {
+ out = mOutputStream;
+ }
+
+ if ((out != null) && (!isHalted)) {
+ try {
+ out.write(packet.bytes, packet.offset, packet.count);
+ if (mVerbose) {
+ logInfo("TCPTransport.sendBytesOverTransport: successfully sent data");
+ }
+ } catch (IOException e) {
+ logError("TCPTransport.sendBytesOverTransport: error during sending data: " + e.getMessage());
+ }
+ } else {
+ if (isHalted) {
+ logError("TCPTransport: sendBytesOverTransport request accepted, thread is cancelled");
+ } else {
+ logError("TCPTransport: sendBytesOverTransport request accepted, but output stream is null");
+ }
+ }
+
+ }catch(InterruptedException e){
+ break;
+ }
+ }
+ }
public void write(byte[] msgBytes, int offset, int count) {
if ((msgBytes == null) || (msgBytes.length == 0)) {
@@ -366,32 +406,12 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport {
if (offset + count > msgBytes.length) {
count = msgBytes.length - offset;
}
+ packetQueue.add(new OutPacket(msgBytes, offset, count));
- OutputStream out;
- synchronized (MultiplexTcpTransport.this) {
- out = mOutputStream;
- }
-
- if ((out != null) && (!mCancelled)) {
- try {
- out.write(msgBytes, offset, count);
- if (mVerbose) {
- logInfo("TCPTransport.sendBytesOverTransport: successfully sent data");
- }
- } catch (IOException e) {
- logError("TCPTransport.sendBytesOverTransport: error during sending data: " + e.getMessage());
- }
- } else {
- if (mCancelled) {
- logError("TCPTransport: sendBytesOverTransport request accepted, thread is cancelled");
- } else {
- logError("TCPTransport: sendBytesOverTransport request accepted, but output stream is null");
- }
- }
}
public synchronized void cancel() {
- mCancelled = true;
+ isHalted = true;
if (mOutputStream != null) {
synchronized (MultiplexTcpTransport.this) {
try {
@@ -410,4 +430,18 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport {
}
}
}
+
+ private final class OutPacket{
+ byte[] bytes;
+ int count;
+ int offset;
+
+ OutPacket(byte[] bytes, int offset, int count){
+ this.bytes = bytes;
+ this.offset = offset;
+ this.count = count;
+ }
+ }
+
+
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
index dcfee9745..60ff45206 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
@@ -3173,10 +3173,10 @@ public class SdlRouterService extends Service{
* @return
*/
private TransportType getCompatPrimaryTransport(){
- if(this.registeredTransports != null){
+ if(this.registeredTransports != null && this.registeredTransports.size() > 0) {
List<TransportType> transportTypes = this.registeredTransports.valueAt(0);
- if(transportTypes != null){
- if(transportTypes.get(0) != null){
+ if (transportTypes != null) {
+ if (transportTypes.get(0) != null) {
return transportTypes.get(0);
}
}
@@ -3199,7 +3199,9 @@ public class SdlRouterService extends Service{
int flags = receivedBundle.getInt(TransportConstants.BYTES_TO_SEND_FLAGS, TransportConstants.BYTES_TO_SEND_FLAG_NONE);
TransportType transportType = TransportType.valueForString(receivedBundle.getString(TransportConstants.TRANSPORT_TYPE));
if(transportType == null){
- transportType = getCompatPrimaryTransport();
+ synchronized (TRANSPORT_LOCK){
+ transportType = getCompatPrimaryTransport();
+ }
receivedBundle.putString(TransportConstants.TRANSPORT_TYPE, transportType.name());
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransportManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransportManager.java
new file mode 100644
index 000000000..29e0c3aa1
--- /dev/null
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransportManager.java
@@ -0,0 +1,135 @@
+package com.smartdevicelink.transport;
+
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import com.smartdevicelink.protocol.SdlPacket;
+import com.smartdevicelink.transport.enums.TransportType;
+import com.smartdevicelink.transport.utl.TransportRecord;
+import com.smartdevicelink.util.DebugTool;
+
+import java.lang.ref.WeakReference;
+
+public class TCPTransportManager extends TransportManagerBase{
+
+ private static final String TAG = "TCPTransportManager";
+
+ private TCPHandler tcpHandler;
+ private MultiplexTcpTransport transport;
+ private TCPTransportConfig config;
+
+ public TCPTransportManager(TCPTransportConfig config, TransportEventListener transportEventListener){
+ super(config,transportEventListener);
+ Log.d(TAG, "USING THE TCP TRANSPORT MANAGER");
+ this.config = config;
+ tcpHandler = new TCPHandler(this);
+ transport = new MultiplexTcpTransport(config.getPort(), config.getIPAddress(),config.getAutoReconnect(),tcpHandler, null);
+ }
+
+ @Override
+ public void start() {
+ transport.start();
+
+ }
+
+ @Override
+ public void close(long sessionId) {
+ transport.stop();
+ }
+
+ @Override
+ public void resetSession() {
+ if(transport != null){
+ transport.stop();
+ }
+ //TODO make sure this makes sense
+ transport = new MultiplexTcpTransport(config.getPort(), config.getIPAddress(),config.getAutoReconnect(), tcpHandler, null);
+
+ }
+
+ @Override
+ public boolean isConnected(TransportType transportType, String address) {
+ return (transportType == null || TransportType.TCP.equals(transportType)) && transport.isConnected();
+ }
+
+ @Override
+ public TransportRecord getTransportRecord(TransportType transportType, String address) {
+ if(transport != null){
+ return transport.getTransportRecord();
+ }else{
+ return null;
+ }
+ }
+
+ @Override
+ public void sendPacket(SdlPacket packet) {
+ if(packet != null){
+ byte[] rawBytes = packet.constructPacket();
+ if(rawBytes != null && rawBytes.length >0){
+ transport.write(rawBytes, 0, rawBytes.length);
+ }
+ }
+
+ }
+
+
+ protected static class TCPHandler extends Handler {
+
+ final WeakReference<TCPTransportManager> provider;
+
+ public TCPHandler(TCPTransportManager provider){
+ this.provider = new WeakReference<>(provider);
+ }
+ @Override
+ public void handleMessage(Message msg) {
+ if(this.provider.get() == null){
+ return;
+ }
+ TCPTransportManager service = this.provider.get();
+ if(service.transportListener == null){
+ return;
+ }
+ switch (msg.what) {
+ case SdlRouterService.MESSAGE_STATE_CHANGE:
+ switch (msg.arg1) {
+ case MultiplexBaseTransport.STATE_CONNECTED:
+ synchronized (service.TRANSPORT_STATUS_LOCK){
+ service.transportStatus.clear();
+ service.transportStatus.add(service.transport.getTransportRecord());
+ }
+ DebugTool.logInfo("TCP transport has connected");
+ service.transportListener.onTransportConnected(service.transportStatus);
+ break;
+ case MultiplexBaseTransport.STATE_CONNECTING:
+ // Currently attempting to connect - update UI?
+ break;
+ case MultiplexBaseTransport.STATE_LISTEN:
+ if(service.transport != null){
+ service.transport.stop();
+ service.transport = null;
+ }
+ break;
+ case MultiplexBaseTransport.STATE_NONE:
+ // We've just lost the connection
+ if(service.transport != null){
+ service.transportListener.onTransportDisconnected("TCP transport disconnected", service.transport.transportRecord, null);
+ }else{
+ service.transportListener.onTransportDisconnected("TCP transport disconnected", null, null);
+
+ }
+ break;
+ case MultiplexBaseTransport.STATE_ERROR:
+ Log.d(TAG, "TCP transport encountered an error");
+ service.transportListener.onError("TCP transport encountered an error" );
+ break;
+ }
+ break;
+
+ case SdlRouterService.MESSAGE_READ:
+ service.transportListener.onPacketReceived((SdlPacket) msg.obj);
+ break;
+ }
+ }
+ }
+}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java
index 0ab335bf9..10cb518d4 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java
@@ -55,6 +55,7 @@ import com.smartdevicelink.transport.enums.TransportType;
import com.smartdevicelink.transport.utl.ByteAraryMessageAssembler;
import com.smartdevicelink.transport.utl.ByteArrayMessageSpliter;
import com.smartdevicelink.transport.utl.TransportRecord;
+import com.smartdevicelink.util.DebugTool;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
@@ -119,7 +120,6 @@ public class TransportBroker {
Log.d(TAG, "Unbound from service " + className.getClassName());
routerServiceMessenger = null;
registeredWithRouterService = false;
- unBindFromRouterService();
isBound = false;
onHardwareDisconnected(null, null);
}
@@ -158,6 +158,7 @@ public class TransportBroker {
Log.d(TAG, "Dead object while attempting to send packet");
routerServiceMessenger = null;
registeredWithRouterService = false;
+ unBindFromRouterService();
isBound = false;
onHardwareDisconnected(null, null);
return false;
@@ -166,6 +167,7 @@ public class TransportBroker {
Log.d(TAG, "Null messenger while attempting to send packet"); // NPE, routerServiceMessenger is null
routerServiceMessenger = null;
registeredWithRouterService = false;
+ unBindFromRouterService();
isBound = false;
onHardwareDisconnected(null, null);
return false;
@@ -448,7 +450,7 @@ public class TransportBroker {
* This method will end our communication with the router service.
*/
public void stop() {
- //Log.d(TAG, "STOPPING transport broker for " + whereToReply);
+ DebugTool.logInfo("Stopping transport broker for " + whereToReply);
synchronized (INIT_LOCK) {
unregisterWithRouterService();
unBindFromRouterService();
@@ -461,15 +463,13 @@ public class TransportBroker {
private synchronized void unBindFromRouterService() {
try {
- if (isBound && getContext() != null && routerConnection != null) {
- getContext().unbindService(routerConnection);
- isBound = false;
- } else {
- Log.w(TAG, "Unable to unbind from router service. bound? " + isBound + " context? " + (getContext()!=null) + " router connection?" + (routerConnection != null));
- }
+ getContext().unbindService(routerConnection);
- } catch (IllegalArgumentException e) {
+ } catch (Exception e) {
//This is ok
+ Log.w(TAG, "Unable to unbind from router service. bound? " + isBound + " context? " + (getContext()!=null) + " router connection?" + (routerConnection != null));
+ }finally {
+ isBound = false;
}
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java
index 6e7fd7c75..d33f4c374 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java
@@ -72,6 +72,10 @@ public class WiFiSocketFactory {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static Socket createWiFiSocket(Context context) {
+ if(context == null){
+ logInfo("Context supplied was null");
+ return null;
+ }
PackageManager pm = context.getPackageManager();
if (pm == null) {
logInfo("PackageManager isn't available.");