diff options
author | Shinichi Watanabe <swatanabe@uievolution.com> | 2019-09-25 12:23:48 +0900 |
---|---|---|
committer | Shinichi Watanabe <swatanabe@uievolution.com> | 2019-09-25 12:23:48 +0900 |
commit | 352fdbd221beac30c4ead9237c5ecc662a22e976 (patch) | |
tree | 6976c024b8af706c78795516faf802368008bcee /android/sdl_android/src/main/java/com/smartdevicelink/transport | |
parent | 568ffd7de0132f7577692af84cde36ddfb07de55 (diff) | |
parent | 1b57bdc3c71475a9b2c071ebdfdc805cc1dff32e (diff) | |
download | sdl_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')
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."); |