summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Grover <joeygrover@gmail.com>2015-08-28 10:29:08 -0400
committerJoey Grover <joeygrover@gmail.com>2015-08-28 10:29:08 -0400
commit8d38821dd98e3181108036b209c6429c80785e8c (patch)
tree3784a2e88c7ef74e1199948aa721139c24a8580a
parent95a2e431fc503ed169078527b520fa73a0e03611 (diff)
parentcad50ffc7437d073832e92fc36c4ca18955a09f3 (diff)
downloadsdl_android-8d38821dd98e3181108036b209c6429c80785e8c.tar.gz
Merge branch 'feature/heartbeat-update' of https://github.com/smartdevicelink/sdl_android into develop
Conflicts: sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlSession.java sdl_android_lib/src/com/smartdevicelink/protocol/IProtocolListener.java sdl_android_lib/src/com/smartdevicelink/protocol/WiProProtocol.java sdl_android_lib/src/com/smartdevicelink/proxy/SdlProxyBase.java sdl_android_lib/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java1
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java74
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlSession.java38
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/protocol/AbstractProtocol.java31
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/protocol/IProtocolListener.java14
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/protocol/WiProProtocol.java26
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/protocol/enums/FrameDataControlFrameType.java4
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/HeartbeatMonitor.java276
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/IHeartbeatMonitor.java7
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/proxy/SdlProxyBase.java59
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java4
11 files changed, 353 insertions, 181 deletions
diff --git a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java
index 73d53dca3..57fb15e50 100644
--- a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java
+++ b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java
@@ -27,4 +27,5 @@ public interface ISdlConnectionListener {
public void onHeartbeatTimedOut(byte sessionID);
+ public void onProtocolServiceDataACK(SessionType sessionType, byte sessionID);
}
diff --git a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java
index b4be8f2e8..384499228 100644
--- a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java
+++ b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java
@@ -545,8 +545,9 @@ public class SdlConnection implements IProtocolListener, ITransportListener, ISt
@Override
public void onHeartbeatTimedOut(byte sessionID) {
- for (SdlSession session : listenerList) {
- session.onHeartbeatTimedOut(sessionID);
+ SdlSession session = findSessionById(sessionID);
+ if (session != null) {
+ session.onHeartbeatTimedOut(sessionID);
}
}
@@ -555,40 +556,83 @@ public class SdlConnection implements IProtocolListener, ITransportListener, ISt
SdlSession session = findSessionById(sessionID);
if (session != null) {
session.onProtocolSessionEndedNACKed(sessionType, sessionID, correlationID);
- }
- }
- }
+ }
+ }
+
+ @Override
+ public void onProtocolServiceDataACK(SessionType sessionType,
+ byte sessionID) {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
+ @Override
+ public void onProtocolServiceDataACK(SessionType sessionType,
+ byte sessionID) {
+ SdlSession session = findSessionById(sessionID);
+ if (session != null) {
+ session.onProtocolServiceDataACK(sessionType, sessionID);
+ }
+ }
public int getRegisterCount() {
return listenerList.size();
}
-
- @Override
+
+ @Override
+ public void onProtocolHeartbeat(SessionType sessionType, byte sessionID) {
+ SdlSession mySession = findSessionById(sessionID);
+ if (mySession == null) return;
+
+ if (mySession._outgoingHeartbeatMonitor != null) {
+ mySession._outgoingHeartbeatMonitor.heartbeatReceived();
+ }
+ if (mySession._incomingHeartbeatMonitor != null) {
+ mySession._incomingHeartbeatMonitor.heartbeatReceived();
+ }
+ }
+
+ @Override
public void onProtocolHeartbeatACK(SessionType sessionType, byte sessionID) {
-
SdlSession mySession = findSessionById(sessionID);
if (mySession == null) return;
- if (mySession._heartbeatMonitor != null) {
- mySession._heartbeatMonitor.heartbeatACKReceived();
+ if (mySession._outgoingHeartbeatMonitor != null) {
+ mySession._outgoingHeartbeatMonitor.heartbeatACKReceived();
+ }
+ if (mySession._incomingHeartbeatMonitor != null) {
+ mySession._incomingHeartbeatMonitor.heartbeatACKReceived();
+ }
+ }
+
+ @Override
+ public void onResetOutgoingHeartbeat(SessionType sessionType, byte sessionID){
+
+ SdlSession mySession = findSessionById(sessionID);
+ if (mySession == null) return;
+
+ if (mySession._outgoingHeartbeatMonitor != null) {
+ mySession._outgoingHeartbeatMonitor.notifyTransportActivity();
}
}
@Override
- public void onResetHeartbeat(SessionType sessionType, byte sessionID){
+ public void onResetIncomingHeartbeat(SessionType sessionType, byte sessionID){
SdlSession mySession = findSessionById(sessionID);
if (mySession == null) return;
- if (mySession._heartbeatMonitor != null) {
- mySession._heartbeatMonitor.notifyTransportActivity();
+ if (mySession._incomingHeartbeatMonitor != null) {
+ mySession._incomingHeartbeatMonitor.notifyTransportActivity();
}
}
-
+
@Override
public void onProtocolSessionEndedNACKed(SessionType sessionType,
byte sessionID, String correlationID) {
_connectionListener.onProtocolSessionEndedNACKed(sessionType, sessionID, correlationID);
-
+
}
}
diff --git a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlSession.java b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlSession.java
index aa65d85ee..dbc87b792 100644
--- a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlSession.java
+++ b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlSession.java
@@ -22,7 +22,8 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
private byte wiproProcolVer;
private ISdlConnectionListener sessionListener;
private BaseTransportConfig transportConfig;
- IHeartbeatMonitor _heartbeatMonitor = null;
+ IHeartbeatMonitor _outgoingHeartbeatMonitor = null;
+ IHeartbeatMonitor _incomingHeartbeatMonitor = null;
private static final String TAG = "SdlSession";
private LockScreenManager lockScreenMan = new LockScreenManager();
@@ -50,13 +51,22 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
private SdlSession() {
}
- public IHeartbeatMonitor getHeartbeatMonitor() {
- return _heartbeatMonitor;
+ public IHeartbeatMonitor getOutgoingHeartbeatMonitor() {
+ return _outgoingHeartbeatMonitor;
}
+
+ public IHeartbeatMonitor getIncomingHeartbeatMonitor() {
+ return _incomingHeartbeatMonitor;
+ }
+
+ public void setOutgoingHeartbeatMonitor(IHeartbeatMonitor outgoingHeartbeatMonitor) {
+ this._outgoingHeartbeatMonitor = outgoingHeartbeatMonitor;
+ _outgoingHeartbeatMonitor.setListener(this);
+ }
- public void setHeartbeatMonitor(IHeartbeatMonitor heartbeatMonitor) {
- this._heartbeatMonitor = heartbeatMonitor;
- _heartbeatMonitor.setListener(this);
+ public void setIncomingHeartbeatMonitor(IHeartbeatMonitor incomingHeartbeatMonitor) {
+ this._incomingHeartbeatMonitor = incomingHeartbeatMonitor;
+ _incomingHeartbeatMonitor.setListener(this);
}
@@ -113,8 +123,11 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
}
private void initialiseSession() {
- if (_heartbeatMonitor != null) {
- _heartbeatMonitor.start();
+ if (_outgoingHeartbeatMonitor != null) {
+ _outgoingHeartbeatMonitor.start();
+ }
+ if (_incomingHeartbeatMonitor != null) {
+ _incomingHeartbeatMonitor.start();
}
}
@@ -215,10 +228,15 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
this.sessionListener.onProtocolSessionStartedNACKed(sessionType, sessionID, version, correlationID);
}
- @Override
+ @Override
public void onProtocolSessionEndedNACKed(SessionType sessionType,
byte sessionID, String correlationID) {
this.sessionListener.onProtocolSessionEndedNACKed(sessionType, sessionID, correlationID);
- }
+ }
+
+ @Override
+ public void onProtocolServiceDataACK(SessionType sessionType, byte sessionID) {
+ this.sessionListener.onProtocolServiceDataACK(sessionType, sessionID);
+ }
}
diff --git a/sdl_android_lib/src/com/smartdevicelink/protocol/AbstractProtocol.java b/sdl_android_lib/src/com/smartdevicelink/protocol/AbstractProtocol.java
index 344904051..e9439b5b1 100644
--- a/sdl_android_lib/src/com/smartdevicelink/protocol/AbstractProtocol.java
+++ b/sdl_android_lib/src/com/smartdevicelink/protocol/AbstractProtocol.java
@@ -57,6 +57,8 @@ public abstract class AbstractProtocol {
public abstract void SetHeartbeatReceiveInterval(int heartbeatReceiveInterval_ms);
public abstract void SendHeartBeat(byte sessionID);
+
+ public abstract void SendHeartBeatACK(byte sessionID);
// This method is called whenever the protocol receives a complete frame
protected void handleProtocolFrameReceived(ProtocolFrameHeader header, byte[] data, MessageFrameAssembler assembler) {
@@ -65,10 +67,16 @@ public abstract class AbstractProtocol {
assembler.handleFrame(header, data);
}
+
+ private synchronized void resetOutgoingHeartbeat(SessionType sessionType, byte sessionID) {
+ if (_protocolListener != null) {
+ _protocolListener.onResetOutgoingHeartbeat(sessionType,sessionID);
+ }
+ }
- private synchronized void resetHeartbeat(SessionType sessionType, byte sessionID) {
+ private synchronized void resetIncomingHeartbeat(SessionType sessionType, byte sessionID) {
if (_protocolListener != null) {
- _protocolListener.onResetHeartbeat(sessionType,sessionID);
+ _protocolListener.onResetIncomingHeartbeat(sessionType,sessionID);
}
}
@@ -76,7 +84,7 @@ public abstract class AbstractProtocol {
protected void handleProtocolFrameToSend(ProtocolFrameHeader header, byte[] data, int offset, int length) {
SdlTrace.logProtocolEvent(InterfaceActivityDirection.Transmit, header, data,
offset, length, SDL_LIB_TRACE_KEY);
- resetHeartbeat(header.getSessionType(), header.getSessionID());
+ resetOutgoingHeartbeat(header.getSessionType(), header.getSessionID());
synchronized(_frameLock) {
byte[] frameHeader = header.assembleHeaderBytes();
handleProtocolMessageBytesToSend(frameHeader, 0, frameHeader.length);
@@ -96,9 +104,6 @@ public abstract class AbstractProtocol {
// This method handles received protocol messages.
protected void handleProtocolMessageReceived(ProtocolMessage message) {
-
- //uncomment when SDL Core supports
- //resetHeartbeat(message.getSessionType(), message.getSessionID());
_protocolListener.onProtocolMessageReceived(message);
}
@@ -132,8 +137,18 @@ public abstract class AbstractProtocol {
// listener.
protected void handleProtocolError(String string, Exception ex) {
_protocolListener.onProtocolError(string, ex);
- }
- protected void handleProtocolHeartbeatACK(SessionType sessionType, byte sessionID) {
+ }
+ protected void handleProtocolHeartbeat(SessionType sessionType, byte sessionID) {
+ SendHeartBeatACK(sessionID);
+ _protocolListener.onProtocolHeartbeat(sessionType, sessionID);
+ }
+ protected void handleProtocolHeartbeatACK(SessionType sessionType, byte sessionID) {
_protocolListener.onProtocolHeartbeatACK(sessionType, sessionID);
}
+ protected void handleProtocolServiceDataACK(SessionType sessionType, byte sessionID) {
+ _protocolListener.onProtocolServiceDataACK(sessionType, sessionID);
+ }
+ protected void onResetIncomingHeartbeat(SessionType sessionType, byte sessionID) {
+ resetIncomingHeartbeat(sessionType, sessionID);
+ }
} // end-class
diff --git a/sdl_android_lib/src/com/smartdevicelink/protocol/IProtocolListener.java b/sdl_android_lib/src/com/smartdevicelink/protocol/IProtocolListener.java
index d1071ecc6..56dd88160 100644
--- a/sdl_android_lib/src/com/smartdevicelink/protocol/IProtocolListener.java
+++ b/sdl_android_lib/src/com/smartdevicelink/protocol/IProtocolListener.java
@@ -17,17 +17,23 @@ public interface IProtocolListener {
void onProtocolSessionNACKed(SessionType sessionType, byte sessionID, byte version, String correlationID);
// Called to indicate that a protocol session has ended (from either side)
- void onProtocolSessionEnded(SessionType sessionType, byte sessionID, String correlationID /*, String info, Exception ex*/);
+ void onProtocolSessionEnded(SessionType sessionType, byte sessionID, String correlationID /*, String info, Exception ex*/);
- void onProtocolSessionEndedNACKed(SessionType sessionType, byte sessionID, String correlationID /*, String info, Exception ex*/);
+ void onProtocolSessionEndedNACKed(SessionType sessionType, byte sessionID, String correlationID /*, String info, Exception ex*/);
+
+ void onProtocolHeartbeat(SessionType sessionType, byte sessionID);
/**
* Called when a protocol heartbeat ACK message has been received from SDL.
*/
void onProtocolHeartbeatACK(SessionType sessionType, byte sessionID);
+
+ void onProtocolServiceDataACK(SessionType sessionType, byte sessionID);
+
+ void onResetOutgoingHeartbeat(SessionType sessionType, byte sessionID);
- void onResetHeartbeat(SessionType sessionType, byte sessionID);
+ void onResetIncomingHeartbeat(SessionType sessionType, byte sessionID);
// Called to indicate that a protocol error was detected in received data.
void onProtocolError(String info, Exception e);
-} // end-interfCe \ No newline at end of file
+} // end-interfCe
diff --git a/sdl_android_lib/src/com/smartdevicelink/protocol/WiProProtocol.java b/sdl_android_lib/src/com/smartdevicelink/protocol/WiProProtocol.java
index 7f36327a8..3ac165fee 100644
--- a/sdl_android_lib/src/com/smartdevicelink/protocol/WiProProtocol.java
+++ b/sdl_android_lib/src/com/smartdevicelink/protocol/WiProProtocol.java
@@ -51,7 +51,7 @@ public class WiProProtocol extends AbstractProtocol {
return this._version;
}
- public void setVersion(byte version) {
+ public void setVersion(byte version) {
if (version > 4) {
this._version = 4; //protect for future, proxy only supports v4 or lower
HEADER_SIZE = 12;
@@ -78,7 +78,7 @@ public class WiProProtocol extends AbstractProtocol {
MAX_DATA_SIZE = V1_V2_MTU_SIZE - HEADER_SIZE;
_headerBuf = new byte[HEADER_SIZE];
}
- }
+ }
public void StartProtocolSession(SessionType sessionType) {
ProtocolFrameHeader header = ProtocolFrameHeaderFactory.createStartSession(sessionType, 0x00, _version, (byte) 0x00);
@@ -276,6 +276,8 @@ public class WiProProtocol extends AbstractProtocol {
new SdlException("Error handling protocol message from sdl, data buffer is null.", SdlExceptionCause.DATA_BUFFER_NULL));
return null;
}
+
+ onResetIncomingHeartbeat(_currentHeader.getSessionType(), _currentHeader.getSessionID());
int bytesLeft = receivedBytesLength - receivedBytesReadPos;
int bytesNeeded = _dataBuf.length - _dataBufWritePos;
@@ -423,16 +425,22 @@ public class WiProProtocol extends AbstractProtocol {
} // end-if
} // end-method
+ private void handleProtocolHeartbeat(ProtocolFrameHeader header,
+ byte[] data) {
+ WiProProtocol.this.handleProtocolHeartbeat(header.getSessionType(),header.getSessionID());
+ } // end-method
+
private void handleProtocolHeartbeatACK(ProtocolFrameHeader header,
byte[] data) {
WiProProtocol.this.handleProtocolHeartbeatACK(header.getSessionType(),header.getSessionID());
} // end-method
private void handleControlFrame(ProtocolFrameHeader header, byte[] data) {
- if (header.getFrameData() == FrameDataControlFrameType.HeartbeatACK.getValue()) {
+ if (header.getFrameData() == FrameDataControlFrameType.Heartbeat.getValue()) {
+ handleProtocolHeartbeat(header, data);
+ } else if (header.getFrameData() == FrameDataControlFrameType.HeartbeatACK.getValue()) {
handleProtocolHeartbeatACK(header, data);
- }
- else if (header.getFrameData() == FrameDataControlFrameType.StartSession.getValue()) {
+ } else if (header.getFrameData() == FrameDataControlFrameType.StartSession.getValue()) {
sendStartProtocolSessionACK(header.getSessionType(), header.getSessionID());
} else if (header.getFrameData() == FrameDataControlFrameType.StartSessionACK.getValue()) {
// Use this sessionID to create a message lock
@@ -460,6 +468,8 @@ public class WiProProtocol extends AbstractProtocol {
handleProtocolSessionEnded(header.getSessionType(), header.getSessionID(), "");
} else if (header.getFrameData() == FrameDataControlFrameType.EndSessionNACK.getValue()) {
handleProtocolSessionEndedNACK(header.getSessionType(), header.getSessionID(), "");
+ } else if (header.getFrameData() == FrameDataControlFrameType.ServiceDataACK.getValue()) {
+ handleProtocolServiceDataACK(header.getSessionType(), header.getSessionID());
}
} // end-method
@@ -520,4 +530,10 @@ public class WiProProtocol extends AbstractProtocol {
final ProtocolFrameHeader heartbeat = ProtocolFrameHeaderFactory.createHeartbeat(SessionType.CONTROL, sessionID, _version);
sendFrameToTransport(heartbeat);
}
+
+ @Override
+ public void SendHeartBeatACK(byte sessionID) {
+ final ProtocolFrameHeader heartbeat = ProtocolFrameHeaderFactory.createHeartbeatACK(SessionType.CONTROL, sessionID, _version);
+ sendFrameToTransport(heartbeat);
+ }
} // end-class \ No newline at end of file
diff --git a/sdl_android_lib/src/com/smartdevicelink/protocol/enums/FrameDataControlFrameType.java b/sdl_android_lib/src/com/smartdevicelink/protocol/enums/FrameDataControlFrameType.java
index b9296fdfb..88c92b716 100644
--- a/sdl_android_lib/src/com/smartdevicelink/protocol/enums/FrameDataControlFrameType.java
+++ b/sdl_android_lib/src/com/smartdevicelink/protocol/enums/FrameDataControlFrameType.java
@@ -19,6 +19,7 @@ public class FrameDataControlFrameType extends ByteEnumer {
public final static FrameDataControlFrameType EndSession = new FrameDataControlFrameType((byte)0x04, "EndSession");
public final static FrameDataControlFrameType EndSessionACK = new FrameDataControlFrameType((byte)0x05, "EndSessionACK");
public final static FrameDataControlFrameType EndSessionNACK = new FrameDataControlFrameType((byte)0x06, "EndSessionNACK");
+ public final static FrameDataControlFrameType ServiceDataACK = new FrameDataControlFrameType((byte)0xFE, "ServiceDataACK");
public final static FrameDataControlFrameType HeartbeatACK = new FrameDataControlFrameType((byte)0xFF, "HeartbeatACK");
static {
@@ -29,6 +30,7 @@ public class FrameDataControlFrameType extends ByteEnumer {
theList.addElement(EndSession);
theList.addElement(EndSessionACK);
theList.addElement(EndSessionNACK);
+ theList.addElement(ServiceDataACK);
theList.addElement(HeartbeatACK);
}
@@ -40,4 +42,4 @@ public class FrameDataControlFrameType extends ByteEnumer {
return theList.toArray(new FrameDataControlFrameType[theList.size()]);
}
-} \ No newline at end of file
+}
diff --git a/sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/HeartbeatMonitor.java b/sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/HeartbeatMonitor.java
index f5d4e9c84..e74fdf17e 100644
--- a/sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/HeartbeatMonitor.java
+++ b/sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/HeartbeatMonitor.java
@@ -1,67 +1,99 @@
package com.smartdevicelink.protocol.heartbeat;
+
import android.os.Handler;
import android.os.Looper;
-import android.util.Log;
+
public class HeartbeatMonitor implements IHeartbeatMonitor {
- private static final String TAG = HeartbeatMonitor.class.getSimpleName();
- private final Object HeartbeatThreadHandler_Lock = new Object();
- private final Object Listener_Lock = new Object();
- //
- private int interval;
- private IHeartbeatMonitorListener listener;
- private boolean ackReceived;
- private Thread heartbeatThread;
- private Looper heartbeatThreadLooper;
- private Handler heartbeatThreadHandler;
-
+
+ public static final int HEARTBEAT_INTERVAL = 5000;
+ public static final int HEARTBEAT_INTERVAL_MAX = Integer.MAX_VALUE;
+
+ private final Object heartbeatThreadHandlerLock = new Object();
+ private final Object listenerLock = new Object();
+
+ private int mHeartBeatInterval = HEARTBEAT_INTERVAL;
+ private boolean mHeartBeatAck = true;
+
+ private IHeartbeatMonitorListener mListener;
+ private volatile boolean mIsAckReceived;
+ private volatile boolean isHeartbeatReceived;
+ private Thread mHeartbeatThread;
+ private Looper mHeartbeatThreadLooper;
+ private Handler mHeartbeatThreadHandler;
+
+ public HeartbeatMonitor() {
+ }
+
private Runnable heartbeatTimeoutRunnable = new Runnable() {
+
+ @Override
+ public void run() {
+ try{
+ synchronized (listenerLock) {
+ if (isHeartbeatReceived) {
+ if (mListener != null) {
+ mListener.sendHeartbeat(HeartbeatMonitor.this);
+ } else {
+
+ }
+ isHeartbeatReceived = false;
+ } else {
+ if (mListener != null) {
+ mListener.heartbeatTimedOut(HeartbeatMonitor.this);
+ }
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ stop();
+ }
+ }
+ };
+
+ private Runnable heartbeatAckTimeoutRunnable = new Runnable() {
+
@Override
public void run() {
- synchronized (Listener_Lock) {
- Log.d(TAG, "run()");
-
- if (ackReceived) {
- Log.d(TAG,
- "ACK has been received, sending and scheduling heartbeat");
- if (listener != null) {
- listener.sendHeartbeat(HeartbeatMonitor.this);
- } else {
- Log.w(TAG,
- "Delegate is not set, scheduling heartbeat anyway");
- }
- ackReceived = false;
- } else {
- Log.d(TAG, "ACK has not been received");
- if (listener != null) {
- stop();
- listener.heartbeatTimedOut(HeartbeatMonitor.this);
- }
- // TODO stop?
- }
- }
+ try
+ {
+ synchronized (listenerLock) {
+ if (mIsAckReceived) {
+ if (mListener != null) {
+ mListener.sendHeartbeat(HeartbeatMonitor.this);
+ } else {
+ }
+ mIsAckReceived = false;
+ } else {
+ if (mListener != null) {
+ mListener.heartbeatTimedOut(HeartbeatMonitor.this);
+ }
+ stop();
+ }
+ }
+
+ }
+ catch(Exception ex)
+ {
+ stop();
+ }
+
rescheduleHeartbeat();
}
private void rescheduleHeartbeat() {
- synchronized (HeartbeatThreadHandler_Lock) {
- if (heartbeatThreadHandler != null) {
+ synchronized (heartbeatThreadHandlerLock) {
+ if (mHeartbeatThreadHandler != null) {
if (!Thread.interrupted()) {
- Log.d(TAG, "Rescheduling run()");
- if (!heartbeatThreadHandler.postDelayed(this,
- interval)) {
- Log.e(TAG, "Couldn't reschedule run()");
+ if (!mHeartbeatThreadHandler.postDelayed(this, mHeartBeatInterval)) {
}
} else {
- Log.i(TAG,
- "The thread is interrupted; not scheduling heartbeat");
}
} else {
- Log.e(TAG,
- "HeartbeatThread handler is not set; not scheduling heartbeat");
- HeartbeatMonitor.this.stop();
+ stop();
}
}
}
@@ -69,109 +101,123 @@ public class HeartbeatMonitor implements IHeartbeatMonitor {
@Override
public void start() {
- synchronized (HeartbeatThreadHandler_Lock) {
- if (heartbeatThread == null) {
- heartbeatThread = new Thread(new Runnable() {
- @Override
- public void run() {
- if (!Thread.interrupted()) {
- Looper.prepare();
- heartbeatThreadLooper = Looper.myLooper();
-
- heartbeatThreadHandler = new Handler();
- Log.d(TAG, "scheduling run()");
- ackReceived = true;
- if (!heartbeatThreadHandler.postDelayed(
- heartbeatTimeoutRunnable, interval)) {
- Log.e(TAG, "Couldn't schedule run()");
- }
-
- Log.d(TAG, "Starting looper");
- Looper.loop();
- Log.d(TAG, "Looper stopped, exiting thread");
- } else {
- Log.i(TAG,
- "HeartbeatThread is run, but already interrupted");
+
+ synchronized (heartbeatThreadHandlerLock) {
+
+ if (mHeartbeatThread != null) {
+ return;
+ }
+
+ mHeartbeatThread = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+
+ while (!Thread.interrupted()) {
+ Looper.prepare();
+ mHeartbeatThreadLooper = Looper.myLooper();
+
+ mHeartbeatThreadHandler = new Handler();
+ mIsAckReceived = true;
+ isHeartbeatReceived = true;
+
+ if (!mHeartbeatThreadHandler.postDelayed(
+ heartbeatAckTimeoutRunnable, mHeartBeatInterval)) {
}
+ Looper.loop();
}
- }, "HeartbeatThread");
- heartbeatThread.start();
- } else {
- Log.d(TAG, "HeartbeatThread is already started; doing nothing");
- }
+ }
+
+ }, "HeartbeatThread");
+ mHeartbeatThread.setPriority(Thread.MAX_PRIORITY);
+ mHeartbeatThread.start();
}
}
@Override
public void stop() {
- synchronized (HeartbeatThreadHandler_Lock) {
-
- if (heartbeatThread != null) {
- heartbeatThread.interrupt();
- heartbeatThread = null;
-
- if (heartbeatThreadHandler != null) {
- heartbeatThreadHandler.removeCallbacks(
- heartbeatTimeoutRunnable);
- heartbeatThreadHandler = null;
- } else {
- Log.e(TAG, "HeartbeatThread's handler is null");
- }
- if (heartbeatThreadLooper != null) {
- heartbeatThreadLooper.quit();
- heartbeatThreadLooper = null;
- } else {
- Log.e(TAG, "HeartbeatThread's looper is null");
- }
+
+ synchronized (heartbeatThreadHandlerLock) {
+
+ if (mHeartbeatThread == null) {
+ mHeartbeatThreadHandler = null;
+ mHeartbeatThreadLooper = null;
+ return;
+ }
+
+ mHeartbeatThread.interrupt();
+ mHeartbeatThread = null;
+
+ if (mHeartbeatThreadHandler != null) {
+ mHeartbeatThreadHandler.removeCallbacks(heartbeatAckTimeoutRunnable);
+ mHeartbeatThreadHandler.removeCallbacks(heartbeatTimeoutRunnable);
+ mHeartbeatThreadHandler = null;
+ } else {
+ }
+
+ if (mHeartbeatThreadLooper != null) {
+ mHeartbeatThreadLooper.quit();
+ mHeartbeatThreadLooper = null;
} else {
- Log.d(TAG, "HeartbeatThread is not started");
- // just in case
- heartbeatThreadHandler = null;
- heartbeatThreadLooper = null;
}
}
}
@Override
public int getInterval() {
- return interval;
+ return mHeartBeatInterval;
}
@Override
- public void setInterval(int interval) {
- this.interval = interval;
+ public void setInterval(int value) {
+ mHeartBeatInterval = value;
}
@Override
public IHeartbeatMonitorListener getListener() {
- return listener;
+ return mListener;
}
@Override
- public void setListener(IHeartbeatMonitorListener listener) {
- this.listener = listener;
+ public void setListener(IHeartbeatMonitorListener value) {
+ mListener = value;
}
@Override
public void notifyTransportActivity() {
- synchronized (HeartbeatThreadHandler_Lock) {
- if (heartbeatThreadHandler != null) {
- heartbeatThreadHandler.removeCallbacks(
- heartbeatTimeoutRunnable);
- if (!heartbeatThreadHandler.postDelayed(
- heartbeatTimeoutRunnable, interval)) {
- Log.e(TAG, "Couldn't reschedule run()");
- }
+ if (mHeartbeatThreadHandler == null) {
+ return;
+ }
+ synchronized (heartbeatThreadHandlerLock) {
+ if (mHeartbeatThreadHandler == null) {
+ return;
+ }
+ mHeartbeatThreadHandler.removeCallbacks(heartbeatAckTimeoutRunnable);
+ if (!mHeartbeatThreadHandler.postDelayed(heartbeatAckTimeoutRunnable, mHeartBeatInterval)) {
}
}
}
+
+ @Override
+ public synchronized void heartbeatACKReceived() {
+ synchronized (listenerLock) {
+ mIsAckReceived = true;
+ }
+ }
+
@Override
- public void heartbeatACKReceived() {
- synchronized (Listener_Lock) {
- Log.d(TAG, "ACK received");
- ackReceived = true;
+ public void heartbeatReceived() {
+ if (mHeartbeatThreadHandler == null) {
+ return;
+ }
+ synchronized (listenerLock) {
+ if (mHeartBeatAck) {
+ isHeartbeatReceived = true;
+ if (!mHeartbeatThreadHandler.post(heartbeatTimeoutRunnable)) {
+ }
+ }
}
}
-}
+} \ No newline at end of file
diff --git a/sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/IHeartbeatMonitor.java b/sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/IHeartbeatMonitor.java
index a8203e7d5..ff4feb9cb 100644
--- a/sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/IHeartbeatMonitor.java
+++ b/sdl_android_lib/src/com/smartdevicelink/protocol/heartbeat/IHeartbeatMonitor.java
@@ -51,4 +51,9 @@ public interface IHeartbeatMonitor {
* Notifies the monitor about a received heartbeat ACK message.
*/
public void heartbeatACKReceived();
-}
+
+ /**
+ * Notifies the monitor about a received heartbeat message.
+ */
+ public void heartbeatReceived();
+} \ No newline at end of file
diff --git a/sdl_android_lib/src/com/smartdevicelink/proxy/SdlProxyBase.java b/sdl_android_lib/src/com/smartdevicelink/proxy/SdlProxyBase.java
index db0d052da..4a2b0ec8d 100644
--- a/sdl_android_lib/src/com/smartdevicelink/proxy/SdlProxyBase.java
+++ b/sdl_android_lib/src/com/smartdevicelink/proxy/SdlProxyBase.java
@@ -1,9 +1,5 @@
package com.smartdevicelink.proxy;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
@@ -19,7 +15,15 @@ import java.net.URL;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
+import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
import android.app.Service;
import android.content.Context;
@@ -30,8 +34,6 @@ import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Surface;
-import com.smartdevicelink.proxy.RPCRequestFactory;
-import com.smartdevicelink.proxy.rpc.PutFile;
import com.smartdevicelink.Dispatcher.IDispatchingStrategy;
import com.smartdevicelink.Dispatcher.IncomingProtocolMessageComparitor;
import com.smartdevicelink.Dispatcher.InternalProxyMessageComparitor;
@@ -90,10 +92,6 @@ import com.smartdevicelink.transport.BaseTransportConfig;
import com.smartdevicelink.transport.SiphonServer;
import com.smartdevicelink.transport.enums.TransportType;
import com.smartdevicelink.util.DebugTool;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.ScheduledExecutorService;
public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> {
// Used for calls to Android Log class.
@@ -288,16 +286,21 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
updateBroadcastIntent(sendIntent, "COMMENT2", " ServiceType: " + sessionType.getName());
sendBroadcastIntent(sendIntent);
- setWiProVersion(version);
-
- if ( (_transportConfig.getHeartBeatTimeout() != Integer.MAX_VALUE) && (version > 2) )
- {
- HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();
- heartbeatMonitor.setInterval(_transportConfig.getHeartBeatTimeout());
- sdlSession.setHeartbeatMonitor(heartbeatMonitor);
- }
+ setWiProVersion(version);
- if (sessionType.eq(SessionType.RPC)) {
+ if (sessionType.eq(SessionType.RPC)) {
+
+ if ( (_transportConfig.getHeartBeatTimeout() != Integer.MAX_VALUE) && (version > 2))
+ {
+ HeartbeatMonitor outgoingHeartbeatMonitor = new HeartbeatMonitor();
+ outgoingHeartbeatMonitor.setInterval(_transportConfig.getHeartBeatTimeout());
+ sdlSession.setOutgoingHeartbeatMonitor(outgoingHeartbeatMonitor);
+
+ HeartbeatMonitor incomingHeartbeatMonitor = new HeartbeatMonitor();
+ incomingHeartbeatMonitor.setInterval(_transportConfig.getHeartBeatTimeout());
+ sdlSession.setIncomingHeartbeatMonitor(incomingHeartbeatMonitor);
+ }
+
startRPCProtocolSession(sessionID, correlationID);
} else if (sessionType.eq(SessionType.NAV)) {
NavServiceStarted();
@@ -386,7 +389,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
- @Override
+ @Override
public void onProtocolSessionEndedNACKed(SessionType sessionType,
byte sessionID, String correlationID) {
if (sessionType.eq(SessionType.NAV)) {
@@ -409,7 +412,21 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
AudioServiceEndedNACK();
}
- }
+ }
+ public void onProtocolServiceDataACK(SessionType sessionType,
+ byte sessionID) {
+ if (_callbackToUIThread) {
+ // Run in UI thread
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onServiceDataACK();
+ }
+ });
+ } else {
+ _proxyListener.onServiceDataACK();
+ }
+ }
}
/**
diff --git a/sdl_android_lib/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java b/sdl_android_lib/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java
index 245339ca4..636ac97c2 100644
--- a/sdl_android_lib/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java
+++ b/sdl_android_lib/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java
@@ -318,10 +318,12 @@ public interface IProxyListenerBase {
public void onDialNumberResponse(DialNumberResponse response);
public void onSendLocationResponse(SendLocationResponse response);
-
+
public void onShowConstantTbtResponse(ShowConstantTbtResponse response);
public void onAlertManeuverResponse(AlertManeuverResponse response);
public void onUpdateTurnListResponse(UpdateTurnListResponse response);
+
+ public void onServiceDataACK();
}