diff options
Diffstat (limited to 'SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink')
155 files changed, 12565 insertions, 0 deletions
diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/exception/SmartDeviceLinkException.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/exception/SmartDeviceLinkException.java new file mode 100755 index 000000000..863d427bd --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/exception/SmartDeviceLinkException.java @@ -0,0 +1,49 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.exception; + +public class SmartDeviceLinkException extends Exception { + + private static final long serialVersionUID = 5922492291870772815L; + + protected Throwable detail = null; + private SmartDeviceLinkExceptionCause _SmartDeviceLinkExceptionCause = null; + + public SmartDeviceLinkException(String msg, SmartDeviceLinkExceptionCause exceptionCause) { + super(msg); + _SmartDeviceLinkExceptionCause = exceptionCause; + } + + public SmartDeviceLinkException(String msg, Throwable ex, SmartDeviceLinkExceptionCause exceptionCause) { + super(msg + " --- Check inner exception for diagnostic details"); + detail = ex; + _SmartDeviceLinkExceptionCause = exceptionCause; + } + + public SmartDeviceLinkException(Throwable ex) { + super(ex.getMessage()); + detail = ex; + } + + public SmartDeviceLinkExceptionCause getSmartDeviceLinkExceptionCause() { + return _SmartDeviceLinkExceptionCause; + } + + public Throwable getInnerException() { + return detail; + } + + public String toString() { + String ret = this.getClass().getName(); + ret += ": " + this.getMessage(); + if(this.getSmartDeviceLinkExceptionCause() != null){ + ret += "\nSmartDeviceLinkExceptionCause: " + this.getSmartDeviceLinkExceptionCause().name(); + } + if (detail != null) { + ret += "\nnested: " + detail.toString(); + detail.printStackTrace(); + } + return ret; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/exception/SmartDeviceLinkExceptionCause.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/exception/SmartDeviceLinkExceptionCause.java new file mode 100755 index 000000000..34a8b8908 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/exception/SmartDeviceLinkExceptionCause.java @@ -0,0 +1,21 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.exception; + +public enum SmartDeviceLinkExceptionCause { + BLUETOOTH_ADAPTER_NULL, + BLUETOOTH_DISABLED, + HEARTBEAT_PAST_DUE, + INCORRECT_LIFECYCLE_MODEL, + INVALID_ARGUMENT, + INVALID_RPC_PARAMETER, + PERMISSION_DENIED, + RESERVED_CORRELATION_ID, + SMARTDEVICELINK_CONNECTION_FAILED, + SMARTDEVICELINK_PROXY_CYCLED, + SMARTDEVICELINK_PROXY_DISPOSED, + SMARTDEVICELINK_PROXY_OBSOLETE, + SMARTDEVICELINK_REGISTRATION_ERROR, + SMARTDEVICELINK_UNAVAILALBE; +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/marshal/JsonRPCMarshaller.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/marshal/JsonRPCMarshaller.java new file mode 100755 index 000000000..42bf46d93 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/marshal/JsonRPCMarshaller.java @@ -0,0 +1,121 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.marshal; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import com.smartdevicelink.proxy.RPCMessage; +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.trace.*; +import com.smartdevicelink.trace.enums.InterfaceActivityDirection; +import com.smartdevicelink.util.DebugTool; + +/* + * Responsible for marshalling and unmarshing between RPC Objects and byte streams that are sent + * over transmission + */ + +public class JsonRPCMarshaller { + + private static final String SMARTDEVICELINK_LIB_PRIVATE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + + public static byte[] marshall(RPCMessage msg, byte version) { + byte[] jsonBytes = null; + try { + JSONObject jsonObject = msg.serializeJSON(version); + jsonBytes = jsonObject.toString().getBytes(); + + SyncTrace.logMarshallingEvent(InterfaceActivityDirection.Transmit, jsonBytes, SMARTDEVICELINK_LIB_PRIVATE_KEY); + } catch (JSONException e) { + DebugTool.logError("Failed to encode messages to JSON.", e); + } + return jsonBytes; + } + + public static Hashtable<String, Object> unmarshall(byte[] message) { + SyncTrace.logMarshallingEvent(InterfaceActivityDirection.Receive, message, SMARTDEVICELINK_LIB_PRIVATE_KEY); + Hashtable<String, Object> ret = null; + try { + String jsonString = new String(message); + JSONObject jsonObject = new JSONObject(jsonString); + ret = deserializeJSONObject(jsonObject); + } catch (JSONException e) { + DebugTool.logError("Failed to parse JSON", e); + } + return ret; + } + + public static Hashtable<String, Object> deserializeJSONObject(JSONObject jsonObject) + throws JSONException { + Hashtable<String, Object> ret = new Hashtable<String, Object>(); + Iterator it = jsonObject.keys(); + String key = null; + while (it.hasNext()) { + key = (String) it.next(); + Object value = jsonObject.get(key); + if (value instanceof JSONObject) { + ret.put(key, deserializeJSONObject((JSONObject)value)); + } else if (value instanceof JSONArray) { + JSONArray arrayValue = (JSONArray) value; + Vector<Object> putList = new Vector<Object>(arrayValue.length()); + for (int i = 0; i < arrayValue.length(); i++) { + Object anObject = arrayValue.get(i); + if (anObject instanceof JSONObject) { + Hashtable<String, Object> deserializedObject = deserializeJSONObject((JSONObject)anObject); + putList.add(deserializedObject); + } else { + putList.add(anObject); + } + } + ret.put(key, putList); + } else { + ret.put(key, value); + } + } + return ret; + } + + private static JSONArray serializeVector(Vector vector) throws JSONException{ + JSONArray toPut = new JSONArray(); + Iterator<Object> valueIterator = (vector).iterator(); + while(valueIterator.hasNext()){ + Object anObject = valueIterator.next(); + if (anObject instanceof RPCStruct) { + RPCStruct toSerialize = (RPCStruct) anObject; + toPut.put(toSerialize.serializeJSON()); + } else if(anObject instanceof Hashtable){ + Hashtable toSerialize = (Hashtable)anObject; + toPut.put(serializeHashtable(toSerialize)); + } else { + toPut.put(anObject); + } + } + return toPut; + } + + public static JSONObject serializeHashtable(Hashtable<String, Object> hash) throws JSONException{ + JSONObject obj = new JSONObject(); + Iterator<String> hashKeyIterator = hash.keySet().iterator(); + while (hashKeyIterator.hasNext()){ + String key = (String) hashKeyIterator.next(); + Object value = hash.get(key); + if (value instanceof RPCStruct) { + obj.put(key, ((RPCStruct) value).serializeJSON()); + } else if (value instanceof Vector<?>) { + obj.put(key, serializeVector((Vector) value)); + } else if (value instanceof Hashtable) { + obj.put(key, serializeHashtable((Hashtable)value)); + } else { + obj.put(key, value); + } + } + return obj; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/IDispatchingStrategy.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/IDispatchingStrategy.java new file mode 100755 index 000000000..defdc9fd6 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/IDispatchingStrategy.java @@ -0,0 +1,12 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.messageDispatcher; + +public interface IDispatchingStrategy<messageType> { + public void dispatch(messageType message); + + public void handleDispatchingError(String info, Exception ex); + + public void handleQueueingError(String info, Exception ex); +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/IncomingProtocolMessageComparitor.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/IncomingProtocolMessageComparitor.java new file mode 100755 index 000000000..f59810b2f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/IncomingProtocolMessageComparitor.java @@ -0,0 +1,17 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.messageDispatcher; + +import java.util.Comparator; + +import com.smartdevicelink.protocol.ProtocolMessage; + +public class IncomingProtocolMessageComparitor implements Comparator<ProtocolMessage> { + + @Override + public int compare(ProtocolMessage arg0, ProtocolMessage arg1) { + // Always return 0, turning the priority queue into a FIFO queue. + return 0; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/InternalProxyMessageComparitor.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/InternalProxyMessageComparitor.java new file mode 100755 index 000000000..92de89e5b --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/InternalProxyMessageComparitor.java @@ -0,0 +1,17 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.messageDispatcher; + +import java.util.Comparator; + +import com.smartdevicelink.proxy.callbacks.InternalProxyMessage; + +public class InternalProxyMessageComparitor implements Comparator<InternalProxyMessage> { + + @Override + public int compare(InternalProxyMessage arg0, InternalProxyMessage arg1) { + // Always return 0, turning the priority queue into a FIFO queue. + return 0; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/OutgoingProtocolMessageComparitor.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/OutgoingProtocolMessageComparitor.java new file mode 100755 index 000000000..9545689b4 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/OutgoingProtocolMessageComparitor.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.messageDispatcher; + +import java.util.Comparator; + +import com.smartdevicelink.protocol.ProtocolMessage; + +public class OutgoingProtocolMessageComparitor implements Comparator<ProtocolMessage> { + + @Override + public int compare(ProtocolMessage arg0, ProtocolMessage arg1) { + // Always return 0, turning the priority queue into a FIFO queue. + return 0; + } +} + diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/ProxyMessageDispatcher.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/ProxyMessageDispatcher.java new file mode 100755 index 000000000..b3f72b010 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/messageDispatcher/ProxyMessageDispatcher.java @@ -0,0 +1,68 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.messageDispatcher; + +import java.util.Comparator; +import java.util.concurrent.PriorityBlockingQueue; + +import com.smartdevicelink.util.DebugTool; + +public class ProxyMessageDispatcher<messageType> { + PriorityBlockingQueue<messageType> _queue = null; + private Thread _messageDispatchingThread = null; + IDispatchingStrategy<messageType> _strategy = null; + + // Boolean to track if disposed + private Boolean dispatcherDisposed = false; + + public ProxyMessageDispatcher(String THREAD_NAME, Comparator<messageType> messageComparator, + IDispatchingStrategy<messageType> strategy) { + _queue = new PriorityBlockingQueue<messageType>(10, messageComparator); + + _strategy = strategy; + + // Create dispatching thread + _messageDispatchingThread = new Thread(new Runnable() {public void run(){handleMessages();}}); + _messageDispatchingThread.setName(THREAD_NAME); + _messageDispatchingThread.setDaemon(true); + _messageDispatchingThread.start(); + } + + public void dispose() { + dispatcherDisposed = true; + + if(_messageDispatchingThread != null) { + _messageDispatchingThread.interrupt(); + _messageDispatchingThread = null; + } + } + + private void handleMessages() { + + try { + messageType thisMessage; + + while(dispatcherDisposed == false) { + thisMessage = _queue.take(); + _strategy.dispatch(thisMessage); + } + } catch (InterruptedException e) { + // Thread was interrupted by dispose() method, no action required + return; + } catch (Exception e) { + DebugTool.logError("Error occurred dispating message.", e); + _strategy.handleDispatchingError("Error occurred dispating message.", e); + } + } + + public void queueMessage(messageType message) { + try { + _queue.put(message); + } catch(ClassCastException e) { + _strategy.handleQueueingError("ClassCastException encountered when queueing message.", e); + } catch(Exception e) { + _strategy.handleQueueingError("Exception encountered when queueing message.", e); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/AbstractProtocol.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/AbstractProtocol.java new file mode 100755 index 000000000..dbbc24226 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/AbstractProtocol.java @@ -0,0 +1,105 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol; + +import com.smartdevicelink.protocol.SmartDeviceLinkProtocol.MessageFrameAssembler; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.trace.SyncTrace; +import com.smartdevicelink.trace.enums.InterfaceActivityDirection; + +public abstract class AbstractProtocol { + private static final String SmartDeviceLink_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + + private IProtocolListener _protocolListener = null; + + // Lock to ensure all frames are sent uninterupted + private Object _frameLock = new Object(); + + // Caller must provide a non-null IProtocolListener interface reference. + public AbstractProtocol(IProtocolListener protocolListener) { + if (protocolListener == null) { + throw new IllegalArgumentException("Provided protocol listener interface reference is null"); + } // end-if + + _protocolListener = protocolListener; + } // end-ctor + + // This method receives raw bytes as they arrive from transport. Those bytes + // are then collected by the protocol and assembled into complete messages and + // handled internally by the protocol or propagated to the protocol listener. + public abstract void HandleReceivedBytes(byte[] receivedBytes, int length); + + // This method receives a protocol message (e.g. RPC, BULK, etc.) and processes + // it for transmission over the transport. The results of this processing will + // be sent to the onProtocolMessageBytesToSend() method on protocol listener + // interface. Note that the ProtocolMessage itself contains information + // about the type of message (e.g. RPC, BULK, etc.) and the protocol session + // over which to send the message, etc. + public abstract void SendMessage(ProtocolMessage msg); + + // This method starts a protocol session. A corresponding call to the protocol + // listener onProtocolSessionStarted() method will be made when the protocol + // session has been established. + public abstract void StartProtocolSession(SessionType sessionType); + + // This method ends a protocol session. A corresponding call to the protocol + // listener onProtocolSessionEnded() method will be made when the protocol + // session has ended. + public abstract void EndProtocolSession(SessionType sessionType, byte sessionID); + + // This method is called whenever the protocol receives a complete frame + protected void handleProtocolFrameReceived(ProtocolFrameHeader header, byte[] data, MessageFrameAssembler assembler) { + SyncTrace.logProtocolEvent(InterfaceActivityDirection.Receive, header, data, + 0, data.length, SmartDeviceLink_LIB_TRACE_KEY); + + assembler.handleFrame(header, data); + } + + // This method is called whenever a protocol has an entire frame to send + protected void handleProtocolFrameToSend(ProtocolFrameHeader header, byte[] data, int offset, int length) { + SyncTrace.logProtocolEvent(InterfaceActivityDirection.Transmit, header, data, + offset, length, SmartDeviceLink_LIB_TRACE_KEY); + + synchronized(_frameLock) { + byte[] frameHeader = header.assembleHeaderBytes(); + handleProtocolMessageBytesToSend(frameHeader, 0, frameHeader.length); + + if (data != null) { + handleProtocolMessageBytesToSend(data, offset, length); + } // end-if + } + } + + // This method handles protocol message bytes that are ready to send. + // A callback is sent to the protocol listener. + protected void handleProtocolMessageBytesToSend(byte[] bytesToSend, + int offset, int length) { + _protocolListener.onProtocolMessageBytesToSend(bytesToSend, offset, length); + } + + // This method handles received protocol messages. + protected void handleProtocolMessageReceived(ProtocolMessage message) { + _protocolListener.onProtocolMessageReceived(message); + } + + // This method handles the end of a protocol session. A callback is + // sent to the protocol listener. + protected void handleProtocolSessionEnded(SessionType sessionType, + byte sessionID, String correlationID) { + _protocolListener.onProtocolSessionEnded(sessionType, sessionID, correlationID); + } + + // This method handles the startup of a protocol session. A callback is sent + // to the protocol listener. + protected void handleProtocolSessionStarted(SessionType sessionType, + byte sessionID, byte version, String correlationID) { + _protocolListener.onProtocolSessionStarted(sessionType, sessionID, version, correlationID); + } + + // This method handles protocol errors. A callback is sent to the protocol + // listener. + protected void handleProtocolError(String string, Exception ex) { + _protocolListener.onProtocolError(string, ex); + } +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/BinaryFrameHeader.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/BinaryFrameHeader.java new file mode 100644 index 000000000..65985eec5 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/BinaryFrameHeader.java @@ -0,0 +1,109 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol; + +import com.smartdevicelink.util.BitConverter; + +public class BinaryFrameHeader { + private byte _rpcType; + private int _functionID; + private int _correlationID; + private int _jsonSize; + + private byte[] _jsonData; + private byte[] _bulkData; + + public BinaryFrameHeader() {} + + public static BinaryFrameHeader parseBinaryHeader(byte[] binHeader) { + BinaryFrameHeader msg = new BinaryFrameHeader(); + + byte RPC_Type = (byte) (binHeader[0] >>> 4); + msg.setRPCType(RPC_Type); + + int _functionID = (BitConverter.intFromByteArray(binHeader, 0) & 0x0FFFFFFF); + msg.setFunctionID(_functionID); + + int corrID = BitConverter.intFromByteArray(binHeader, 4); + msg.setCorrID(corrID); + + int _jsonSize = BitConverter.intFromByteArray(binHeader, 8); + msg.setJsonSize(_jsonSize); + + if (_jsonSize > 0) { + byte[] _jsonData = new byte[_jsonSize]; + System.arraycopy(binHeader, 12, _jsonData, 0, _jsonSize); + msg.setJsonData(_jsonData); + } + + if (binHeader.length - _jsonSize - 12 > 0) { + byte[] _bulkData = new byte[binHeader.length - _jsonSize - 12]; + System.arraycopy(binHeader, 12 + _jsonSize, _bulkData, 0, _bulkData.length); + msg.setBulkData(_bulkData); + } + + return msg; + } + + protected byte[] assembleHeaderBytes() { + int binHeader = _functionID; + binHeader |= (_rpcType << 28); + + byte[] ret = new byte[12]; + System.arraycopy(BitConverter.intToByteArray(binHeader), 0, ret, 0, 4); + System.arraycopy(BitConverter.intToByteArray(_correlationID), 0, ret, 4, 4); + System.arraycopy(BitConverter.intToByteArray(_jsonSize), 0, ret, 8, 4); + + return ret; + } + + public byte getRPCType() { + return _rpcType; + } + + public void setRPCType(byte _rpcType) { + this._rpcType = _rpcType; + } + + public int getFunctionID() { + return _functionID; + } + + public void setFunctionID(int _functionID) { + this._functionID = _functionID; + } + + public int getCorrID() { + return _correlationID; + } + + public void setCorrID(int _correlationID) { + this._correlationID = _correlationID; + } + + public int getJsonSize() { + return _jsonSize; + } + + public void setJsonSize(int _jsonSize) { + this._jsonSize = _jsonSize; + } + + public byte[] getJsonData() { + return _jsonData; + } + + public void setJsonData(byte[] _jsonData) { + this._jsonData = new byte[this._jsonSize]; + System.arraycopy(_jsonData, 0, this._jsonData, 0, _jsonSize); + } + + public byte[] getBulkData() { + return _bulkData; + } + + public void setBulkData(byte[] _bulkData) { + this._bulkData = _bulkData; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/IProtocol.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/IProtocol.java new file mode 100755 index 000000000..5acba98c1 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/IProtocol.java @@ -0,0 +1,25 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol; + +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.transport.ISmartDeviceLinkTransport; +import com.smartdevicelink.transport.ITransportListener; + +public interface IProtocol extends ITransportListener { + + void handleBytesFromTransport(byte[] receivedBytes, int receivedBytesLength); + public void sendStartSession(SessionType sessionType); + public void sendEndSession(SessionType sessionType, byte sessionID); + + public void sendData(SessionType sessionType, byte sessionID, byte[] data); + + public ISmartDeviceLinkTransport getTransport(); + public void setTransport(ISmartDeviceLinkTransport transport); + + void addProtocolListener(IProtocolListener listener); + boolean removeProtocolListener(IProtocolListener listener); + + public void close(); +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/IProtocolListener.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/IProtocolListener.java new file mode 100755 index 000000000..b660030bb --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/IProtocolListener.java @@ -0,0 +1,25 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol; + +import com.smartdevicelink.protocol.enums.*; + +public interface IProtocolListener { + // Called to indicate that these bytes are to be sent as part of a message. + // This call includes the part of the message. + void onProtocolMessageBytesToSend(byte[] msgBytes, int offset, int length); + + // Called to indicate that a complete message (RPC, BULK, etc.) has been + // received. This call includes the message. + void onProtocolMessageReceived(ProtocolMessage msg); + + // Called to indicate that a protocol session has been started (from either side) + void onProtocolSessionStarted(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*/); + + // Called to indicate that a protocol error was detected in received data. + void onProtocolError(String info, Exception e); +} // end-interfCe diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolFrameHeader.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolFrameHeader.java new file mode 100755 index 000000000..be8bd8721 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolFrameHeader.java @@ -0,0 +1,162 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol; + +import com.smartdevicelink.protocol.enums.FrameType; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.util.BitConverter; + +public class ProtocolFrameHeader { + private byte version = 1; + private boolean compressed = false; + private FrameType frameType = FrameType.Control; + private SessionType sessionType = SessionType.RPC; + private byte frameData = 0; + private byte sessionID; + private int dataSize; + private int messageID; + + public static final byte FrameDataSingleFrame = 0x00; + public static final byte FrameDataFirstFrame = 0x00; + public static final byte FrameDataFinalConsecutiveFrame = 0x00; + + public ProtocolFrameHeader() {} + + public static ProtocolFrameHeader parseWiProHeader(byte[] header) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + + byte version = (byte) (header[0] >>> 4); + msg.setVersion(version); + + boolean compressed = 1 == ((header[0] & 0x08) >>> 3); + msg.setCompressed(compressed); + + byte frameType = (byte) (header[0] & 0x07); + msg.setFrameType(FrameType.valueOf(frameType)); + + byte serviceType = header[1]; + msg.setSessionType(SessionType.valueOf(serviceType)); + + byte frameData = header[2]; + msg.setFrameData(frameData); + + byte sessionID = header[3]; + msg.setSessionID(sessionID); + + int dataSize = BitConverter.intFromByteArray(header, 4); + msg.setDataSize(dataSize); + + if (version == 2) { + int messageID = BitConverter.intFromByteArray(header, 8); + msg.setMessageID(messageID); + } else msg.setMessageID(0); + + return msg; + } + + protected byte[] assembleHeaderBytes() { + int header = 0; + header |= version; + header <<= 1; + header |= (compressed ? 1 : 0); + header <<= 3; + header |= frameType.value(); + header <<= 8; + header |= sessionType.value(); + header <<= 8; + header |= frameData; + header <<= 8; + header |= sessionID; + + if (version == 1) { + byte[] ret = new byte[8]; + System.arraycopy(BitConverter.intToByteArray(header), 0, ret, 0, 4); + System.arraycopy(BitConverter.intToByteArray(dataSize), 0, ret, 4, 4); + + return ret; + } else if (version == 2) { + byte[] ret = new byte[12]; + System.arraycopy(BitConverter.intToByteArray(header), 0, ret, 0, 4); + System.arraycopy(BitConverter.intToByteArray(dataSize), 0, ret, 4, 4); + System.arraycopy(BitConverter.intToByteArray(messageID), 0, ret, 8, 4); + + return ret; + } else return null; + } + + public String toString() { + String ret = ""; + ret += "version " + version + ", " + (compressed ? "compressed" : "uncompressed") + "\n"; + ret += "frameType " + frameType + ", serviceType " + sessionType; + ret += "\nframeData " + frameData; + ret += ", sessionID " + sessionID; + ret += ", dataSize " + dataSize; + ret += ", messageID " + messageID; + return ret; + } + + public byte getVersion() { + return version; + } + + public void setVersion(byte version) { + this.version = version; + } + + public boolean isCompressed() { + return compressed; + } + + public void setCompressed(boolean compressed) { + this.compressed = compressed; + } + + public byte getFrameData() { + return frameData; + } + + public void setFrameData(byte frameData) { + this.frameData = frameData; + } + + public byte getSessionID() { + return sessionID; + } + + public void setSessionID(byte sessionID) { + this.sessionID = sessionID; + } + + public int getDataSize() { + return dataSize; + } + + public void setDataSize(int dataSize) { + this.dataSize = dataSize; + } + + public int getMessageID() { + return messageID; + } + + public void setMessageID(int messageID) { + this.messageID = messageID; + } + + public FrameType getFrameType() { + return frameType; + } + + public void setFrameType(FrameType frameType) { + this.frameType = frameType; + } + + public SessionType getSessionType() { + return sessionType; + } + + public void setSessionType(SessionType sessionType) { + this.sessionType = sessionType; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolFrameHeaderFactory.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolFrameHeaderFactory.java new file mode 100755 index 000000000..d92b92187 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolFrameHeaderFactory.java @@ -0,0 +1,122 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol; + +import com.smartdevicelink.protocol.enums.*; + +public class ProtocolFrameHeaderFactory { + + public static ProtocolFrameHeader createStartSession(SessionType serviceType, int messageID, byte version) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + msg.setVersion(version); + msg.setFrameType(FrameType.Control); + msg.setSessionType(serviceType); + msg.setFrameData(FrameDataControlFrameType.StartSession.value()); + msg.setMessageID(messageID); + + return msg; + } + + public static ProtocolFrameHeader createStartSessionACK(SessionType serviceType, byte sessionID, int messageID, byte version) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + msg.setVersion(version); + msg.setFrameType(FrameType.Control); + msg.setSessionType(serviceType); + msg.setSessionID(sessionID); + msg.setFrameData(FrameDataControlFrameType.StartSessionACK.value()); + msg.setMessageID(messageID); + + return msg; + } + + public static ProtocolFrameHeader createStartSessionNACK(SessionType serviceType, byte sessionID, int messageID, byte version) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + msg.setVersion(version); + msg.setFrameType(FrameType.Control); + msg.setSessionType(serviceType); + msg.setSessionID(sessionID); + msg.setFrameData(FrameDataControlFrameType.StartSessionNACK.value()); + msg.setMessageID(messageID); + + return msg; + } + + public static ProtocolFrameHeader createEndSession(SessionType serviceType, byte sessionID, int messageID, byte version) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + msg.setVersion(version); + msg.setFrameType(FrameType.Control); + msg.setSessionType(serviceType); + msg.setSessionID(sessionID); + msg.setFrameData(FrameDataControlFrameType.EndSession.value()); + msg.setMessageID(messageID); + + return msg; + } + + public static ProtocolFrameHeader createSingleSendData(SessionType serviceType, byte sessionID, + int dataLength, int messageID, byte version) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + msg.setVersion(version); + msg.setFrameType(FrameType.Single); + msg.setSessionType(serviceType); + msg.setFrameData(ProtocolFrameHeader.FrameDataSingleFrame); + msg.setSessionID(sessionID); + msg.setDataSize(dataLength); + msg.setMessageID(messageID); + + return msg; + } + + public static ProtocolFrameHeader createMultiSendDataFirst(SessionType serviceType, byte sessionID, + int messageID, byte version) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + msg.setVersion(version); + msg.setFrameType(FrameType.First); + msg.setSessionType(serviceType); + msg.setFrameData(ProtocolFrameHeader.FrameDataFirstFrame); + msg.setSessionID(sessionID); + msg.setDataSize(8); + msg.setMessageID(messageID); + + return msg; + } + + public static ProtocolFrameHeader createMultiSendDataRest(SessionType serviceType, byte sessionID, + int dataLength, byte frameSequenceNumber, int messageID, byte version) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + msg.setVersion(version); + msg.setFrameType(FrameType.Consecutive); + msg.setSessionType(serviceType); + msg.setFrameData(frameSequenceNumber/*FrameData.ConsecutiveFrame.value()*/); + msg.setSessionID(sessionID); + msg.setDataSize(dataLength); + msg.setMessageID(messageID); + + return msg; + } + + public static ProtocolFrameHeader createMultiSendDataRest(SessionType serviceType, byte sessionID, + int dataLength, int messageID, byte version) { + ProtocolFrameHeader msg = new ProtocolFrameHeader(); + msg.setVersion(version); + msg.setFrameType(FrameType.Consecutive); + msg.setSessionType(serviceType); + msg.setFrameData(FrameData.ConsecutiveFrame.value()); + msg.setSessionID(sessionID); + msg.setDataSize(dataLength); + msg.setMessageID(messageID); + + return msg; + } + + public static BinaryFrameHeader createBinaryFrameHeader(byte rpcType, int functionID, int corrID, int jsonSize) { + BinaryFrameHeader msg = new BinaryFrameHeader(); + msg.setRPCType(rpcType); + msg.setFunctionID(functionID); + msg.setCorrID(corrID); + msg.setJsonSize(jsonSize); + + return msg; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolMessage.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolMessage.java new file mode 100755 index 000000000..06668f2fa --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/ProtocolMessage.java @@ -0,0 +1,108 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol; + +import com.smartdevicelink.protocol.enums.MessageType; +import com.smartdevicelink.protocol.enums.SessionType; + +public class ProtocolMessage { + private byte version = 1; + private SessionType _sessionType = SessionType.RPC; + private MessageType _messageType = MessageType.UNDEFINED; + private byte _sessionID = 0; + private byte _rpcType; + private int _functionID; + private int _correlationID; + private int _jsonSize; + + private byte[] _data = null; + private byte[] _bulkData = null; + + public ProtocolMessage() {} + + public byte getVersion() { + return version; + } + + public void setVersion(byte version) { + this.version = version; + } + + public byte getSessionID() { + return _sessionID; + } + + public void setSessionID(byte sessionID) { + this._sessionID = sessionID; + } + + public byte[] getData() { + return _data; + } + + public void setData(byte[] data) { + this._data = data; + this._jsonSize = data.length; + } + + public byte[] getBulkData() { + return _bulkData; + } + + public void setBulkData(byte[] bulkData) { + if (this._bulkData != null) + this._bulkData = null; + this._bulkData = new byte[bulkData.length]; + System.arraycopy(bulkData, 0, this._bulkData, 0, bulkData.length); + //this._bulkData = bulkData; + } + + public SessionType getSessionType() { + return _sessionType; + } + + public void setSessionType(SessionType sessionType) { + this._sessionType = sessionType; + } + + public MessageType getMessageType() { + return _messageType; + } + + public void setMessageType(MessageType messageType) { + this._messageType = messageType; + } + + public byte getRPCType() { + return _rpcType; + } + + public void setRPCType(byte _rpcType) { + this._rpcType = _rpcType; + } + + public int getFunctionID() { + return _functionID; + } + + public void setFunctionID(int _functionID) { + this._functionID = _functionID; + } + + public int getCorrID() { + return _correlationID; + } + + public void setCorrID(int _correlationID) { + this._correlationID = _correlationID; + } + + public int getJsonSize() { + return _jsonSize; + } + + public void setJsonSize(int _jsonSize) { + this._jsonSize = _jsonSize; + } +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/SmartDeviceLinkProtocol.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/SmartDeviceLinkProtocol.java new file mode 100755 index 000000000..d1d5f3805 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/SmartDeviceLinkProtocol.java @@ -0,0 +1,378 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol; + +import java.io.ByteArrayOutputStream; +import java.util.Hashtable; + +import com.smartdevicelink.protocol.enums.*; +import com.smartdevicelink.util.BitConverter; +import com.smartdevicelink.util.DebugTool; +import com.smartdevicelink.exception.*; + +public class SmartDeviceLinkProtocol extends AbstractProtocol { + byte _version = 1; + private final static String FailurePropagating_Msg = "Failure propagating "; + + public static final int MTU_SIZE = 1500; + public static int HEADER_SIZE = 8; + public static int MAX_DATA_SIZE = MTU_SIZE - HEADER_SIZE; + + boolean _haveHeader = false; + byte[] _headerBuf = new byte[HEADER_SIZE]; + int _headerBufWritePos = 0; + ProtocolFrameHeader _currentHeader = null; + byte[] _dataBuf = null; + int _dataBufWritePos = 0; + + int hashID = 0; + int messageID = 0; + + Hashtable<Integer, MessageFrameAssembler> _assemblerForMessageID = new Hashtable<Integer, MessageFrameAssembler>(); + Hashtable<Byte, Hashtable<Integer, MessageFrameAssembler>> _assemblerForSessionID = new Hashtable<Byte, Hashtable<Integer, MessageFrameAssembler>>(); + Hashtable<Byte, Object> _messageLocks = new Hashtable<Byte, Object>(); + + // Hide no-arg ctor + private SmartDeviceLinkProtocol() { + super(null); + } // end-ctor + + public SmartDeviceLinkProtocol(IProtocolListener protocolListener) { + super(protocolListener); + } // end-ctor + + public byte getVersion() { + return this._version; + } + + public void setVersion(byte version) { + this._version = version; + if (version == 2) { + HEADER_SIZE = 12; + MAX_DATA_SIZE = MTU_SIZE - HEADER_SIZE; + _headerBuf = new byte[HEADER_SIZE]; + } + } + + public void StartProtocolSession(SessionType sessionType) { + ProtocolFrameHeader header = ProtocolFrameHeaderFactory.createStartSession(sessionType, 0x00, _version); + sendFrameToTransport(header); + } // end-method + + private void sendStartProtocolSessionACK(SessionType sessionType, byte sessionID) { + ProtocolFrameHeader header = ProtocolFrameHeaderFactory.createStartSessionACK(sessionType, sessionID, 0x00, _version); + sendFrameToTransport(header); + } // end-method + + public void EndProtocolSession(SessionType sessionType, byte sessionID) { + ProtocolFrameHeader header = ProtocolFrameHeaderFactory.createEndSession(sessionType, sessionID, 0x00, _version); + sendFrameToTransport(header); + } // end-method + + public void SendMessage(ProtocolMessage protocolMsg) { + protocolMsg.setRPCType((byte) 0x00); //always sending a request + SessionType sessionType = protocolMsg.getSessionType(); + byte sessionID = protocolMsg.getSessionID(); + + byte[] data = null; + if (_version == 2) { + if (protocolMsg.getBulkData() != null) { + data = new byte[12 + protocolMsg.getJsonSize() + protocolMsg.getBulkData().length]; + sessionType = SessionType.Bulk_Data; + } else data = new byte[12 + protocolMsg.getJsonSize()]; + BinaryFrameHeader binFrameHeader = new BinaryFrameHeader(); + binFrameHeader = ProtocolFrameHeaderFactory.createBinaryFrameHeader(protocolMsg.getRPCType(), protocolMsg.getFunctionID(), protocolMsg.getCorrID(), protocolMsg.getJsonSize()); + System.arraycopy(binFrameHeader.assembleHeaderBytes(), 0, data, 0, 12); + System.arraycopy(protocolMsg.getData(), 0, data, 12, protocolMsg.getJsonSize()); + if (protocolMsg.getBulkData() != null) { + System.arraycopy(protocolMsg.getBulkData(), 0, data, 12 + protocolMsg.getJsonSize(), protocolMsg.getBulkData().length); + } + } else { + data = protocolMsg.getData(); + } + + // Get the message lock for this protocol session + Object messageLock = _messageLocks.get(sessionID); + if (messageLock == null) { + handleProtocolError("Error sending protocol message to SmartDeviceLink.", + new SmartDeviceLinkException("Attempt to send protocol message prior to startSession ACK.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE)); + return; + } + + synchronized(messageLock) { + if (data.length > MAX_DATA_SIZE) { + + messageID++; + ProtocolFrameHeader firstHeader = ProtocolFrameHeaderFactory.createMultiSendDataFirst(sessionType, sessionID, messageID, _version); + + // Assemble first frame. + int frameCount = data.length / MAX_DATA_SIZE; + if (data.length % MAX_DATA_SIZE > 0) { + frameCount++; + } + byte[] firstFrameData = new byte[8]; + // First four bytes are data size. + System.arraycopy(BitConverter.intToByteArray(data.length), 0, firstFrameData, 0, 4); + // Second four bytes are frame count. + System.arraycopy(BitConverter.intToByteArray(frameCount), 0, firstFrameData, 4, 4); + + handleProtocolFrameToSend(firstHeader, firstFrameData, 0, firstFrameData.length); + + int currentOffset = 0; + byte frameSequenceNumber = 0; + + for (int i = 0; i < frameCount; i++) { + if (i < (frameCount - 1)) { + frameSequenceNumber = (byte)(i + 1); + } else { + frameSequenceNumber = ProtocolFrameHeader.FrameDataFinalConsecutiveFrame; + } // end-if + + int bytesToWrite = data.length - currentOffset; + if (bytesToWrite > MAX_DATA_SIZE) { + bytesToWrite = MAX_DATA_SIZE; + } + + ProtocolFrameHeader consecHeader = ProtocolFrameHeaderFactory.createMultiSendDataRest(sessionType, sessionID, bytesToWrite, frameSequenceNumber , messageID, _version); + handleProtocolFrameToSend(consecHeader, data, currentOffset, bytesToWrite); + currentOffset += bytesToWrite; + } + } else { + messageID++; + ProtocolFrameHeader header = ProtocolFrameHeaderFactory.createSingleSendData(sessionType, sessionID, data.length, messageID, _version); + handleProtocolFrameToSend(header, data, 0, data.length); + } + } + } + + private void sendFrameToTransport(ProtocolFrameHeader header) { + handleProtocolFrameToSend(header, null, 0, 0); + } + + public void HandleReceivedBytes(byte[] receivedBytes, int receivedBytesLength) { + int receivedBytesReadPos = 0; + + //Check for a version difference + if (_version == 1) { + //Nothing has been read into the buffer and version is 2 + if (_headerBufWritePos == 0 && (byte) (receivedBytes[0] >>> 4) == 2) { + setVersion((byte) (receivedBytes[0] >>> 4)); + //Buffer has something in it and version is 2 + } else if ((byte) (_headerBuf[0] >>> 4) == 2) { + //safe current state of the buffer and also set the new version + byte[] tempHeader = new byte[_headerBufWritePos]; + tempHeader = _headerBuf; + setVersion((byte) (_headerBuf[0] >>> 4)); + _headerBuf = tempHeader; + } + } + + // If I don't yet know the message size, grab those bytes. + if (!_haveHeader) { + // If I can't get the size, just get the bytes that are there. + int headerBytesNeeded = _headerBuf.length - _headerBufWritePos; + if (receivedBytesLength < headerBytesNeeded) { + System.arraycopy(receivedBytes, receivedBytesReadPos, + _headerBuf, _headerBufWritePos, receivedBytesLength); + _headerBufWritePos += receivedBytesLength; + return; + } else { + // If I got the size, allocate the buffer + System.arraycopy(receivedBytes, receivedBytesReadPos, + _headerBuf, _headerBufWritePos, headerBytesNeeded); + _headerBufWritePos += headerBytesNeeded; + receivedBytesReadPos += headerBytesNeeded; + _haveHeader = true; + _currentHeader = ProtocolFrameHeader.parseWiProHeader(_headerBuf); + _dataBuf = new byte[_currentHeader.getDataSize()]; + _dataBufWritePos = 0; + } + } + + int bytesLeft = receivedBytesLength - receivedBytesReadPos; + int bytesNeeded = _dataBuf.length - _dataBufWritePos; + // If I don't have enough bytes for the message, just grab what's there. + if (bytesLeft < bytesNeeded) { + System.arraycopy(receivedBytes, receivedBytesReadPos, _dataBuf, + _dataBufWritePos, bytesLeft); + _dataBufWritePos += bytesLeft; + return; + } else { + // Fill the buffer and call the handler! + System.arraycopy(receivedBytes, receivedBytesReadPos, _dataBuf, _dataBufWritePos, bytesNeeded); + receivedBytesReadPos += bytesNeeded; + + MessageFrameAssembler assembler = getFrameAssemblerForFrame(_currentHeader); + handleProtocolFrameReceived(_currentHeader, _dataBuf, assembler); + + // Reset all class member variables for next frame + _dataBuf = null; + _dataBufWritePos = 0; + _haveHeader = false; + _headerBuf = new byte[HEADER_SIZE]; + _currentHeader = null; + _headerBufWritePos = 0; + + // If there are any bytes left, recurse. + int moreBytesLeft = receivedBytesLength - receivedBytesReadPos; + if (moreBytesLeft > 0) { + byte[] moreBytes = new byte[moreBytesLeft]; + System.arraycopy(receivedBytes, receivedBytesReadPos, + moreBytes, 0, moreBytesLeft); + HandleReceivedBytes(moreBytes, moreBytesLeft); + } + } + } + + protected MessageFrameAssembler getFrameAssemblerForFrame(ProtocolFrameHeader header) { + Hashtable<Integer, MessageFrameAssembler> hashSessionID = _assemblerForSessionID.get(new Byte(header.getSessionID())); + if (hashSessionID == null) { + hashSessionID = new Hashtable<Integer, MessageFrameAssembler>(); + _assemblerForSessionID.put(new Byte(header.getSessionID()), hashSessionID); + } // end-if + + MessageFrameAssembler ret = (MessageFrameAssembler) _assemblerForMessageID.get(new Integer(header.getMessageID())); + if (ret == null) { + ret = new MessageFrameAssembler(); + _assemblerForMessageID.put(new Integer(header.getMessageID()), ret); + } // end-if + + return ret; + } // end-method + + protected class MessageFrameAssembler { + protected boolean hasFirstFrame = false; + protected boolean hasSecondFrame = false; + protected ByteArrayOutputStream accumulator = null; + protected int totalSize = 0; + protected int framesRemaining = 0; + + protected void handleFirstDataFrame(ProtocolFrameHeader header, byte[] data) { + //The message is new, so let's figure out how big it is. + hasFirstFrame = true; + totalSize = BitConverter.intFromByteArray(data, 0) - HEADER_SIZE; + framesRemaining = BitConverter.intFromByteArray(data, 4); + accumulator = new ByteArrayOutputStream(totalSize); + } + + protected void handleSecondFrame(ProtocolFrameHeader header, byte[] data) { + handleRemainingFrame(header, data); + } + + protected void handleRemainingFrame(ProtocolFrameHeader header, byte[] data) { + accumulator.write(data, 0, header.getDataSize()); + notifyIfFinished(header); + } + + protected void notifyIfFinished(ProtocolFrameHeader header) { + //if (framesRemaining == 0) { + if (header.getFrameType() == FrameType.Consecutive && header.getFrameData() == 0x0) + { + ProtocolMessage message = new ProtocolMessage(); + message.setSessionType(header.getSessionType()); + message.setSessionID(header.getSessionID()); + //If it is WiPro 2.0 it must have binary header + if (_version == 2) { + BinaryFrameHeader binFrameHeader = BinaryFrameHeader. + parseBinaryHeader(accumulator.toByteArray()); + message.setVersion(_version); + message.setRPCType(binFrameHeader.getRPCType()); + message.setFunctionID(binFrameHeader.getFunctionID()); + message.setCorrID(binFrameHeader.getCorrID()); + if (binFrameHeader.getJsonSize() > 0) message.setData(binFrameHeader.getJsonData()); + if (binFrameHeader.getBulkData() != null) message.setBulkData(binFrameHeader.getBulkData()); + } else message.setData(accumulator.toByteArray()); + + _assemblerForMessageID.remove(header.getMessageID()); + + try { + handleProtocolMessageReceived(message); + } catch (Exception excp) { + DebugTool.logError(FailurePropagating_Msg + "onProtocolMessageReceived: " + excp.toString(), excp); + } // end-catch + + hasFirstFrame = false; + hasSecondFrame = false; + accumulator = null; + } // end-if + } // end-method + + protected void handleMultiFrameMessageFrame(ProtocolFrameHeader header, byte[] data) { + if (header.getFrameType() == FrameType.First) { + handleFirstDataFrame(header, data); + } else { + handleRemainingFrame(header, data); + } + + //} + } // end-method + + protected void handleFrame(ProtocolFrameHeader header, byte[] data) { + if (header.getFrameType().equals(FrameType.Control)) { + handleControlFrame(header, data); + } else { + // Must be a form of data frame (single, first, consecutive, etc.) + if ( header.getFrameType() == FrameType.First + || header.getFrameType() == FrameType.Consecutive + ) { + handleMultiFrameMessageFrame(header, data); + } else { + handleSingleFrameMessageFrame(header, data); + } + } // end-if + } // end-method + + private void handleProtocolHeartbeat(ProtocolFrameHeader header, byte[] data) { + } // end-method + + private void handleControlFrame(ProtocolFrameHeader header, byte[] data) { + 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 + Object messageLock = _messageLocks.get(header.getSessionID()); + if (messageLock == null) { + messageLock = new Object(); + _messageLocks.put(header.getSessionID(), messageLock); + } + handleProtocolSessionStarted(header.getSessionType(), header.getSessionID(), _version, ""); + } else if (header.getFrameData() == FrameDataControlFrameType.StartSessionNACK.getValue()) { + handleProtocolError("Got StartSessionNACK for protocol sessionID=" + header.getSessionID(), null); + } else if (header.getFrameData() == FrameDataControlFrameType.EndSession.getValue()) { + handleProtocolSessionEnded(header.getSessionType(), header.getSessionID(), ""); + } + } // end-method + + private void handleSingleFrameMessageFrame(ProtocolFrameHeader header, byte[] data) { + ProtocolMessage message = new ProtocolMessage(); + if (header.getSessionType() == SessionType.RPC) { + message.setMessageType(MessageType.RPC); + } else if (header.getSessionType() == SessionType.Bulk_Data) { + message.setMessageType(MessageType.BULK); + } // end-if + message.setSessionType(header.getSessionType()); + message.setSessionID(header.getSessionID()); + + if (_version == 2) { + BinaryFrameHeader binFrameHeader = BinaryFrameHeader. + parseBinaryHeader(data); + message.setVersion(_version); + message.setRPCType(binFrameHeader.getRPCType()); + message.setFunctionID(binFrameHeader.getFunctionID()); + message.setCorrID(binFrameHeader.getCorrID()); + if (binFrameHeader.getJsonSize() > 0) message.setData(binFrameHeader.getJsonData()); + if (binFrameHeader.getBulkData() != null) message.setBulkData(binFrameHeader.getBulkData()); + } else message.setData(data); + + _assemblerForMessageID.remove(header.getMessageID()); + + try { + handleProtocolMessageReceived(message); + } catch (Exception ex) { + DebugTool.logError(FailurePropagating_Msg + "onProtocolMessageReceived: " + ex.toString(), ex); + handleProtocolError(FailurePropagating_Msg + "onProtocolMessageReceived: ", ex); + } // end-catch + } // end-method + } // end-class +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameData.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameData.java new file mode 100755 index 000000000..60714a5d0 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameData.java @@ -0,0 +1,42 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol.enums; + +import java.util.Vector; + +import com.smartdevicelink.util.ByteEnumer; + +public class FrameData extends ByteEnumer { + + private static Vector theList = new Vector(); + public static Vector getList() { return theList; } + + byte i = 0x00; + + protected FrameData(byte value, String name) {super(value, name);} + public final static FrameData StartSession = new FrameData((byte)0x01, "StartSession"); + public final static FrameData StartSessionACK = new FrameData((byte)0x02, "StartSessionACK"); + public final static FrameData StartSessionNACK = new FrameData((byte)0x03, "StartSessionNACK"); + public final static FrameData EndSession = new FrameData((byte)0x04, "EndSession"); + + public final static FrameData SingleFrame = new FrameData((byte)0x00, "SingleFrame"); + public final static FrameData FirstFrame = new FrameData((byte)0x00, "FirstFrame"); + public final static FrameData ConsecutiveFrame = new FrameData((byte)0x00, "ConsecutiveFrame"); + public final static byte LastFrame = (byte)0x00; + + static { + theList.addElement(StartSession); + theList.addElement(StartSessionACK); + theList.addElement(StartSessionNACK); + theList.addElement(EndSession); + } + + public static FrameData valueOf(String passedButton) { + return (FrameData) get(theList, passedButton); + } + + public static FrameData[] values() { + return (FrameData[]) theList.toArray(); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameDataControlFrameType.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameDataControlFrameType.java new file mode 100755 index 000000000..efae9a701 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameDataControlFrameType.java @@ -0,0 +1,36 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol.enums; + +import java.util.Vector; + +import com.smartdevicelink.util.ByteEnumer; + +public class FrameDataControlFrameType extends ByteEnumer { + private static Vector theList = new Vector(); + public static Vector getList() { return theList; } + + private byte _i = 0x00; + + protected FrameDataControlFrameType(byte value, String name) {super(value, name);} + public final static FrameDataControlFrameType StartSession = new FrameDataControlFrameType((byte)0x01, "StartSession"); + public final static FrameDataControlFrameType StartSessionACK = new FrameDataControlFrameType((byte)0x02, "StartSessionACK"); + public final static FrameDataControlFrameType StartSessionNACK = new FrameDataControlFrameType((byte)0x03, "StartSessionNACK"); + public final static FrameDataControlFrameType EndSession = new FrameDataControlFrameType((byte)0x04, "EndSession"); + + static { + theList.addElement(StartSession); + theList.addElement(StartSessionACK); + theList.addElement(StartSessionNACK); + theList.addElement(EndSession); + } + + public static FrameDataControlFrameType valueOf(String passedButton) { + return (FrameDataControlFrameType) get(theList, passedButton); + } // end-method + + public static FrameDataControlFrameType[] values() { + return (FrameDataControlFrameType[]) theList.toArray(); + } // end-method +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameType.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameType.java new file mode 100755 index 000000000..984dca112 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FrameType.java @@ -0,0 +1,37 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol.enums; + +import java.util.Vector; + +import com.smartdevicelink.util.ByteEnumer; + +public class FrameType extends ByteEnumer { + + private static Vector theList = new Vector(); + public static Vector getList() { return theList; } + + byte i = 0x00; + + protected FrameType(byte value, String name) {super(value, name);} + public final static FrameType Control = new FrameType((byte)0x00, "Control"); + public final static FrameType Single = new FrameType((byte)0x01, "Single"); + public final static FrameType First = new FrameType((byte)0x02, "First"); + public final static FrameType Consecutive = new FrameType((byte)0x03, "Consecutive"); + + static { + theList.addElement(Control); + theList.addElement(Single); + theList.addElement(First); + theList.addElement(Consecutive); + } + + public static FrameType valueOf(byte passed) { + return (FrameType) get(theList, passed); + } + + public static FrameType[] values() { + return (FrameType[]) theList.toArray(); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FunctionID.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FunctionID.java new file mode 100755 index 000000000..f602f7e0f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/FunctionID.java @@ -0,0 +1,86 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol.enums; + +import java.util.ArrayList; +import java.util.Arrays; + +import com.smartdevicelink.proxy.constants.Names; + +public class FunctionID { + static ArrayList<String> functionID = null; + + public FunctionID() { + } + + static public String getFunctionName(int i) { + if (functionID == null) { + initFunctionIds(); + } + return functionID.get(i); + } + + static public void initFunctionIds() { + String [] functionIds = new String[60]; + functionIds[1] = Names.RegisterAppInterface; + functionIds[2] = Names.UnregisterAppInterface; + functionIds[3] = Names.SetGlobalProperties; + functionIds[4] = Names.ResetGlobalProperties; + functionIds[5] = Names.AddCommand; + functionIds[6] = Names.DeleteCommand; + functionIds[7] = Names.AddSubMenu; + functionIds[8] = Names.DeleteSubMenu; + functionIds[9] = Names.CreateInteractionChoiceSet; + functionIds[10] = Names.PerformInteraction; + functionIds[11] = Names.DeleteInteractionChoiceSet; + functionIds[12] = Names.Alert; + functionIds[13] = Names.Show; + functionIds[14] = Names.Speak; + functionIds[15] = Names.SetMediaClockTimer; + functionIds[16] = Names.EncodedSyncPData; + functionIds[17] = Names.DialNumber; + functionIds[18] = Names.PerformAudioPassThru; + functionIds[19] = Names.EndAudioPassThru; + functionIds[20] = Names.SubscribeButton; + functionIds[21] = Names.UnsubscribeButton; + functionIds[22] = Names.SubscribeVehicleData; + functionIds[23] = Names.UnsubscribeVehicleData; + functionIds[24] = Names.GetVehicleData; + functionIds[25] = Names.ReadDID; + functionIds[26] = Names.GetDTCs; + functionIds[27] = Names.ScrollableMessage; + functionIds[28] = Names.Slider; + functionIds[29] = Names.ShowConstantTBT; + functionIds[30] = Names.AlertManeuver; + functionIds[31] = Names.UpdateTurnList; + functionIds[32] = Names.ChangeRegistration; + functionIds[33] = Names.GenericResponse; + functionIds[34] = Names.PutFile; + functionIds[35] = Names.DeleteFile; + functionIds[36] = Names.ListFiles; + functionIds[37] = Names.SetAppIcon; + functionIds[38] = Names.SetDisplayLayout; + functionIds[39] = Names.OnHMIStatus; + functionIds[40] = Names.OnAppInterfaceUnregistered; + functionIds[41] = Names.OnButtonEvent; + functionIds[42] = Names.OnButtonPress; + functionIds[43] = Names.OnVehicleData; + functionIds[44] = Names.OnCommand; + functionIds[45] = Names.OnEncodedSyncPData; + functionIds[46] = Names.OnTBTClientState; + functionIds[47] = Names.OnDriverDistraction; + functionIds[48] = Names.OnPermissionsChange; + functionIds[49] = Names.OnAudioPassThru; + functionIds[50] = Names.OnLanguageChange; + + functionID = new ArrayList<String>(Arrays.asList(functionIds)); + } + + static public int getFunctionID(String functionName) { + if (functionID == null) { + initFunctionIds(); + } + return functionID.indexOf(functionName); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/MessageType.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/MessageType.java new file mode 100755 index 000000000..9f6aa88dd --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/MessageType.java @@ -0,0 +1,10 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol.enums; + +public enum MessageType { + UNDEFINED, + BULK, + RPC +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/SessionType.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/SessionType.java new file mode 100755 index 000000000..34defe5f3 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/protocol/enums/SessionType.java @@ -0,0 +1,34 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.protocol.enums; + +import java.util.Vector; + +import com.smartdevicelink.util.ByteEnumer; + + +public class SessionType extends ByteEnumer { + + private static Vector theList = new Vector(); + public static Vector getList() { return theList; } + + byte i = 0x00; + + protected SessionType(byte value, String name) {super(value, name);} + public final static SessionType RPC = new SessionType((byte)0x07, "RPC"); + public final static SessionType Bulk_Data = new SessionType((byte)0xF, "Bulk_Data"); + + static { + theList.addElement(RPC); + theList.addElement(Bulk_Data); + } + + public static SessionType valueOf(byte passedButton) { + return (SessionType) get(theList, passedButton); + } + + public static SessionType[] values() { + return (SessionType[]) theList.toArray(); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/IProxyListener.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/IProxyListener.java new file mode 100755 index 000000000..59180cceb --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/IProxyListener.java @@ -0,0 +1,22 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import com.smartdevicelink.proxy.interfaces.IProxyListenerBase; +import com.smartdevicelink.proxy.rpc.OnAppInterfaceUnregistered; +import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse; +import com.smartdevicelink.proxy.rpc.UnregisterAppInterfaceResponse; + +public interface IProxyListener extends IProxyListenerBase{ + // Adds Legacy Life-cycle Management call-backs to the IProxyListenerAbstract interface + + public void onProxyOpened(); + + public void onRegisterAppInterfaceResponse(RegisterAppInterfaceResponse response); + + public void onOnAppInterfaceUnregistered(OnAppInterfaceUnregistered notification); + + public void onUnregisterAppInterfaceResponse(UnregisterAppInterfaceResponse response); + +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCMessage.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCMessage.java new file mode 100755 index 000000000..dae9dfb11 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCMessage.java @@ -0,0 +1,71 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Hashtable; + +import com.smartdevicelink.protocol.ProtocolMessage; +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.proxy.constants.Names; + +public class RPCMessage extends RPCStruct { + + public RPCMessage(String functionName) { + this(functionName, "request"); + } + + protected RPCMessage(RPCMessage rpcm) { + this(rpcm.store); + } + + protected RPCMessage(RPCStruct rpcs) { + this("", ""); + this.parameters = rpcs.store; + } + + public RPCMessage(String functionName, String messageType) { + function = new Hashtable(); + this.messageType = messageType; + store.put(messageType, function); + parameters = new Hashtable(); + function.put(Names.parameters, parameters); + function.put(Names.function_name, functionName); + } + + public RPCMessage(Hashtable hash) { + store = hash; + messageType = (String)hash.keys().nextElement(); + + function = (Hashtable)hash.get(messageType); + parameters = (Hashtable)function.get(Names.parameters); + } + + protected String messageType; + protected Hashtable parameters; + protected Hashtable function; + + public String getFunctionName() { + return (String)function.get(Names.function_name); + } + + protected void setFunctionName(String functionName) { + function.put(Names.function_name, functionName); + } + + public String getMessageType() { + return messageType; + } + + public void setParameters(String functionName, Object value) { + if (value != null) { + parameters.put(functionName, value); + } else { + parameters.remove(functionName); + } + } + + public Object getParameters(String functionName) { + return parameters.get(functionName); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCNotification.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCNotification.java new file mode 100755 index 000000000..6380ba0e2 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCNotification.java @@ -0,0 +1,21 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Hashtable; + +public class RPCNotification extends RPCMessage { + + public RPCNotification(String functionName) { + super(functionName, "notification"); + } + + public RPCNotification(Hashtable hash) { + super(hash); + } + + public RPCNotification(RPCMessage rpcMsg) { + super(rpcMsg); + } +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCRequest.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCRequest.java new file mode 100755 index 000000000..803672c77 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCRequest.java @@ -0,0 +1,32 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.constants.Names; + +public class RPCRequest extends RPCMessage { + + public RPCRequest(String functionName) { + super(functionName, "request"); + messageType = Names.request; + } + + public RPCRequest(Hashtable hash) { + super(hash); + } + + public Integer getCorrelationID() { + return (Integer)function.get(Names.correlationID); + } + + public void setCorrelationID(Integer correlationID) { + if (correlationID != null) { + function.put(Names.correlationID, correlationID ); + } else if (parameters.contains(Names.correlationID)) { + function.remove(Names.correlationID); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCRequestFactory.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCRequestFactory.java new file mode 100755 index 000000000..529345f4b --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCRequestFactory.java @@ -0,0 +1,431 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Vector; + +import com.smartdevicelink.proxy.rpc.*; +import com.smartdevicelink.proxy.rpc.enums.*; + +public class RPCRequestFactory { + + public static final int NGN_MEDIA_SCREEN_APP_NAME_MAX_LENGTH = 5; + public static final int SMARTDEVICELINK_MSG_MAJOR_VERSION = 1; + public static final int SMARTDEVICELINK_MSG_MINOR_VERSION = 0; + + public static EncodedSyncPData buildEncodedSyncPData( + Vector<String> data, Integer correlationID) { + + if(data == null) return null; + + EncodedSyncPData msg = new EncodedSyncPData(); + msg.setCorrelationID(correlationID); + msg.setData(data); + return msg; + } + + public static AddCommand buildAddCommand(Integer commandID, + String menuText, Integer parentID, Integer position, + Vector<String> vrCommands, Integer correlationID) { + AddCommand msg = new AddCommand(); + msg.setCorrelationID(correlationID); + msg.setCmdID(commandID); + msg.setVrCommands(vrCommands); + + if(menuText != null || parentID != null || position != null) { + MenuParams menuParams = new MenuParams(); + menuParams.setMenuName(menuText); + menuParams.setPosition(position); + menuParams.setParentID(parentID); + msg.setMenuParams(menuParams); + } + + return msg; + } + + public static AddCommand buildAddCommand(Integer commandID, + String menuText, Vector<String> vrCommands, Integer correlationID) { + AddCommand msg = buildAddCommand(commandID, menuText, null, null, + vrCommands, correlationID); + return msg; + } + + public static AddCommand buildAddCommand(Integer commandID, + Vector<String> vrCommands, Integer correlationID) { + AddCommand msg = new AddCommand(); + msg.setCorrelationID(correlationID); + msg.setCmdID(commandID); + msg.setVrCommands(vrCommands); + + return msg; + } + + public static AddSubMenu buildAddSubMenu(Integer menuID, String menuName, + Integer correlationID) { + AddSubMenu msg = buildAddSubMenu(menuID, menuName, null, correlationID); + return msg; + } + + public static AddSubMenu buildAddSubMenu(Integer menuID, String menuName, + Integer position, Integer correlationID) { + AddSubMenu msg = new AddSubMenu(); + msg.setCorrelationID(correlationID); + msg.setMenuName(menuName); + msg.setMenuID(menuID); + msg.setPosition(position); + + return msg; + } + + public static Alert buildAlert(String ttsText, Boolean playTone, + Integer correlationID) { + Vector<TTSChunk> chunks = TTSChunkFactory + .createSimpleTTSChunks(ttsText); + Alert msg = buildAlert(chunks, null, null, playTone, null, + correlationID); + return msg; + } + + public static Alert buildAlert(String alertText1, String alertText2, + Integer duration, Integer correlationID) { + Alert msg = buildAlert((Vector<TTSChunk>) null, alertText1, alertText2, + null, duration, correlationID); + return msg; + } + + public static Alert buildAlert(String ttsText, String alertText1, + String alertText2, Boolean playTone, Integer duration, + Integer correlationID) { + Vector<TTSChunk> chunks = TTSChunkFactory + .createSimpleTTSChunks(ttsText); + Alert msg = buildAlert(chunks, alertText1, alertText2, playTone, + duration, correlationID); + return msg; + } + + public static Alert buildAlert(Vector<TTSChunk> chunks, Boolean playTone, + Integer correlationID) { + Alert msg = buildAlert(chunks, null, null, playTone, null, + correlationID); + return msg; + } + + public static Alert buildAlert(Vector<TTSChunk> ttsChunks, + String alertText1, String alertText2, Boolean playTone, + Integer duration, Integer correlationID) { + Alert msg = new Alert(); + msg.setCorrelationID(correlationID); + msg.setAlertText1(alertText1); + msg.setAlertText2(alertText2); + msg.setDuration(duration); + msg.setPlayTone(playTone); + msg.setTtsChunks(ttsChunks); + + return msg; + } + + public static CreateInteractionChoiceSet buildCreateInteractionChoiceSet( + Vector<Choice> choiceSet, Integer interactionChoiceSetID, + Integer correlationID) { + CreateInteractionChoiceSet msg = new CreateInteractionChoiceSet(); + msg.setChoiceSet(choiceSet); + msg.setInteractionChoiceSetID(interactionChoiceSetID); + msg.setCorrelationID(correlationID); + return msg; + } + + public static DeleteCommand buildDeleteCommand(Integer commandID, + Integer correlationID) { + DeleteCommand msg = new DeleteCommand(); + msg.setCmdID(commandID); + msg.setCorrelationID(correlationID); + return msg; + } + + public static DeleteInteractionChoiceSet buildDeleteInteractionChoiceSet( + Integer interactionChoiceSetID, Integer correlationID) { + DeleteInteractionChoiceSet msg = new DeleteInteractionChoiceSet(); + msg.setInteractionChoiceSetID(interactionChoiceSetID); + msg.setCorrelationID(correlationID); + + return msg; + } + + public static DeleteSubMenu buildDeleteSubMenu(Integer menuID, + Integer correlationID) { + DeleteSubMenu msg = new DeleteSubMenu(); + msg.setCorrelationID(correlationID); + msg.setMenuID(menuID); + + return msg; + } + + public static PerformInteraction buildPerformInteraction( + Vector<TTSChunk> initChunks, String displayText, + Vector<Integer> interactionChoiceSetIDList, + Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, + InteractionMode interactionMode, Integer timeout, + Integer correlationID) { + PerformInteraction msg = new PerformInteraction(); + msg.setInitialPrompt(initChunks); + msg.setInitialText(displayText); + msg.setInteractionChoiceSetIDList(interactionChoiceSetIDList); + msg.setInteractionMode(interactionMode); + msg.setTimeout(timeout); + msg.setHelpPrompt(helpChunks); + msg.setTimeoutPrompt(timeoutChunks); + msg.setCorrelationID(correlationID); + + return msg; + } + + public static PerformInteraction buildPerformInteraction( + String initPrompt, String displayText, + Vector<Integer> interactionChoiceSetIDList, + String helpPrompt, String timeoutPrompt, + InteractionMode interactionMode, Integer timeout, + Integer correlationID) { + Vector<TTSChunk> initChunks = TTSChunkFactory + .createSimpleTTSChunks(initPrompt); + Vector<TTSChunk> helpChunks = TTSChunkFactory + .createSimpleTTSChunks(helpPrompt); + Vector<TTSChunk> timeoutChunks = TTSChunkFactory + .createSimpleTTSChunks(timeoutPrompt); + return buildPerformInteraction(initChunks, + displayText, interactionChoiceSetIDList, helpChunks, + timeoutChunks, interactionMode, timeout, correlationID); + } + + public static PerformInteraction buildPerformInteraction( + String initPrompt, String displayText, + Integer interactionChoiceSetID, + String helpPrompt, String timeoutPrompt, + InteractionMode interactionMode, Integer timeout, + Integer correlationID) { + Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>(); + interactionChoiceSetIDs.add(interactionChoiceSetID); + + return buildPerformInteraction( + initPrompt, displayText, interactionChoiceSetIDs, + helpPrompt, timeoutPrompt, interactionMode, + timeout, correlationID); + } + + public static PerformInteraction buildPerformInteraction(String initPrompt, + String displayText, Integer interactionChoiceSetID, + Integer correlationID) { + + return buildPerformInteraction(initPrompt, displayText, + interactionChoiceSetID, null, null, + InteractionMode.BOTH, null, correlationID); + } + + @Deprecated + public static PerformInteraction buildPerformInteraction( + Vector<TTSChunk> initChunks, String displayText, + Vector<Integer> interactionChoiceSetIDList, + Vector<TTSChunk> helpChunks, InteractionMode interactionMode, + Integer timeout, Integer correlationID) { + PerformInteraction msg = new PerformInteraction(); + msg.setInitialPrompt(initChunks); + msg.setInitialText(displayText); + msg.setInteractionChoiceSetIDList(interactionChoiceSetIDList); + msg.setInteractionMode(interactionMode); + msg.setTimeout(timeout); + msg.setHelpPrompt(helpChunks); + msg.setCorrelationID(correlationID); + return msg; + } + + @Deprecated + public static PerformInteraction buildPerformInteraction(String initPrompt, + String displayText, Vector<Integer> interactionChoiceSetIDList, + String helpPrompt, InteractionMode interactionMode, + Integer timeout, Integer correlationID) { + Vector<TTSChunk> initChunks = TTSChunkFactory + .createSimpleTTSChunks(initPrompt); + Vector<TTSChunk> helpChunks = TTSChunkFactory + .createSimpleTTSChunks(helpPrompt); + PerformInteraction msg = buildPerformInteraction(initChunks, + displayText, interactionChoiceSetIDList, helpChunks, + interactionMode, timeout, correlationID); + return msg; + } + + public static RegisterAppInterface buildRegisterAppInterface(String appName) { + return buildRegisterAppInterface(appName, false, ""); + } + + public static RegisterAppInterface buildRegisterAppInterface( + String appName, Boolean isMediaApp, String autoActivateID) { + + return buildRegisterAppInterface(null, appName, null, null, isMediaApp, + null, autoActivateID, null); + } + + public static RegisterAppInterface buildRegisterAppInterface( + SyncMsgVersion SyncMsgVersion, String appName, String ngnMediaScreenAppName, + Vector<String> vrSynonyms, Boolean isMediaApp, Language languageDesired, + String autoActivateID, Integer correlationID) { + RegisterAppInterface msg = new RegisterAppInterface(); + + if (correlationID == null) { + correlationID = 1; + } + msg.setCorrelationID(correlationID); + + if (SyncMsgVersion == null) { + SyncMsgVersion = new SyncMsgVersion(); + SyncMsgVersion.setMajorVersion(new Integer(SMARTDEVICELINK_MSG_MAJOR_VERSION)); + SyncMsgVersion.setMinorVersion(new Integer(SMARTDEVICELINK_MSG_MINOR_VERSION)); + } + msg.setSyncMsgVersion(SyncMsgVersion); + + msg.setAppName(appName); + + msg.setAutoActivateID(autoActivateID); + + if (ngnMediaScreenAppName == null) { + ngnMediaScreenAppName = appName; + } + + if (ngnMediaScreenAppName.length() > NGN_MEDIA_SCREEN_APP_NAME_MAX_LENGTH) { + ngnMediaScreenAppName = ngnMediaScreenAppName.substring(0, + NGN_MEDIA_SCREEN_APP_NAME_MAX_LENGTH); + } + msg.setNgnMediaScreenAppName(ngnMediaScreenAppName); + + if (vrSynonyms == null) { + vrSynonyms = new Vector<String>(); + vrSynonyms.add(appName); + } + msg.setVrSynonyms(vrSynonyms); + + msg.setIsMediaApplication(isMediaApp); + + if (languageDesired == null) { + languageDesired = Language.EN_US; + } + msg.setLanguageDesired(languageDesired); + + return msg; + } + + public static SetGlobalProperties buildSetGlobalProperties( + String helpPrompt, String timeoutPrompt, Integer correlationID) { + return buildSetGlobalProperties(TTSChunkFactory + .createSimpleTTSChunks(helpPrompt), TTSChunkFactory + .createSimpleTTSChunks(timeoutPrompt), correlationID); + } + + public static SetGlobalProperties buildSetGlobalProperties( + Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, + Integer correlationID) { + SetGlobalProperties req = new SetGlobalProperties(); + req.setCorrelationID(correlationID); + + req.setHelpPrompt(helpChunks); + req.setTimeoutPrompt(timeoutChunks); + + return req; + } + + public static SetMediaClockTimer buildSetMediaClockTimer(Integer hours, + Integer minutes, Integer seconds, UpdateMode updateMode, + Integer correlationID) { + + SetMediaClockTimer msg = new SetMediaClockTimer(); + if (hours != null || minutes != null || seconds != null) { + StartTime startTime = new StartTime(); + msg.setStartTime(startTime); + startTime.setHours(hours); + startTime.setMinutes(minutes); + startTime.setSeconds(seconds); + } + + msg.setUpdateMode(updateMode); + msg.setCorrelationID(correlationID); + + return msg; + } + + @Deprecated + public static SetMediaClockTimer buildSetMediaClockTimer( + UpdateMode updateMode, Integer correlationID) { + Integer hours = null; + Integer minutes = null; + Integer seconds = null; + + SetMediaClockTimer msg = buildSetMediaClockTimer(hours, minutes, + seconds, updateMode, correlationID); + return msg; + } + + public static Show buildShow(String mainText1, String mainText2, + String statusBar, String mediaClock, String mediaTrack, + TextAlignment alignment, Integer correlationID) { + Show msg = new Show(); + msg.setCorrelationID(correlationID); + msg.setMainField1(mainText1); + msg.setMainField2(mainText2); + msg.setStatusBar(statusBar); + msg.setMediaClock(mediaClock); + msg.setMediaTrack(mediaTrack); + msg.setAlignment(alignment); + + return msg; + } + + public static Show buildShow(String mainText1, String mainText2, + TextAlignment alignment, Integer correlationID) { + Show msg = buildShow(mainText1, mainText2, null, null, null, alignment, + correlationID); + return msg; + } + + public static Speak buildSpeak(String ttsText, Integer correlationID) { + Speak msg = buildSpeak(TTSChunkFactory.createSimpleTTSChunks(ttsText), + correlationID); + return msg; + } + + public static Speak buildSpeak(Vector<TTSChunk> ttsChunks, + Integer correlationID) { + + Speak msg = new Speak(); + msg.setCorrelationID(correlationID); + + msg.setTtsChunks(ttsChunks); + + return msg; + } + + public static SubscribeButton buildSubscribeButton(ButtonName buttonName, + Integer correlationID) { + + SubscribeButton msg = new SubscribeButton(); + msg.setCorrelationID(correlationID); + msg.setButtonName(buttonName); + + return msg; + } + + public static UnregisterAppInterface buildUnregisterAppInterface( + Integer correlationID) { + UnregisterAppInterface msg = new UnregisterAppInterface(); + msg.setCorrelationID(correlationID); + + return msg; + } + + public static UnsubscribeButton buildUnsubscribeButton( + ButtonName buttonName, Integer correlationID) { + + UnsubscribeButton msg = new UnsubscribeButton(); + msg.setCorrelationID(correlationID); + msg.setButtonName(buttonName); + + return msg; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCResponse.java new file mode 100755 index 000000000..be3f6fd2f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCResponse.java @@ -0,0 +1,79 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.Result; +import com.smartdevicelink.util.DebugTool; + +public class RPCResponse extends RPCMessage { + + public RPCResponse(String functionName) { + super(functionName, "response"); + } + + public RPCResponse(Hashtable hash) { + super(hash); + } + + public RPCResponse(RPCMessage rpcMsg) { + super(rpcMsg); + } + + public Integer getCorrelationID() { + return (Integer)function.get(Names.correlationID); + } + + public void setCorrelationID(Integer correlationID) { + if (correlationID != null) { + function.put(Names.correlationID, correlationID ); + } else if (parameters.contains(Names.correlationID)){ + function.remove(Names.correlationID); + } + } + + public Boolean getSuccess() { + return (Boolean) parameters.get( Names.success ); + } + + public void setSuccess( Boolean success ) { + if (success != null) { + parameters.put(Names.success, success ); + } + } + + public Result getResultCode() { + Object obj = parameters.get(Names.resultCode); + if (obj instanceof Result) { + return (Result) obj; + } else if (obj instanceof String) { + Result theCode = null; + try { + theCode = Result.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.resultCode, e); + } + return theCode; + } + return null; + } + + public void setResultCode( Result resultCode ) { + if (resultCode != null) { + parameters.put(Names.resultCode, resultCode ); + } + } + + public String getInfo() { + return (String) parameters.get( Names.info ); + } + + public void setInfo( String info ) { + if (info != null) { + parameters.put(Names.info, info ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCStruct.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCStruct.java new file mode 100755 index 000000000..a91522e4e --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/RPCStruct.java @@ -0,0 +1,54 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Hashtable; + +import org.json.JSONException; +import org.json.JSONObject; + +import com.smartdevicelink.marshal.JsonRPCMarshaller; +import com.smartdevicelink.proxy.constants.Names; + +public class RPCStruct { + + protected Hashtable<String, Object> store = null; + + public RPCStruct() { + store = new Hashtable<String, Object>(); + } + + protected RPCStruct(RPCStruct rpcs) { + this.store = rpcs.store; + } + + public RPCStruct(Hashtable<String, Object> hashtable) { + store = hashtable; + } + + public void deserializeJSON(JSONObject jsonObject) throws JSONException { + store = JsonRPCMarshaller.deserializeJSONObject(jsonObject); + } + + // deserializeJSONObject method moved to JsonRPCMarshaller for consistency + // Keep reference here for backwards compatibility + @Deprecated + public static Hashtable<String, Object> deserializeJSONObject(JSONObject jsonObject) + throws JSONException { + return JsonRPCMarshaller.deserializeJSONObject(jsonObject); + } + + public JSONObject serializeJSON() throws JSONException { + return JsonRPCMarshaller.serializeHashtable(store); + } + + public JSONObject serializeJSON(byte version) throws JSONException { + if (version == 2) { + String messageType = (String)store.keys().nextElement(); + Hashtable function = (Hashtable)store.get(messageType); + Hashtable hash = (Hashtable)function.get(Names.parameters); + return JsonRPCMarshaller.serializeHashtable(hash); + } else return JsonRPCMarshaller.serializeHashtable(store); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxy.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxy.java new file mode 100755 index 000000000..99c92467f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxy.java @@ -0,0 +1,215 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Vector; + +import com.smartdevicelink.exception.SmartDeviceLinkException; +import com.smartdevicelink.exception.SmartDeviceLinkExceptionCause; +import com.smartdevicelink.proxy.rpc.SyncMsgVersion; +import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.trace.SyncTrace; + +public class SmartDeviceLinkProxy extends SmartDeviceLinkProxyBase<IProxyListener> { + + private static final String SMARTDEVICELINK_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + private static final String SMARTDEVICELINK_LIB_PRIVATE_TOKEN = "{DAE1A88C-6C16-4768-ACA5-6F1247EA01C2}"; + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink. + * + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @throws SmartDeviceLinkException + */ + public SmartDeviceLinkProxy(IProxyListener listener) throws SmartDeviceLinkException { + super( listener, + /*application context*/null, + /*enable advanced lifecycle management*/false, + /*app name*/ null, + /*ngn media screen app name*/null, + /*vr synonyms*/null, + /*is media app*/ null, + /*SyncMsgVersion*/null, + /*language desired*/null, + /*autoActivateID*/null, + /*callbackToUIThread*/ true); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxy instance passing in: IProxyListener.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink. + * + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @param applicationContext - Context of the application. Used to access application specific resources. + * @throws SmartDeviceLinkException + */ + public SmartDeviceLinkProxy(IProxyListener listener, SmartDeviceLinkProxyConfigurationResources SmartDeviceLinkProxyConfigurationResources) + throws SmartDeviceLinkException { + super( listener, + SmartDeviceLinkProxyConfigurationResources, + /*enable advanced lifecycle management*/false, + /*app name*/ null, + /*ngn media screen app name*/null, + /*vr synonyms*/null, + /*is media app*/ null, + /*SyncMsgVersion*/null, + /*language desired*/null, + /*autoActivateID*/null, + /*callbackToUIThread*/ true); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxy instance passing in: IProxyListener, SmartDeviceLinkProxyConfigurationResources.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink. + * + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @param callbackToUIThread - If true, all callbacks will occur on the UI thread. + * @throws SmartDeviceLinkException + */ + public SmartDeviceLinkProxy(IProxyListener listener, boolean callbackToUIThread) throws SmartDeviceLinkException { + super( listener, + /*SmartDeviceLink proxy configuration resources*/null, + /*enable advanced lifecycle management*/false, + /*app name*/ null, + /*ngn media screen app name*/null, + /*vr synonyms*/null, + /*is media app*/ null, + /*SyncMsgVersion*/null, + /*language desired*/null, + /*autoActivateID*/null, + callbackToUIThread); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxy instance passing in: IProxyListener, callBackToUIThread.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink. + * + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @param applicationContext - Context of the application. Used to access application specific resources. + * @param callbackToUIThread - If true, all callbacks will occur on the UI thread. + * @throws SmartDeviceLinkException + */ + public SmartDeviceLinkProxy(IProxyListener listener, SmartDeviceLinkProxyConfigurationResources SmartDeviceLinkProxyConfigurationResources, + boolean callbackToUIThread) throws SmartDeviceLinkException { + super( listener, + SmartDeviceLinkProxyConfigurationResources, + /*enable advanced lifecycle management*/false, + /*app name*/ null, + /*ngn media screen app name*/null, + /*vr synonyms*/null, + /*is media app*/ null, + /*SyncMsgVersion*/null, + /*language desired*/null, + /*autoActivateID*/null, + callbackToUIThread); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxy instance passing in: IProxyListener, callBackToUIThread.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + + + + /******************** Public Helper Methods *************************/ + + + /** + * Sends a RegisterAppInterface RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param SyncMsgVersion + * @param appName + * @param ngnMediaScreenAppName + * @param vrSynonyms + * @param isMediaApp + * @param languageDesired + * @param autoActivateID + * @param correlationID + * + * @throws SmartDeviceLinkException + */ + public void registerAppInterface( + SyncMsgVersion SyncMsgVersion, String appName, String ngnMediaScreenAppName, + Vector<String> vrSynonyms, Boolean isMediaApp, Language languageDesired, + String autoActivateID, Integer correlationID) + throws SmartDeviceLinkException { + + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This SmartDeviceLinkProxy object has been disposed, it is no long capable of sending requests.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + registerAppInterfacePrivate( + SyncMsgVersion, + appName, + ngnMediaScreenAppName, + vrSynonyms, + isMediaApp, + languageDesired, + autoActivateID, + correlationID); + } + + /** + * Sends a RegisterAppInterface RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param appName + * @param isMediaApp + * @param autoActivateID + * @throws SmartDeviceLinkException + */ + public void registerAppInterface( + String appName, Boolean isMediaApp, String autoActivateID, Integer correlationID) + throws SmartDeviceLinkException { + + registerAppInterface( + /*SyncMsgVersion*/null, + appName, + /*ngnMediaScreenAppName*/null, + /*vrSynonyms*/null, + isMediaApp, + /*languageDesired*/null, + autoActivateID, + correlationID); + } + + /** + * Sends a RegisterAppInterface RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param appName + * @throws SmartDeviceLinkException + */ + public void registerAppInterface(String appName, Integer correlationID) + throws SmartDeviceLinkException { + + registerAppInterface(appName, false, "", correlationID); + } + + /** + * Sends an UnregisterAppInterface RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void unregisterAppInterface(Integer correlationID) + throws SmartDeviceLinkException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This SmartDeviceLinkProxy object has been disposed, it is no long capable of executing methods.", + SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + unregisterAppInterfacePrivate(correlationID); + } + + /** + * Returns is isConnected state of the SmartDeviceLink transport. + * + * @return Boolean isConnected + */ + public Boolean getIsConnected() { + return super.getIsConnected(); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyALM.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyALM.java new file mode 100755 index 000000000..38b348262 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyALM.java @@ -0,0 +1,385 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Vector; + +import com.smartdevicelink.exception.SmartDeviceLinkException; +import com.smartdevicelink.exception.SmartDeviceLinkExceptionCause; +import com.smartdevicelink.proxy.interfaces.IProxyListenerALM; +import com.smartdevicelink.proxy.rpc.ButtonCapabilities; +import com.smartdevicelink.proxy.rpc.DisplayCapabilities; +import com.smartdevicelink.proxy.rpc.SyncMsgVersion; +import com.smartdevicelink.proxy.rpc.enums.HmiZoneCapabilities; +import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities; +import com.smartdevicelink.proxy.rpc.enums.SmartDeviceLinkDisconnectedReason; +import com.smartdevicelink.proxy.rpc.enums.VrCapabilities; +import com.smartdevicelink.trace.SyncTrace; +import com.smartdevicelink.transport.BaseTransportConfig; + +public class SmartDeviceLinkProxyALM extends SmartDeviceLinkProxyBase<IProxyListenerALM> { + + private static final String SMARTDEVICELINK_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + private static final String SMARTDEVICELINK_LIB_PRIVATE_TOKEN = "{DAE1A88C-6C16-4768-ACA5-6F1247EA01C2}"; + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink + * + * Takes advantage of the advanced lifecycle management. + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @param appName - Name of the application displayed on SmartDeviceLink. + * @param isMediaApp - Indicates if the app is a media application. + */ + public SmartDeviceLinkProxyALM(IProxyListenerALM listener, String appName, Boolean isMediaApp) throws SmartDeviceLinkException { + super( listener, + /*SmartDeviceLink proxy configuration resources*/null, + /*enable advanced lifecycle management*/true, + appName, + /*ngn media app*/null, + /*vr synonyms*/null, + /*is media app*/isMediaApp, + /*SyncMsgVersion*/null, + /*language desired*/null, + /*autoActivateID*/null, + /*callbackToUIThread*/ false); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxyALM instance passing in: IProxyListener, appName, and isMediaApp.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + public SmartDeviceLinkProxyALM(IProxyListenerALM listener, String appName, Boolean isMediaApp, + BaseTransportConfig transportConfig) throws SmartDeviceLinkException { + super( listener, + /*SmartDeviceLink proxy configuration resources*/null, + /*enable advanced lifecycle management*/true, + appName, + /*ngn media app*/null, + /*vr synonyms*/null, + /*is media app*/isMediaApp, + /*SyncMsgVersion*/null, + /*language desired*/null, + /*autoActivateID*/null, + /*callbackToUIThread*/ false, + transportConfig); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxyALM instance passing in: IProxyListener, appName, and isMediaApp.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink. + * + * Takes advantage of the advanced lifecycle management. + * + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @param appName - Name of the application displayed on SmartDeviceLink. + * @param ngnMediaScreenAppName - Name of the application displayed on SmartDeviceLink for Navigation equipped + * vehicles. Limited to five characters. + * @param vrSynonyms - A vector of strings, all of which can be used as voice commands to + * @param isMediaApp - Indicates if the app is a media application. + * @param SyncMsgVersion - Indicates the version of SmartDeviceLink SmartDeviceLink Messages desired. Must be less than + * or equal to the version of SmartDeviceLink SmartDeviceLink running on the vehicle. + * @param languageDesired - Indicates the language desired for the SmartDeviceLink interface. + * @param autoActivateID - ID used to re-register previously registered application. + * @throws SmartDeviceLinkException + */ + public SmartDeviceLinkProxyALM(IProxyListenerALM listener, String appName, String ngnMediaScreenAppName, + Vector<String> vrSynonyms, Boolean isMediaApp, SyncMsgVersion SyncMsgVersion, + Language languageDesired, String autoActivateID) throws SmartDeviceLinkException { + super( listener, + /*SmartDeviceLink proxy configuration resources*/null, + /*enable advanced lifecycle management*/true, + appName, + ngnMediaScreenAppName, + vrSynonyms, + isMediaApp, + SyncMsgVersion, + languageDesired, + autoActivateID, + /*callbackToUIThread*/ false); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxyALM instance passing in: IProxyListener, appName, ngnMediaScreenAppName, " + + "vrSynonyms, isMediaApp, SyncMsgVersion, languageDesired, and autoActivateID.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink. + * + * Takes advantage of the advanced lifecycle management. + * + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @param applicationContext - Context of the application. Used to access application specific resources. + * @param appName - Name of the application displayed on SmartDeviceLink. + * @param ngnMediaScreenAppName - Name of the application displayed on SmartDeviceLink for Navigation equipped + * vehicles. Limited to five characters. + * @param vrSynonyms - A vector of strings, all of which can be used as voice commands to + * @param isMediaApp - Indicates if the app is a media application. + * @param SyncMsgVersion - Indicates the version of SmartDeviceLink SmartDeviceLink Messages desired. Must be less than + * or equal to the version of SmartDeviceLink SmartDeviceLink running on the vehicle. + * @param languageDesired - Indicates the language desired for the SmartDeviceLink interface. + * @param autoActivateID - ID used to re-register previously registered application. + * @throws SmartDeviceLinkException + */ + public SmartDeviceLinkProxyALM(IProxyListenerALM listener, SmartDeviceLinkProxyConfigurationResources SmartDeviceLinkProxyConfigurationResources, + String appName, String ngnMediaScreenAppName, Vector<String> vrSynonyms, + Boolean isMediaApp, SyncMsgVersion SyncMsgVersion, Language languageDesired, + String autoActivateID) throws SmartDeviceLinkException { + super( listener, + SmartDeviceLinkProxyConfigurationResources, + /*enable advanced lifecycle management*/true, + appName, + ngnMediaScreenAppName, + vrSynonyms, + isMediaApp, + SyncMsgVersion, + languageDesired, + autoActivateID, + /*callbackToUIThread*/ false); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxyALM instance passing in: IProxyListener, SmartDeviceLinkProxyConfigurationResources, " + + "appName, ngnMediaScreenAppName, vrSynonyms, isMediaApp, SyncMsgVersion, languageDesired, and autoActivateID.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink. + * + * Takes advantage of the advanced lifecycle management. + * + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @param appName - Name of the application displayed on SmartDeviceLink. + * @param ngnMediaScreenAppName - Name of the application displayed on SmartDeviceLink for Navigation equipped + * vehicles. Limited to five characters. + * @param vrSynonyms - A vector of strings, all of which can be used as voice commands to + * @param isMediaApp - Indicates if the app is a media application. + * @param SyncMsgVersion - Indicates the version of SmartDeviceLink SmartDeviceLink Messages desired. Must be less than + * or equal to the version of SmartDeviceLink SmartDeviceLink running on the vehicle. + * @param languageDesired - Indicates the language desired for the SmartDeviceLink interface. + * @param autoActivateID - ID used to re-register previously registered application. + * @param callbackToUIThread - If true, all callbacks will occur on the UI thread. + * @throws SmartDeviceLinkException + */ + public SmartDeviceLinkProxyALM(IProxyListenerALM listener, String appName, String ngnMediaScreenAppName, + Vector<String> vrSynonyms, Boolean isMediaApp, SyncMsgVersion SyncMsgVersion, + Language languageDesired, String autoActivateID, boolean callbackToUIThread) throws SmartDeviceLinkException { + super( listener, + /*SmartDeviceLink proxy configuration resources*/null, + /*enable advanced lifecycle management*/true, + appName, + ngnMediaScreenAppName, + vrSynonyms, + isMediaApp, + SyncMsgVersion, + languageDesired, + autoActivateID, + callbackToUIThread); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxyALM instance passing in: IProxyListener, " + + "appName, ngnMediaScreenAppName, vrSynonyms, isMediaApp, SyncMsgVersion, languageDesired, autoActivateID, " + + "and callbackToUIThread", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + /** + * Constructor for the SmartDeviceLinkProxy object, the proxy for communicating between the App and SmartDeviceLink. + * + * Takes advantage of the advanced lifecycle management. + * + * @param listener - Reference to the object in the App listening to callbacks from SmartDeviceLink. + * @param applicationContext - Context of the application. Used to access application specific resources. + * @param appName - Name of the application displayed on SmartDeviceLink. + * @param ngnMediaScreenAppName - Name of the application displayed on SmartDeviceLink for Navigation equipped + * vehicles. Limited to five characters. + * @param vrSynonyms - A vector of strings, all of which can be used as voice commands to + * @param isMediaApp - Indicates if the app is a media application. + * @param SyncMsgVersion - Indicates the version of SmartDeviceLink SmartDeviceLink Messages desired. Must be less than + * or equal to the version of SmartDeviceLink SmartDeviceLink running on the vehicle. + * @param languageDesired - Indicates the language desired for the SmartDeviceLink interface. + * @param autoActivateID - ID used to re-register previously registered application. + * @param callbackToUIThread - If true, all callbacks will occur on the UI thread. + * @throws SmartDeviceLinkException + */ + public SmartDeviceLinkProxyALM(IProxyListenerALM listener, SmartDeviceLinkProxyConfigurationResources SmartDeviceLinkProxyConfigurationResources, + String appName, String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, + SyncMsgVersion SyncMsgVersion, Language languageDesired, String autoActivateID, + boolean callbackToUIThread) throws SmartDeviceLinkException { + super( listener, + SmartDeviceLinkProxyConfigurationResources, + /*enable advanced lifecycle management*/true, + appName, + ngnMediaScreenAppName, + vrSynonyms, + isMediaApp, + SyncMsgVersion, + languageDesired, + autoActivateID, + callbackToUIThread); + + SyncTrace.logProxyEvent("Application constructed SmartDeviceLinkProxyALM instance passing in: IProxyListener, SmartDeviceLinkProxyConfigurationResources, " + + "appName, ngnMediaScreenAppName, vrSynonyms, isMediaApp, SyncMsgVersion, languageDesired, autoActivateID, " + + "and callbackToUIThread", SMARTDEVICELINK_LIB_TRACE_KEY); + } + + // Allow applications using ALM to reset the proxy (dispose and reinstantiate) + /** + * Disconnects the application from SmartDeviceLink, then recreates the transport such that + * the next time a SmartDeviceLink unit discovers applications, this application will be + * available. + */ + public void resetProxy() throws SmartDeviceLinkException { + super.cycleProxy(SmartDeviceLinkDisconnectedReason.APPLICATION_REQUESTED_DISCONNECT); + } + + /********* Getters for values returned by RegisterAppInterfaceResponse **********/ + + /** + * Gets autoActivateId set when application interface is registered. + * + * @return autoActivateId + * @throws SmartDeviceLinkException + */ + public String getAutoActivateId() throws SmartDeviceLinkException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test SmartDeviceLink availability + if (!_appInterfaceRegisterd) { + throw new SmartDeviceLinkException("SmartDeviceLink is not connected. Unable to get the autoActivateId.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + return _autoActivateIdReturned; + } + + /** + * Gets buttonCapabilities set when application interface is registered. + * + * @return buttonCapabilities + * @throws SmartDeviceLinkException + */ + public Vector<ButtonCapabilities> getButtonCapabilities() throws SmartDeviceLinkException{ + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test SmartDeviceLink availability + if (!_appInterfaceRegisterd) { + throw new SmartDeviceLinkException("SmartDeviceLink is unavailable. Unable to get the buttonCapabilities.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + return _buttonCapabilities; + } + + /** + * Gets displayCapabilities set when application interface is registered. + * + * @return displayCapabilities + * @throws SmartDeviceLinkException + */ + public DisplayCapabilities getDisplayCapabilities() throws SmartDeviceLinkException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test SmartDeviceLink availability + if (!_appInterfaceRegisterd) { + throw new SmartDeviceLinkException("SmartDeviceLink is unavailable. Unable to get the displayCapabilities.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + return _displayCapabilities; + } + + /** + * Gets hmiZoneCapabilities set when application interface is registered. + * + * @return hmiZoneCapabilities + * @throws SmartDeviceLinkException + */ + public Vector<HmiZoneCapabilities> getHmiZoneCapabilities() throws SmartDeviceLinkException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test SmartDeviceLink availability + if (!_appInterfaceRegisterd) { + throw new SmartDeviceLinkException("SmartDeviceLink is unavailable. Unable to get the hmiZoneCapabilities.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + return _hmiZoneCapabilities; + } + + /** + * Gets speechCapabilities set when application interface is registered. + * + * @return speechCapabilities + * @throws SmartDeviceLinkException + */ + public Vector<SpeechCapabilities> getSpeechCapabilities() throws SmartDeviceLinkException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test SmartDeviceLink availability + if (!_appInterfaceRegisterd) { + throw new SmartDeviceLinkException("SmartDeviceLink is unavailable. Unable to get the speechCapabilities.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + + return _speechCapabilities; + } + + /** + * Gets SmartDeviceLinkLanguage set when application interface is registered. + * + * @return SmartDeviceLinkLanguage + * @throws SmartDeviceLinkException + */ + public Language getSmartDeviceLinkLanguage() throws SmartDeviceLinkException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test SmartDeviceLink availability + if (!_appInterfaceRegisterd) { + throw new SmartDeviceLinkException("SmartDeviceLink is unavailable. Unable to get the SmartDeviceLinkLanguage.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + return _SmartDeviceLinkLanguage; + } + + /** + * Gets SyncMsgVersion set when application interface is registered. + * + * @return SyncMsgVersion + * @throws SmartDeviceLinkException + */ + public SyncMsgVersion getSyncMsgVersion() throws SmartDeviceLinkException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test SmartDeviceLink availability + if (!_appInterfaceRegisterd) { + throw new SmartDeviceLinkException("SmartDeviceLink is unavailable. Unable to get the SyncMsgVersion.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + return _SyncMsgVersion; + } + + /** + * Gets vrCapabilities set when application interface is registered. + * + * @return vrCapabilities + * @throws SmartDeviceLinkException + */ + public Vector<VrCapabilities> getVrCapabilities() throws SmartDeviceLinkException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test SmartDeviceLink availability + if (!_appInterfaceRegisterd) { + throw new SmartDeviceLinkException("SmartDeviceLink is unavailable. Unable to get the vrCapabilities.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + return _vrCapabilities; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyBase.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyBase.java new file mode 100755 index 000000000..fb7ef9333 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyBase.java @@ -0,0 +1,2270 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Hashtable; +import java.util.Vector; + +import android.os.Handler; +import android.os.Looper; +import android.telephony.TelephonyManager; + +import com.smartdevicelink.exception.SmartDeviceLinkException; +import com.smartdevicelink.exception.SmartDeviceLinkExceptionCause; +import com.smartdevicelink.marshal.JsonRPCMarshaller; +import com.smartdevicelink.messageDispatcher.IDispatchingStrategy; +import com.smartdevicelink.messageDispatcher.IncomingProtocolMessageComparitor; +import com.smartdevicelink.messageDispatcher.InternalProxyMessageComparitor; +import com.smartdevicelink.messageDispatcher.OutgoingProtocolMessageComparitor; +import com.smartdevicelink.messageDispatcher.ProxyMessageDispatcher; +import com.smartdevicelink.protocol.ProtocolMessage; +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.protocol.enums.MessageType; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.proxy.callbacks.InternalProxyMessage; +import com.smartdevicelink.proxy.callbacks.OnProxyClosed; +import com.smartdevicelink.proxy.callbacks.OnError; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.interfaces.IProxyListenerBase; +import com.smartdevicelink.proxy.rpc.AddCommand; +import com.smartdevicelink.proxy.rpc.AddCommandResponse; +import com.smartdevicelink.proxy.rpc.AddSubMenu; +import com.smartdevicelink.proxy.rpc.AddSubMenuResponse; +import com.smartdevicelink.proxy.rpc.Alert; +import com.smartdevicelink.proxy.rpc.AlertResponse; +import com.smartdevicelink.proxy.rpc.ButtonCapabilities; +import com.smartdevicelink.proxy.rpc.Choice; +import com.smartdevicelink.proxy.rpc.CreateInteractionChoiceSet; +import com.smartdevicelink.proxy.rpc.CreateInteractionChoiceSetResponse; +import com.smartdevicelink.proxy.rpc.DeleteCommand; +import com.smartdevicelink.proxy.rpc.DeleteCommandResponse; +import com.smartdevicelink.proxy.rpc.DeleteInteractionChoiceSet; +import com.smartdevicelink.proxy.rpc.DeleteInteractionChoiceSetResponse; +import com.smartdevicelink.proxy.rpc.DeleteSubMenu; +import com.smartdevicelink.proxy.rpc.DeleteSubMenuResponse; +import com.smartdevicelink.proxy.rpc.DisplayCapabilities; +import com.smartdevicelink.proxy.rpc.EncodedSyncPData; +import com.smartdevicelink.proxy.rpc.EncodedSyncPDataResponse; +import com.smartdevicelink.proxy.rpc.GenericResponse; +import com.smartdevicelink.proxy.rpc.OnAppInterfaceUnregistered; +import com.smartdevicelink.proxy.rpc.OnButtonEvent; +import com.smartdevicelink.proxy.rpc.OnButtonPress; +import com.smartdevicelink.proxy.rpc.OnCommand; +import com.smartdevicelink.proxy.rpc.OnDriverDistraction; +import com.smartdevicelink.proxy.rpc.OnEncodedSyncPData; +import com.smartdevicelink.proxy.rpc.OnHMIStatus; +import com.smartdevicelink.proxy.rpc.OnPermissionsChange; +import com.smartdevicelink.proxy.rpc.OnTBTClientState; +import com.smartdevicelink.proxy.rpc.PerformInteraction; +import com.smartdevicelink.proxy.rpc.PerformInteractionResponse; +import com.smartdevicelink.proxy.rpc.RegisterAppInterface; +import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse; +import com.smartdevicelink.proxy.rpc.ResetGlobalProperties; +import com.smartdevicelink.proxy.rpc.ResetGlobalPropertiesResponse; +import com.smartdevicelink.proxy.rpc.SetGlobalProperties; +import com.smartdevicelink.proxy.rpc.SetGlobalPropertiesResponse; +import com.smartdevicelink.proxy.rpc.SetMediaClockTimer; +import com.smartdevicelink.proxy.rpc.SetMediaClockTimerResponse; +import com.smartdevicelink.proxy.rpc.Show; +import com.smartdevicelink.proxy.rpc.ShowResponse; +import com.smartdevicelink.proxy.rpc.Speak; +import com.smartdevicelink.proxy.rpc.SpeakResponse; +import com.smartdevicelink.proxy.rpc.SubscribeButton; +import com.smartdevicelink.proxy.rpc.SubscribeButtonResponse; +import com.smartdevicelink.proxy.rpc.SyncMsgVersion; +import com.smartdevicelink.proxy.rpc.TTSChunk; +import com.smartdevicelink.proxy.rpc.UnregisterAppInterface; +import com.smartdevicelink.proxy.rpc.UnregisterAppInterfaceResponse; +import com.smartdevicelink.proxy.rpc.UnsubscribeButton; +import com.smartdevicelink.proxy.rpc.UnsubscribeButtonResponse; +import com.smartdevicelink.proxy.rpc.enums.AudioStreamingState; +import com.smartdevicelink.proxy.rpc.enums.ButtonName; +import com.smartdevicelink.proxy.rpc.enums.GlobalProperty; +import com.smartdevicelink.proxy.rpc.enums.HMILevel; +import com.smartdevicelink.proxy.rpc.enums.HmiZoneCapabilities; +import com.smartdevicelink.proxy.rpc.enums.InteractionMode; +import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities; +import com.smartdevicelink.proxy.rpc.enums.SmartDeviceLinkConnectionState; +import com.smartdevicelink.proxy.rpc.enums.SmartDeviceLinkDisconnectedReason; +import com.smartdevicelink.proxy.rpc.enums.SmartDeviceLinkInterfaceAvailability; +import com.smartdevicelink.proxy.rpc.enums.SystemContext; +import com.smartdevicelink.proxy.rpc.enums.TextAlignment; +import com.smartdevicelink.proxy.rpc.enums.UpdateMode; +import com.smartdevicelink.proxy.rpc.enums.VrCapabilities; +import com.smartdevicelink.syncConnection.ISmartDeviceLinkConnectionListener; +import com.smartdevicelink.syncConnection.SmartDeviceLinkConnection; +import com.smartdevicelink.trace.TraceDeviceInfo; +import com.smartdevicelink.trace.SyncTrace; +import com.smartdevicelink.trace.enums.InterfaceActivityDirection; +import com.smartdevicelink.transport.BTTransportConfig; +import com.smartdevicelink.transport.BaseTransportConfig; +import com.smartdevicelink.transport.SiphonServer; +import com.smartdevicelink.transport.TransportType; +import com.smartdevicelink.util.DebugTool; + +public abstract class SmartDeviceLinkProxyBase<proxyListenerType extends IProxyListenerBase> { + // Used for calls to Android Log class. + public static final String TAG = "SmartDeviceLinkProxy"; + private static final String SMARTDEVICELINK_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + private SmartDeviceLinkConnection _SmartDeviceLinkConnection; + private proxyListenerType _proxyListener = null; + + // Protected Correlation IDs + private final int REGISTER_APP_INTERFACE_CORRELATION_ID = 65529, + UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530; + + // SmartDeviceLinkhronization Objects + private static final Object CONNECTION_REFERENCE_LOCK = new Object(), + INCOMING_MESSAGE_QUEUE_THREAD_LOCK = new Object(), + OUTGOING_MESSAGE_QUEUE_THREAD_LOCK = new Object(), + INTERNAL_MESSAGE_QUEUE_THREAD_LOCK = new Object(), + APP_INTERFACE_REGISTERED_LOCK = new Object(); + + // RPC Session ID + private byte _rpcSessionID = 0; + + // Device Info for logging + private TraceDeviceInfo _traceDeviceInterrogator = null; + + // Declare Queuing Threads + private ProxyMessageDispatcher<ProtocolMessage> _incomingProxyMessageDispatcher; + private ProxyMessageDispatcher<ProtocolMessage> _outgoingProxyMessageDispatcher; + private ProxyMessageDispatcher<InternalProxyMessage> _internalProxyMessageDispatcher; + + // Flag indicating if callbacks should be called from UIThread + private Boolean _callbackToUIThread = false; + // UI Handler + private Handler _mainUIHandler = null; + + // SmartDeviceLinkProxy Advanced Lifecycle Management + protected Boolean _advancedLifecycleManagementEnabled = false; + // Parameters passed to the constructor from the app to register an app interface + private String _applicationName = null; + private String _ngnMediaScreenAppName = null; + private Boolean _isMediaApp = null; + private Language _SmartDeviceLinkLanguageDesired = null; + private String _autoActivateIdDesired = null; + private SyncMsgVersion _SyncMsgVersionRequest = null; + private Vector<String> _vrSynonyms = null; + + private BaseTransportConfig _transportConfig = null; + // Proxy State Variables + protected Boolean _appInterfaceRegisterd = false; + protected Boolean _haveReceivedFirstFocusLevel = false; + protected Boolean _haveReceivedFirstFocusLevelFull = false; + protected Boolean _proxyDisposed = false; + protected SmartDeviceLinkConnectionState _SmartDeviceLinkConnectionState = null; + protected SmartDeviceLinkInterfaceAvailability _SmartDeviceLinkIntefaceAvailablity = null; + protected HMILevel _hmiLevel = null; + private HMILevel _priorHmiLevel = null; + protected AudioStreamingState _audioStreamingState = null; + private AudioStreamingState _priorAudioStreamingState = null; + protected SystemContext _systemContext = null; + // Variables set by RegisterAppInterfaceResponse + protected SyncMsgVersion _SyncMsgVersion = null; + protected String _autoActivateIdReturned = null; + protected Language _SmartDeviceLinkLanguage = null; + protected DisplayCapabilities _displayCapabilities = null; + protected Vector<ButtonCapabilities> _buttonCapabilities = null; + protected Vector<HmiZoneCapabilities> _hmiZoneCapabilities = null; + protected Vector<SpeechCapabilities> _speechCapabilities = null; + protected Vector<VrCapabilities> _vrCapabilities = null; + protected Boolean firstTimeFull = true; + + protected byte _protocolVersion = 1; + + // Interface broker + private SmartDeviceLinkInterfaceBroker _interfaceBroker = null; + + // Private Class to Interface with SmartDeviceLinkConnection + private class SmartDeviceLinkInterfaceBroker implements ISmartDeviceLinkConnectionListener { + + @Override + public void onTransportDisconnected(String info) { + // proxyOnTransportDisconnect is called to alert the proxy that a requested + // disconnect has completed + + if (_advancedLifecycleManagementEnabled) { + // If ALM, nothing is required to be done here + } else { + // If original model, notify app the proxy is closed so it will delete and reinstanciate + notifyProxyClosed(info, new SmartDeviceLinkException("Transport disconnected.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE)); + } + } + + @Override + public void onTransportError(String info, Exception e) { + DebugTool.logError("Transport failure: " + info, e); + + if (_advancedLifecycleManagementEnabled) { + // Cycle the proxy + cycleProxy(SmartDeviceLinkDisconnectedReason.TRANSPORT_ERROR); + } else { + notifyProxyClosed(info, e); + } + } + + @Override + public void onProtocolMessageReceived(ProtocolMessage msg) { + try {if (msg.getData().length > 0) queueIncomingMessage(msg);} + catch (Exception e) {} + try {if (msg.getBulkData().length > 0) queueIncomingMessage(msg);} + catch (Exception e) {} + } + + @Override + public void onProtocolSessionStarted(SessionType sessionType, + byte sessionID, byte version, String correlationID) { + if (_protocolVersion == 1) { + if (version == 2) setProtocolVersion(version); + } + if (sessionType.eq(SessionType.RPC)) { + startRPCProtocolSession(sessionID, correlationID); + } else if (_protocolVersion == 2) { + //If version 2 then don't need to specify a Session Type + startRPCProtocolSession(sessionID, correlationID); + } else { + // Handle other protocol session types here + } + } + + @Override + public void onProtocolSessionEnded(SessionType sessionType, + byte sessionID, String correlationID) { + // How to handle protocol session ended? + // How should protocol session management occur? + } + + @Override + public void onProtocolError(String info, Exception e) { + passErrorToProxyListener(info, e); + } + } + + protected SmartDeviceLinkProxyBase(proxyListenerType listener, SmartDeviceLinkProxyConfigurationResources SmartDeviceLinkProxyConfigurationResources, + boolean enableAdvancedLifecycleManagement, String appName, String ngnMediaScreenAppName, + Vector<String> vrSynonyms, Boolean isMediaApp, SyncMsgVersion SyncMsgVersion, + Language languageDesired, String autoActivateID, boolean callbackToUIThread, + BaseTransportConfig transportConfig) + throws SmartDeviceLinkException { + + _interfaceBroker = new SmartDeviceLinkInterfaceBroker(); + + _callbackToUIThread = callbackToUIThread; + + if (_callbackToUIThread) { + _mainUIHandler = new Handler(Looper.getMainLooper()); + } + + // Set variables for Advanced Lifecycle Management + _advancedLifecycleManagementEnabled = enableAdvancedLifecycleManagement; + _applicationName = appName; + _ngnMediaScreenAppName = ngnMediaScreenAppName; + _isMediaApp = isMediaApp; + _SyncMsgVersionRequest = SyncMsgVersion; + _vrSynonyms = vrSynonyms; + _SmartDeviceLinkLanguageDesired = languageDesired; + _autoActivateIdDesired = autoActivateID; + _transportConfig = transportConfig; + + // Test conditions to invalidate the proxy + if (listener == null) { + throw new IllegalArgumentException("IProxyListener listener must be provided to instantiate SmartDeviceLinkProxy object."); + } + if (_advancedLifecycleManagementEnabled) { + if (_applicationName == null ) { + throw new IllegalArgumentException("To use SmartDeviceLinkProxyALM, an application name, appName, must be provided"); + } + if (_applicationName.length() < 1 || _applicationName.length() > 100) { + throw new IllegalArgumentException("A provided application name, appName, must be between 1 and 100 characters in length."); + } + if (_isMediaApp == null) { + throw new IllegalArgumentException("isMediaApp must not be null when using SmartDeviceLinkProxyALM."); + } + } + + _proxyListener = listener; + + // Get information from SmartDeviceLinkProxyConfigurationResources + TelephonyManager telephonyManager = null; + if (SmartDeviceLinkProxyConfigurationResources != null) { + telephonyManager = SmartDeviceLinkProxyConfigurationResources.getTelephonyManager(); + } + + // Use the telephonyManager to get and log phone info + if (telephonyManager != null) { + // Following is not quite thread-safe (because m_traceLogger could test null twice), + // so we need to fix this, but vulnerability (i.e. two instances of listener) is + // likely harmless. + if (_traceDeviceInterrogator == null) { + _traceDeviceInterrogator = new TraceDeviceInfo(SmartDeviceLinkProxyConfigurationResources.getTelephonyManager()); + } // end-if + } // end-if + + // Setup Internal ProxyMessage Dispatcher + synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure internalProxyMessageDispatcher is null + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.dispose(); + _internalProxyMessageDispatcher = null; + } + + _internalProxyMessageDispatcher = new ProxyMessageDispatcher<InternalProxyMessage>("INTERNAL_MESSAGE_DISPATCHER", + new InternalProxyMessageComparitor(), + new IDispatchingStrategy<InternalProxyMessage>() { + + @Override + public void dispatch(InternalProxyMessage message) { + dispatchInternalMessage((InternalProxyMessage)message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromInternalMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromInternalMessageDispatcher(info, ex); + } + }); + } + + // Setup Incoming ProxyMessage Dispatcher + synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure incomingProxyMessageDispatcher is null + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.dispose(); + _incomingProxyMessageDispatcher = null; + } + + _incomingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("INCOMING_MESSAGE_DISPATCHER", + new IncomingProtocolMessageComparitor(), + new IDispatchingStrategy<ProtocolMessage>() { + @Override + public void dispatch(ProtocolMessage message) { + dispatchIncomingMessage((ProtocolMessage)message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromIncomingMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromIncomingMessageDispatcher(info, ex); + } + }); + } + + // Setup Outgoing ProxyMessage Dispatcher + synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure outgoingProxyMessageDispatcher is null + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.dispose(); + _outgoingProxyMessageDispatcher = null; + } + + _outgoingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("OUTGOING_MESSAGE_DISPATCHER", + new OutgoingProtocolMessageComparitor(), + new IDispatchingStrategy<ProtocolMessage>() { + @Override + public void dispatch(ProtocolMessage message) { + dispatchOutgoingMessage((ProtocolMessage)message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromOutgoingMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromOutgoingMessageDispatcher(info, ex); + } + }); + } + + // Initialize the proxy + try { + initializeProxy(); + } catch (SmartDeviceLinkException e) { + // Couldn't initialize the proxy + // Dispose threads and then rethrow exception + + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.dispose(); + _internalProxyMessageDispatcher = null; + } + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.dispose(); + _incomingProxyMessageDispatcher = null; + } + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.dispose(); + _outgoingProxyMessageDispatcher = null; + } + throw e; + } + + // Trace that ctor has fired + SyncTrace.logProxyEvent("SmartDeviceLinkProxy Created, instanceID=" + this.toString(), SMARTDEVICELINK_LIB_TRACE_KEY); + } + + protected SmartDeviceLinkProxyBase(proxyListenerType listener, SmartDeviceLinkProxyConfigurationResources SmartDeviceLinkProxyConfigurationResources, + boolean enableAdvancedLifecycleManagement, String appName, String ngnMediaScreenAppName, + Vector<String> vrSynonyms, Boolean isMediaApp, SyncMsgVersion SyncMsgVersion, + Language languageDesired, String autoActivateID, boolean callbackToUIThread) + throws SmartDeviceLinkException { + + _interfaceBroker = new SmartDeviceLinkInterfaceBroker(); + + _callbackToUIThread = callbackToUIThread; + + if (_callbackToUIThread) { + _mainUIHandler = new Handler(Looper.getMainLooper()); + } + + // Set variables for Advanced Lifecycle Management + _advancedLifecycleManagementEnabled = enableAdvancedLifecycleManagement; + _applicationName = appName; + _ngnMediaScreenAppName = ngnMediaScreenAppName; + _isMediaApp = isMediaApp; + _SyncMsgVersionRequest = SyncMsgVersion; + _vrSynonyms = vrSynonyms; + _SmartDeviceLinkLanguageDesired = languageDesired; + _autoActivateIdDesired = autoActivateID; + _transportConfig = new BTTransportConfig(); + + // Test conditions to invalidate the proxy + if (listener == null) { + throw new IllegalArgumentException("IProxyListener listener must be provided to instantiate SmartDeviceLinkProxy object."); + } + if (_advancedLifecycleManagementEnabled) { + if (_applicationName == null ) { + throw new IllegalArgumentException("To use SmartDeviceLinkProxyALM, an application name, appName, must be provided"); + } + if (_applicationName.length() < 1 || _applicationName.length() > 100) { + throw new IllegalArgumentException("A provided application name, appName, must be between 1 and 100 characters in length."); + } + if (_isMediaApp == null) { + throw new IllegalArgumentException("isMediaApp must not be null when using SmartDeviceLinkProxyALM."); + } + } + + _proxyListener = listener; + + // Get information from SmartDeviceLinkProxyConfigurationResources + TelephonyManager telephonyManager = null; + if (SmartDeviceLinkProxyConfigurationResources != null) { + telephonyManager = SmartDeviceLinkProxyConfigurationResources.getTelephonyManager(); + } + + // Use the telephonyManager to get and log phone info + if (telephonyManager != null) { + // Following is not quite thread-safe (because m_traceLogger could test null twice), + // so we need to fix this, but vulnerability (i.e. two instances of listener) is + // likely harmless. + if (_traceDeviceInterrogator == null) { + _traceDeviceInterrogator = new TraceDeviceInfo(SmartDeviceLinkProxyConfigurationResources.getTelephonyManager()); + } // end-if + } // end-if + + // Setup Internal ProxyMessage Dispatcher + synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure internalProxyMessageDispatcher is null + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.dispose(); + _internalProxyMessageDispatcher = null; + } + + _internalProxyMessageDispatcher = new ProxyMessageDispatcher<InternalProxyMessage>("INTERNAL_MESSAGE_DISPATCHER", + new InternalProxyMessageComparitor(), + new IDispatchingStrategy<InternalProxyMessage>() { + + @Override + public void dispatch(InternalProxyMessage message) { + dispatchInternalMessage((InternalProxyMessage)message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromInternalMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromInternalMessageDispatcher(info, ex); + } + }); + } + + // Setup Incoming ProxyMessage Dispatcher + synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure incomingProxyMessageDispatcher is null + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.dispose(); + _incomingProxyMessageDispatcher = null; + } + + _incomingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("INCOMING_MESSAGE_DISPATCHER", + new IncomingProtocolMessageComparitor(), + new IDispatchingStrategy<ProtocolMessage>() { + @Override + public void dispatch(ProtocolMessage message) { + dispatchIncomingMessage((ProtocolMessage)message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromIncomingMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromIncomingMessageDispatcher(info, ex); + } + }); + } + + // Setup Outgoing ProxyMessage Dispatcher + synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure outgoingProxyMessageDispatcher is null + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.dispose(); + _outgoingProxyMessageDispatcher = null; + } + + _outgoingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("OUTGOING_MESSAGE_DISPATCHER", + new OutgoingProtocolMessageComparitor(), + new IDispatchingStrategy<ProtocolMessage>() { + @Override + public void dispatch(ProtocolMessage message) { + dispatchOutgoingMessage((ProtocolMessage)message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromOutgoingMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromOutgoingMessageDispatcher(info, ex); + } + }); + } + + // Initialize the proxy + try { + initializeProxy(); + } catch (SmartDeviceLinkException e) { + // Couldn't initialize the proxy + // Dispose threads and then rethrow exception + + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.dispose(); + _internalProxyMessageDispatcher = null; + } + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.dispose(); + _incomingProxyMessageDispatcher = null; + } + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.dispose(); + _outgoingProxyMessageDispatcher = null; + } + throw e; + } + + // Trace that ctor has fired + SyncTrace.logProxyEvent("SmartDeviceLinkProxy Created, instanceID=" + this.toString(), SMARTDEVICELINK_LIB_TRACE_KEY); + } + + // Test correlationID + private boolean isCorrelationIDProtected(Integer correlationID) { + if (correlationID != null && + (REGISTER_APP_INTERFACE_CORRELATION_ID == correlationID + || UNREGISTER_APP_INTERFACE_CORRELATION_ID == correlationID)) { + return true; + } + + return false; + } + + // Protected isConnected method to allow legacy proxy to poll isConnected state + public Boolean getIsConnected() { + return _SmartDeviceLinkConnection.getIsConnected(); + } + + + // Function to initialize new proxy connection + private void initializeProxy() throws SmartDeviceLinkException { + // Reset all of the flags and state variables + _haveReceivedFirstFocusLevel = false; + _haveReceivedFirstFocusLevelFull = false; + _SmartDeviceLinkIntefaceAvailablity = SmartDeviceLinkInterfaceAvailability.SMARTDEVICELINK_INTERFACE_UNAVAILABLE; + + // Setup SmartDeviceLinkConnection + synchronized(CONNECTION_REFERENCE_LOCK) { + if (_SmartDeviceLinkConnection != null) { + _SmartDeviceLinkConnection.closeConnection(_rpcSessionID); + _SmartDeviceLinkConnection = null; + } + _SmartDeviceLinkConnection = new SmartDeviceLinkConnection(_interfaceBroker, _transportConfig); + } + + synchronized(CONNECTION_REFERENCE_LOCK) { + if (_SmartDeviceLinkConnection != null) { + _SmartDeviceLinkConnection.startTransport(); + } + } + } + + // Public method to enable the siphon transport + public static void enableSiphonDebug() { + SiphonServer.enableSiphonServer(); + } + + // Public method to disable the Siphon Trace Server + public static void disableSiphonDebug() { + SiphonServer.disableSiphonServer(); + } + + // Public method to enable the Debug Tool + public static void enableDebugTool() { + DebugTool.enableDebugTool(); + } + + // Public method to disable the Debug Tool + public static void disableDebugTool() { + DebugTool.disableDebugTool(); + } + + @Deprecated + public void close() throws SmartDeviceLinkException { + dispose(); + } + + private void cleanProxy(SmartDeviceLinkDisconnectedReason disconnectedReason) throws SmartDeviceLinkException { + try { + + // ALM Specific Cleanup + if (_advancedLifecycleManagementEnabled) { + _SmartDeviceLinkConnectionState = SmartDeviceLinkConnectionState.SMARTDEVICELINK_DISCONNECTED; + + firstTimeFull = true; + + // Should we wait for the interface to be unregistered? + Boolean waitForInterfaceUnregistered = false; + // Unregister app interface + synchronized(CONNECTION_REFERENCE_LOCK) { + if (_appInterfaceRegisterd == true && _SmartDeviceLinkConnection != null && _SmartDeviceLinkConnection.getIsConnected()) { + waitForInterfaceUnregistered = true; + unregisterAppInterfacePrivate(UNREGISTER_APP_INTERFACE_CORRELATION_ID); + } + } + + // Wait for the app interface to be unregistered + if (waitForInterfaceUnregistered) { + synchronized(APP_INTERFACE_REGISTERED_LOCK) { + try { + APP_INTERFACE_REGISTERED_LOCK.wait(1000); + } catch (InterruptedException e) { + // Do nothing + } + } + } + } + + // Clean up SmartDeviceLink Connection + synchronized(CONNECTION_REFERENCE_LOCK) { + if (_SmartDeviceLinkConnection != null) { + _SmartDeviceLinkConnection.closeConnection(_rpcSessionID); + _SmartDeviceLinkConnection = null; + } + } + } catch (SmartDeviceLinkException e) { + throw e; + } finally { + SyncTrace.logProxyEvent("SmartDeviceLinkProxy cleaned.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + } + + /** + * Terminates the App's Interface Registration, closes the transport connection, ends the protocol session, and frees any resources used by the proxy. + */ + public void dispose() throws SmartDeviceLinkException + { + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + _proxyDisposed = true; + + SyncTrace.logProxyEvent("Application called dispose() method.", SMARTDEVICELINK_LIB_TRACE_KEY); + + try{ + // Clean the proxy + cleanProxy(SmartDeviceLinkDisconnectedReason.APPLICATION_REQUESTED_DISCONNECT); + + // Close IncomingProxyMessageDispatcher thread + synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) { + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.dispose(); + _incomingProxyMessageDispatcher = null; + } + } + + // Close OutgoingProxyMessageDispatcher thread + synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) { + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.dispose(); + _outgoingProxyMessageDispatcher = null; + } + } + + // Close InternalProxyMessageDispatcher thread + synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) { + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.dispose(); + _internalProxyMessageDispatcher = null; + } + } + + _traceDeviceInterrogator = null; + } catch (SmartDeviceLinkException e) { + throw e; + } finally { + SyncTrace.logProxyEvent("SmartDeviceLinkProxy disposed.", SMARTDEVICELINK_LIB_TRACE_KEY); + } + } // end-method + + // Method to cycle the proxy, only called in ALM + protected void cycleProxy(SmartDeviceLinkDisconnectedReason disconnectedReason) { + try{ + cleanProxy(disconnectedReason); + initializeProxy(); + notifyProxyClosed("SmartDeviceLink Proxy Cycled", new SmartDeviceLinkException("SmartDeviceLink Proxy Cycled", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_CYCLED)); + } catch (SmartDeviceLinkException e) { + switch(e.getSmartDeviceLinkExceptionCause()) { + case BLUETOOTH_DISABLED: + notifyProxyClosed("Bluetooth is disabled. Bluetooth must be enabled to connect to SmartDeviceLink. Reattempt a connection once Bluetooth is enabled.", + new SmartDeviceLinkException("Bluetooth is disabled. Bluetooth must be enabled to connect to SmartDeviceLink. Reattempt a connection once Bluetooth is enabled.", SmartDeviceLinkExceptionCause.BLUETOOTH_DISABLED)); + break; + case BLUETOOTH_ADAPTER_NULL: + notifyProxyClosed("Cannot locate a Bluetooth adapater. A SmartDeviceLink connection is impossible on this device until a Bluetooth adapter is added.", + new SmartDeviceLinkException("Cannot locate a Bluetooth adapater. A SmartDeviceLink connection is impossible on this device until a Bluetooth adapter is added.", SmartDeviceLinkExceptionCause.HEARTBEAT_PAST_DUE)); + break; + default : + notifyProxyClosed("Cycling the proxy failed.", e); + break; + } + } catch (Exception e) { + notifyProxyClosed("Cycling the proxy failed.", e); + } + } + + + + /************* Functions used by the Message Dispatching Queues ****************/ + private void dispatchIncomingMessage(ProtocolMessage message) { + try{ + // Dispatching logic + if (message.getSessionType().equals(SessionType.RPC)) { + try { + if (_protocolVersion == 1) { + if (message.getVersion() == 2) setProtocolVersion(message.getVersion()); + } + + Hashtable hash = new Hashtable(); + if (_protocolVersion == 2) { + Hashtable hashTemp = new Hashtable(); + hashTemp.put(Names.correlationID, message.getCorrID()); + if (message.getJsonSize() > 0) { + final Hashtable<String, Object> mhash = JsonRPCMarshaller.unmarshall(message.getData()); + hashTemp.put(Names.parameters, mhash); + } + FunctionID functionID = new FunctionID(); + hashTemp.put(Names.function_name, functionID.getFunctionName(message.getFunctionID())); + if (message.getRPCType() == 0x00) { + hash.put(Names.request, hashTemp); + } else if (message.getRPCType() == 0x01) { + hash.put(Names.response, hashTemp); + } else if (message.getRPCType() == 0x02) { + hash.put(Names.notification, hashTemp); + } + if (message.getBulkData() != null) hash.put(Names.bulkData, message.getBulkData()); + } else { + final Hashtable<String, Object> mhash = JsonRPCMarshaller.unmarshall(message.getData()); + hash = mhash; + } + handleRPCMessage(hash); + } catch (final Exception excp) { + DebugTool.logError("Failure handling protocol message: " + excp.toString(), excp); + passErrorToProxyListener("Error handing incoming protocol message.", excp); + } // end-catch + } else { + // Handle other protocol message types here + } + } catch (final Exception e) { + // Pass error to application through listener + DebugTool.logError("Error handing proxy event.", e); + passErrorToProxyListener("Error handing incoming protocol message.", e); + } + } + + private void setProtocolVersion(byte version) { + this._protocolVersion = version; + } + + private void handleErrorsFromIncomingMessageDispatcher(String info, Exception e) { + passErrorToProxyListener(info, e); + } + + private void dispatchOutgoingMessage(ProtocolMessage message) { + synchronized(CONNECTION_REFERENCE_LOCK) { + if (_SmartDeviceLinkConnection != null) { + _SmartDeviceLinkConnection.sendMessage(message); + } + } + SyncTrace.logProxyEvent("SmartDeviceLinkProxy sending Protocol Message: " + message.toString(), SMARTDEVICELINK_LIB_TRACE_KEY); + } + + private void handleErrorsFromOutgoingMessageDispatcher(String info, Exception e) { + passErrorToProxyListener(info, e); + } + + void dispatchInternalMessage(final InternalProxyMessage message) { + try{ + if (message.getFunctionName().equals(Names.OnProxyError)) { + final OnError msg = (OnError)message; + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onError(msg.getInfo(), msg.getException()); + } + }); + } else { + _proxyListener.onError(msg.getInfo(), msg.getException()); + } + /**************Start Legacy Specific Call-backs************/ + } else if (message.getFunctionName().equals(Names.OnProxyOpened)) { + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + ((IProxyListener)_proxyListener).onProxyOpened(); + } + }); + } else { + ((IProxyListener)_proxyListener).onProxyOpened(); + } + } else if (message.getFunctionName().equals(Names.OnProxyClosed)) { + final OnProxyClosed msg = (OnProxyClosed)message; + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onProxyClosed(msg.getInfo(), msg.getException()); + } + }); + } else { + _proxyListener.onProxyClosed(msg.getInfo(), msg.getException()); + } + /****************End Legacy Specific Call-backs************/ + } else { + // Diagnostics + SyncTrace.logProxyEvent("Unknown RPC Message encountered. Check for an updated version of the SmartDeviceLink Proxy.", SMARTDEVICELINK_LIB_TRACE_KEY); + DebugTool.logError("Unknown RPC Message encountered. Check for an updated version of the SmartDeviceLink Proxy."); + } + + SyncTrace.logProxyEvent("Proxy fired callback: " + message.getFunctionName(), SMARTDEVICELINK_LIB_TRACE_KEY); + } catch(final Exception e) { + // Pass error to application through listener + DebugTool.logError("Error handing proxy event.", e); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onError("Error handing proxy event.", e); + } + }); + } else { + _proxyListener.onError("Error handing proxy event.", e); + } + } + } + + private void handleErrorsFromInternalMessageDispatcher(String info, Exception e) { + DebugTool.logError(info, e); + // This error cannot be passed to the user, as it indicates an error + // in the communication between the proxy and the application. + + DebugTool.logError("InternalMessageDispatcher failed.", e); + + // Note, this is the only place where the _proxyListener should be referenced aSmartDeviceLinkhronously, + // with an error on the internalMessageDispatcher, we have no other reliable way of + // communicating with the application. + notifyProxyClosed("Proxy callback dispatcher is down. Proxy instance is invalid.", e); + _proxyListener.onError("Proxy callback dispatcher is down. Proxy instance is invalid.", e); + } + /************* END Functions used by the Message Dispatching Queues ****************/ + + + // Private sendPRCRequest method. All RPCRequests are funneled through this method after + // error checking. + private void sendRPCRequestPrivate(RPCRequest request) throws SmartDeviceLinkException { + SyncTrace.logRPCEvent(InterfaceActivityDirection.Transmit, request, SMARTDEVICELINK_LIB_TRACE_KEY); + + byte[] msgBytes = JsonRPCMarshaller.marshall(request, _protocolVersion); + + ProtocolMessage pm = new ProtocolMessage(); + pm.setData(msgBytes); + pm.setSessionID(_rpcSessionID); + pm.setMessageType(MessageType.RPC); + pm.setSessionType(SessionType.RPC); + FunctionID functionID = new FunctionID(); + pm.setFunctionID(functionID.getFunctionID(request.getFunctionName())); + pm.setCorrID(request.getCorrelationID()); + + // Queue this outgoing message + synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) { + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.queueMessage(pm); + } + } + } + + private void handleRPCMessage(Hashtable hash) { + RPCMessage rpcMsg = new RPCMessage(hash); + String functionName = rpcMsg.getFunctionName(); + String messageType = rpcMsg.getMessageType(); + + if (messageType.equals(Names.response)) { + SyncTrace.logRPCEvent(InterfaceActivityDirection.Receive, new RPCResponse(rpcMsg), SMARTDEVICELINK_LIB_TRACE_KEY); + + // Check to ensure response is not from an internal message (reserved correlation ID) + if (isCorrelationIDProtected((new RPCResponse(hash)).getCorrelationID())) { + // This is a response generated from an internal message, it can be trapped here + // The app should not receive a response for a request it did not send + if ((new RPCResponse(hash)).getCorrelationID() == REGISTER_APP_INTERFACE_CORRELATION_ID + && _advancedLifecycleManagementEnabled + && functionName.equals(Names.RegisterAppInterface)) { + final RegisterAppInterfaceResponse msg = new RegisterAppInterfaceResponse(hash); + if (msg.getSuccess()) { + _appInterfaceRegisterd = true; + } + + _autoActivateIdReturned = msg.getAutoActivateID(); + _buttonCapabilities = msg.getButtonCapabilities(); + _displayCapabilities = msg.getDisplayCapabilities(); + _hmiZoneCapabilities = msg.getHmiZoneCapabilities(); + _speechCapabilities = msg.getSpeechCapabilities(); + _SmartDeviceLinkLanguage = msg.getLanguage(); + _SyncMsgVersion = msg.getSyncMsgVersion(); + _vrCapabilities = msg.getVrCapabilities(); + + // Send onSmartDeviceLinkConnected message in ALM + _SmartDeviceLinkConnectionState = SmartDeviceLinkConnectionState.SMARTDEVICELINK_CONNECTED; + + // If registerAppInterface failed, exit with OnProxyUnusable + if (!msg.getSuccess()) { + notifyProxyClosed("Unable to register app interface. Review values passed to the SmartDeviceLinkProxy constructor. RegisterAppInterface result code: ", + new SmartDeviceLinkException("Unable to register app interface. Review values passed to the SmartDeviceLinkProxy constructor. RegisterAppInterface result code: " + msg.getResultCode(), SmartDeviceLinkExceptionCause.SMARTDEVICELINK_REGISTRATION_ERROR)); + } + } + return; + } + + if (functionName.equals(Names.RegisterAppInterface)) { + final RegisterAppInterfaceResponse msg = new RegisterAppInterfaceResponse(hash); + if (msg.getSuccess()) { + _appInterfaceRegisterd = true; + } + + _autoActivateIdReturned = msg.getAutoActivateID(); + _buttonCapabilities = msg.getButtonCapabilities(); + _displayCapabilities = msg.getDisplayCapabilities(); + _hmiZoneCapabilities = msg.getHmiZoneCapabilities(); + _speechCapabilities = msg.getSpeechCapabilities(); + _SmartDeviceLinkLanguage = msg.getLanguage(); + _SyncMsgVersion = msg.getSyncMsgVersion(); + _vrCapabilities = msg.getVrCapabilities(); + + // RegisterAppInterface + if (_advancedLifecycleManagementEnabled) { + + // Send onSmartDeviceLinkConnected message in ALM + _SmartDeviceLinkConnectionState = SmartDeviceLinkConnectionState.SMARTDEVICELINK_CONNECTED; + + // If registerAppInterface failed, exit with OnProxyUnusable + if (!msg.getSuccess()) { + notifyProxyClosed("Unable to register app interface. Review values passed to the SmartDeviceLinkProxy constructor. RegisterAppInterface result code: ", + new SmartDeviceLinkException("Unable to register app interface. Review values passed to the SmartDeviceLinkProxy constructor. RegisterAppInterface result code: " + msg.getResultCode(), SmartDeviceLinkExceptionCause.SMARTDEVICELINK_REGISTRATION_ERROR)); + } + } else { + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg); + } + }); + } else { + ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg); + } + } + } else if (functionName.equals(Names.Speak)) { + // SpeakResponse + + final SpeakResponse msg = new SpeakResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSpeakResponse(msg); + } + }); + } else { + _proxyListener.onSpeakResponse(msg); + } + } else if (functionName.equals(Names.Alert)) { + // AlertResponse + + final AlertResponse msg = new AlertResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onAlertResponse(msg); + } + }); + } else { + _proxyListener.onAlertResponse(msg); + } + } else if (functionName.equals(Names.Show)) { + // ShowResponse + + final ShowResponse msg = new ShowResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onShowResponse((ShowResponse)msg); + } + }); + } else { + _proxyListener.onShowResponse((ShowResponse)msg); + } + } else if (functionName.equals(Names.AddCommand)) { + // AddCommand + + final AddCommandResponse msg = new AddCommandResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onAddCommandResponse((AddCommandResponse)msg); + } + }); + } else { + _proxyListener.onAddCommandResponse((AddCommandResponse)msg); + } + } else if (functionName.equals(Names.DeleteCommand)) { + // DeleteCommandResponse + + final DeleteCommandResponse msg = new DeleteCommandResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDeleteCommandResponse((DeleteCommandResponse)msg); + } + }); + } else { + _proxyListener.onDeleteCommandResponse((DeleteCommandResponse)msg); + } + } else if (functionName.equals(Names.AddSubMenu)) { + // AddSubMenu + + final AddSubMenuResponse msg = new AddSubMenuResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onAddSubMenuResponse((AddSubMenuResponse)msg); + } + }); + } else { + _proxyListener.onAddSubMenuResponse((AddSubMenuResponse)msg); + } + } else if (functionName.equals(Names.DeleteSubMenu)) { + // DeleteSubMenu + + final DeleteSubMenuResponse msg = new DeleteSubMenuResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDeleteSubMenuResponse((DeleteSubMenuResponse)msg); + } + }); + } else { + _proxyListener.onDeleteSubMenuResponse((DeleteSubMenuResponse)msg); + } + } else if (functionName.equals(Names.SubscribeButton)) { + // SubscribeButton + + final SubscribeButtonResponse msg = new SubscribeButtonResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSubscribeButtonResponse((SubscribeButtonResponse)msg); + } + }); + } else { + _proxyListener.onSubscribeButtonResponse((SubscribeButtonResponse)msg); + } + } else if (functionName.equals(Names.UnsubscribeButton)) { + // UnsubscribeButton + + final UnsubscribeButtonResponse msg = new UnsubscribeButtonResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onUnsubscribeButtonResponse((UnsubscribeButtonResponse)msg); + } + }); + } else { + _proxyListener.onUnsubscribeButtonResponse((UnsubscribeButtonResponse)msg); + } + } else if (functionName.equals(Names.SetMediaClockTimer)) { + // SetMediaClockTimer + + final SetMediaClockTimerResponse msg = new SetMediaClockTimerResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSetMediaClockTimerResponse((SetMediaClockTimerResponse)msg); + } + }); + } else { + _proxyListener.onSetMediaClockTimerResponse((SetMediaClockTimerResponse)msg); + } + } else if (functionName.equals(Names.EncodedSyncPData)) { + // EncodedSyncPData + + final EncodedSyncPDataResponse msg = new EncodedSyncPDataResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onEncodedSyncPDataResponse(msg); + } + }); + } else { + _proxyListener.onEncodedSyncPDataResponse(msg); + } + } else if (functionName.equals(Names.CreateInteractionChoiceSet)) { + // CreateInteractionChoiceSet + + final CreateInteractionChoiceSetResponse msg = new CreateInteractionChoiceSetResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onCreateInteractionChoiceSetResponse((CreateInteractionChoiceSetResponse)msg); + } + }); + } else { + _proxyListener.onCreateInteractionChoiceSetResponse((CreateInteractionChoiceSetResponse)msg); + } + } else if (functionName.equals(Names.DeleteInteractionChoiceSet)) { + // DeleteInteractionChoiceSet + + final DeleteInteractionChoiceSetResponse msg = new DeleteInteractionChoiceSetResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDeleteInteractionChoiceSetResponse((DeleteInteractionChoiceSetResponse)msg); + } + }); + } else { + _proxyListener.onDeleteInteractionChoiceSetResponse((DeleteInteractionChoiceSetResponse)msg); + } + } else if (functionName.equals(Names.PerformInteraction)) { + // PerformInteraction + + final PerformInteractionResponse msg = new PerformInteractionResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onPerformInteractionResponse((PerformInteractionResponse)msg); + } + }); + } else { + _proxyListener.onPerformInteractionResponse((PerformInteractionResponse)msg); + } + } else if (functionName.equals(Names.SetGlobalProperties)) { + // SetGlobalPropertiesResponse (can also be Heartbeat) + + final SetGlobalPropertiesResponse msg = new SetGlobalPropertiesResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSetGlobalPropertiesResponse((SetGlobalPropertiesResponse)msg); + } + }); + } else { + _proxyListener.onSetGlobalPropertiesResponse((SetGlobalPropertiesResponse)msg); + } + } else if (functionName.equals(Names.ResetGlobalProperties)) { + // ResetGlobalProperties + + final ResetGlobalPropertiesResponse msg = new ResetGlobalPropertiesResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onResetGlobalPropertiesResponse((ResetGlobalPropertiesResponse)msg); + } + }); + } else { + _proxyListener.onResetGlobalPropertiesResponse((ResetGlobalPropertiesResponse)msg); + } + } else if (functionName.equals(Names.UnregisterAppInterface)) { + // UnregisterAppInterface + + _appInterfaceRegisterd = false; + synchronized(APP_INTERFACE_REGISTERED_LOCK) { + APP_INTERFACE_REGISTERED_LOCK.notify(); + } + + final UnregisterAppInterfaceResponse msg = new UnregisterAppInterfaceResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + ((IProxyListener)_proxyListener).onUnregisterAppInterfaceResponse(msg); + } + }); + } else { + ((IProxyListener)_proxyListener).onUnregisterAppInterfaceResponse(msg); + } + + notifyProxyClosed("UnregisterAppInterfaceResponse", null); + } else if (functionName.equals(Names.GenericResponse)) { + // GenericResponse (Usually and error) + final GenericResponse msg = new GenericResponse(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGenericResponse((GenericResponse)msg); + } + }); + } else { + _proxyListener.onGenericResponse((GenericResponse)msg); + } + } else { + if (_SyncMsgVersion != null) { + DebugTool.logError("Unrecognized response Message: " + functionName.toString() + + "SmartDeviceLink Message Version = " + _SyncMsgVersion); + } else { + DebugTool.logError("Unrecognized response Message: " + functionName.toString()); + } + } // end-if + } else if (messageType.equals(Names.notification)) { + SyncTrace.logRPCEvent(InterfaceActivityDirection.Receive, new RPCNotification(rpcMsg), SMARTDEVICELINK_LIB_TRACE_KEY); + if (functionName.equals(Names.OnHMIStatus)) { + // OnHMIStatus + + final OnHMIStatus msg = new OnHMIStatus(hash); + msg.setFirstRun(new Boolean(firstTimeFull)); + if (msg.getHmiLevel() == HMILevel.HMI_FULL) firstTimeFull = false; + + if (msg.getHmiLevel() != _priorHmiLevel && msg.getAudioStreamingState() != _priorAudioStreamingState) { + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnHMIStatus((OnHMIStatus)msg); + } + }); + } else { + _proxyListener.onOnHMIStatus((OnHMIStatus)msg); + } + } + } else if (functionName.equals(Names.OnCommand)) { + // OnCommand + + final OnCommand msg = new OnCommand(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnCommand((OnCommand)msg); + } + }); + } else { + _proxyListener.onOnCommand((OnCommand)msg); + } + } else if (functionName.equals(Names.OnDriverDistraction)) { + // OnDriverDistration + + final OnDriverDistraction msg = new OnDriverDistraction(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnDriverDistraction(msg); + } + }); + } else { + _proxyListener.onOnDriverDistraction(msg); + } + } else if (functionName.equals(Names.OnEncodedSyncPData)) { + // OnEncodedSyncPData + + final OnEncodedSyncPData msg = new OnEncodedSyncPData(hash); + + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnEncodedSyncPData(msg); + } + }); + } else { + _proxyListener.onOnEncodedSyncPData(msg); + } + } else if (functionName.equals(Names.OnPermissionsChange)) { + //OnPermissionsChange + + final OnPermissionsChange msg = new OnPermissionsChange(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnPermissionsChange(msg); + } + }); + } else { + _proxyListener.onOnPermissionsChange(msg); + } + } else if (functionName.equals(Names.OnTBTClientState)) { + // OnTBTClientState + + final OnTBTClientState msg = new OnTBTClientState(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnTBTClientState(msg); + } + }); + } else { + _proxyListener.onOnTBTClientState(msg); + } + } else if (functionName.equals(Names.OnButtonPress)) { + // OnButtonPress + + final OnButtonPress msg = new OnButtonPress(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnButtonPress((OnButtonPress)msg); + } + }); + } else { + _proxyListener.onOnButtonPress((OnButtonPress)msg); + } + } else if (functionName.equals(Names.OnButtonEvent)) { + // OnButtonEvent + + final OnButtonEvent msg = new OnButtonEvent(hash); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnButtonEvent((OnButtonEvent)msg); + } + }); + } else { + _proxyListener.onOnButtonEvent((OnButtonEvent)msg); + } + } else if (functionName.equals(Names.OnAppInterfaceUnregistered)) { + // OnAppInterfaceUnregistered + + _appInterfaceRegisterd = false; + synchronized(APP_INTERFACE_REGISTERED_LOCK) { + APP_INTERFACE_REGISTERED_LOCK.notify(); + } + + final OnAppInterfaceUnregistered msg = new OnAppInterfaceUnregistered(hash); + + if (_advancedLifecycleManagementEnabled) { + // This requires the proxy to be cycled + cycleProxy(SmartDeviceLinkDisconnectedReason.convertAppInterfaceUnregisteredReason(msg.getReason())); + } else { + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + ((IProxyListener)_proxyListener).onOnAppInterfaceUnregistered(msg); + } + }); + } else { + ((IProxyListener)_proxyListener).onOnAppInterfaceUnregistered(msg); + } + + notifyProxyClosed("OnAppInterfaceUnregistered", null); + } + } + else { + if (_SyncMsgVersion != null) { + DebugTool.logInfo("Unrecognized notification Message: " + functionName.toString() + + " connected to SmartDeviceLink using message version: " + _SyncMsgVersion.getMajorVersion() + "." + _SyncMsgVersion.getMinorVersion()); + } else { + DebugTool.logInfo("Unrecognized notification Message: " + functionName.toString()); + } + } // end-if + } // end-if notification + + SyncTrace.logProxyEvent("Proxy received RPC Message: " + functionName, SMARTDEVICELINK_LIB_TRACE_KEY); + } + + /** + * Takes an RPCRequest and sends it to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param msg + * @throws SmartDeviceLinkException + */ + public void sendRPCRequest(RPCRequest request) throws SmartDeviceLinkException { + if (_proxyDisposed) { + throw new SmartDeviceLinkException("This object has been disposed, it is no long capable of executing methods.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_PROXY_DISPOSED); + } + + // Test if request is null + if (request == null) { + SyncTrace.logProxyEvent("Application called sendRPCRequest method with a null RPCRequest.", SMARTDEVICELINK_LIB_TRACE_KEY); + throw new IllegalArgumentException("sendRPCRequest cannot be called with a null request."); + } + + SyncTrace.logProxyEvent("Application called sendRPCRequest method for RPCRequest: ." + request.getFunctionName(), SMARTDEVICELINK_LIB_TRACE_KEY); + + // Test if SmartDeviceLinkConnection is null + synchronized(CONNECTION_REFERENCE_LOCK) { + if (_SmartDeviceLinkConnection == null || !_SmartDeviceLinkConnection.getIsConnected()) { + SyncTrace.logProxyEvent("Application attempted to send and RPCRequest without a connected transport.", SMARTDEVICELINK_LIB_TRACE_KEY); + throw new SmartDeviceLinkException("There is no valid connection to SmartDeviceLink. sendRPCRequest cannot be called until SmartDeviceLink has been connected.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + } + + // Test for illegal correlation ID + if (isCorrelationIDProtected(request.getCorrelationID())) { + + SyncTrace.logProxyEvent("Application attempted to use the reserved correlation ID, " + request.getCorrelationID(), SMARTDEVICELINK_LIB_TRACE_KEY); + throw new SmartDeviceLinkException("Invalid correlation ID. The correlation ID, " + request.getCorrelationID() + + " , is a reserved correlation ID.", SmartDeviceLinkExceptionCause.RESERVED_CORRELATION_ID); + } + + // Throw exception if RPCRequest is sent when SmartDeviceLink is unavailable + if (!_appInterfaceRegisterd && request.getFunctionName() != Names.RegisterAppInterface) { + + SyncTrace.logProxyEvent("Application attempted to send an RPCRequest (non-registerAppInterface), before the interface was registerd.", SMARTDEVICELINK_LIB_TRACE_KEY); + throw new SmartDeviceLinkException("SmartDeviceLink is currently unavailable. RPC Requests cannot be sent.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_UNAVAILALBE); + } + + if (_advancedLifecycleManagementEnabled) { + if ( request.getFunctionName() == Names.RegisterAppInterface + || request.getFunctionName() == Names.UnregisterAppInterface) { + + SyncTrace.logProxyEvent("Application attempted to send a RegisterAppInterface or UnregisterAppInterface while using ALM.", SMARTDEVICELINK_LIB_TRACE_KEY); + throw new SmartDeviceLinkException("The RPCRequest, " + request.getFunctionName() + + ", is unnallowed using the Advanced Lifecycle Management Model.", SmartDeviceLinkExceptionCause.INCORRECT_LIFECYCLE_MODEL); + } + } + + sendRPCRequestPrivate(request); + } // end-method + + public void sendRPCRequest(RPCMessage request) throws SmartDeviceLinkException { + sendRPCRequest((RPCRequest) request); + } + + protected void notifyProxyClosed(final String info, final Exception e) { + SyncTrace.logProxyEvent("NotifyProxyClose", SMARTDEVICELINK_LIB_TRACE_KEY); + + OnProxyClosed message = new OnProxyClosed(info, e); + queueInternalMessage(message); + } + + private void passErrorToProxyListener(final String info, final Exception e) { + + OnError message = new OnError(info, e); + queueInternalMessage(message); + } + + private void startRPCProtocolSession(byte sessionID, String correlationID) { + _rpcSessionID = sessionID; + + // Set Proxy Lifecyclek Available + if (_advancedLifecycleManagementEnabled) { + + try { + registerAppInterfacePrivate( + _SyncMsgVersionRequest, + _applicationName, + _ngnMediaScreenAppName, + _vrSynonyms, + _isMediaApp, + _SmartDeviceLinkLanguageDesired, + _autoActivateIdDesired, + REGISTER_APP_INTERFACE_CORRELATION_ID); + + } catch (Exception e) { + notifyProxyClosed("Failed to register application interface with SmartDeviceLink. Check parameter values given to SmartDeviceLinkProxy constructor.", e); + } + } else { + InternalProxyMessage message = new InternalProxyMessage(Names.OnProxyOpened); + queueInternalMessage(message); + } + } + + // Queue internal callback message + private void queueInternalMessage(InternalProxyMessage message) { + synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) { + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.queueMessage(message); + } + } + } + + // Queue incoming ProtocolMessage + private void queueIncomingMessage(ProtocolMessage message) { + synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) { + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.queueMessage(message); + } + } + } + + /******************** Public Helper Methods *************************/ + + /** + *Sends an AddCommand RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + *@param commandID + *@param menuText + *@param parentID + *@param position + *@param vrCommands + *@param correlationID + *@throws SmartDeviceLinkException + */ + public void addCommand(Integer commandID, + String menuText, Integer parentID, Integer position, + Vector<String> vrCommands, Integer correlationID) + throws SmartDeviceLinkException { + + AddCommand msg = RPCRequestFactory.buildAddCommand(commandID, menuText, parentID, position, + vrCommands, correlationID); + + sendRPCRequest(msg); + } + + /** + *Sends an AddCommand RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + *@param commandID + *@param menuText + *@param position + *@param vrCommands + *@param correlationID + *@throws SmartDeviceLinkException + */ + public void addCommand(Integer commandID, + String menuText, Integer position, + Vector<String> vrCommands, Integer correlationID) + throws SmartDeviceLinkException { + + addCommand(commandID, menuText, null, position, vrCommands, correlationID); + } + + /** + *Sends an AddCommand RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + *@param commandID + *@param menuText + *@param position + *@param correlationID + *@throws SmartDeviceLinkException + */ + public void addCommand(Integer commandID, + String menuText, Integer position, + Integer correlationID) + throws SmartDeviceLinkException { + + addCommand(commandID, menuText, null, position, null, correlationID); + } + + /** + *Sends an AddCommand RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + *@param commandID + *@param menuText + *@param correlationID + *@throws SmartDeviceLinkException + */ + public void addCommand(Integer commandID, + String menuText, Integer correlationID) + throws SmartDeviceLinkException { + + addCommand(commandID, menuText, null, null, null, correlationID); + } + + /** + * Sends an AddCommand RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param commandID + * @param menuText + * @param vrCommands + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void addCommand(Integer commandID, + String menuText, Vector<String> vrCommands, Integer correlationID) + throws SmartDeviceLinkException { + + addCommand(commandID, menuText, null, null, vrCommands, correlationID); + } + + /** + * Sends an AddCommand RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param commandID + * @param vrCommands + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void addCommand(Integer commandID, + Vector<String> vrCommands, Integer correlationID) + throws SmartDeviceLinkException { + + addCommand(commandID, null, null, null, vrCommands, correlationID); + } + + /** + * Sends an AddSubMenu RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param menuID + * @param menuName + * @param position + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void addSubMenu(Integer menuID, String menuName, + Integer position, Integer correlationID) + throws SmartDeviceLinkException { + + AddSubMenu msg = RPCRequestFactory.buildAddSubMenu(menuID, menuName, + position, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends an AddSubMenu RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param menuID + * @param menuName + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void addSubMenu(Integer menuID, String menuName, + Integer correlationID) throws SmartDeviceLinkException { + + addSubMenu(menuID, menuName, null, correlationID); + } + + /** + * Sends an EncodedData RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param data + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void encodedSmartDeviceLinkPData(Vector<String> data, Integer correlationID) + throws SmartDeviceLinkException { + + EncodedSyncPData msg = RPCRequestFactory.buildEncodedSyncPData(data, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends an Alert RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param ttsText + * @param alertText1 + * @param alertText2 + * @param playTone + * @param duration + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void alert(String ttsText, String alertText1, + String alertText2, Boolean playTone, Integer duration, + Integer correlationID) throws SmartDeviceLinkException { + + Alert msg = RPCRequestFactory.buildAlert(ttsText, alertText1, alertText2, + playTone, duration, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends an Alert RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param ttsChunks + * @param alertText1 + * @param alertText2 + * @param playTone + * @param duration + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void alert(Vector<TTSChunk> ttsChunks, + String alertText1, String alertText2, Boolean playTone, + Integer duration, Integer correlationID) throws SmartDeviceLinkException { + + Alert msg = RPCRequestFactory.buildAlert(ttsChunks, alertText1, alertText2, playTone, + duration, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends an Alert RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param ttsText + * @param playTone + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void alert(String ttsText, Boolean playTone, + Integer correlationID) throws SmartDeviceLinkException { + + alert(ttsText, null, null, playTone, null, correlationID); + } + + /** + * Sends an Alert RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param chunks + * @param playTone + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void alert(Vector<TTSChunk> chunks, Boolean playTone, + Integer correlationID) throws SmartDeviceLinkException { + + alert(chunks, null, null, playTone, null, correlationID); + } + + /** + * Sends an Alert RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param alertText1 + * @param alertText2 + * @param playTone + * @param duration + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void alert(String alertText1, String alertText2, + Boolean playTone, Integer duration, Integer correlationID) + throws SmartDeviceLinkException { + + alert((Vector<TTSChunk>)null, alertText1, alertText2, playTone, duration, correlationID); + } + + /** + * Sends a CreateInteractionChoiceSet RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param choiceSet + * @param interactionChoiceSetID + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void createInteractionChoiceSet( + Vector<Choice> choiceSet, Integer interactionChoiceSetID, + Integer correlationID) throws SmartDeviceLinkException { + + CreateInteractionChoiceSet msg = RPCRequestFactory.buildCreateInteractionChoiceSet( + choiceSet, interactionChoiceSetID, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a DeleteCommand RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param commandID + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void deleteCommand(Integer commandID, + Integer correlationID) throws SmartDeviceLinkException { + + DeleteCommand msg = RPCRequestFactory.buildDeleteCommand(commandID, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a DeleteInteractionChoiceSet RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param interactionChoiceSetID + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void deleteInteractionChoiceSet( + Integer interactionChoiceSetID, Integer correlationID) + throws SmartDeviceLinkException { + + DeleteInteractionChoiceSet msg = RPCRequestFactory.buildDeleteInteractionChoiceSet( + interactionChoiceSetID, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a DeleteSubMenu RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param menuID + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void deleteSubMenu(Integer menuID, + Integer correlationID) throws SmartDeviceLinkException { + + DeleteSubMenu msg = RPCRequestFactory.buildDeleteSubMenu(menuID, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param initPrompt + * @param displayText + * @param interactionChoiceSetID + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void performInteraction(String initPrompt, + String displayText, Integer interactionChoiceSetID, + Integer correlationID) throws SmartDeviceLinkException { + + PerformInteraction msg = RPCRequestFactory.buildPerformInteraction(initPrompt, + displayText, interactionChoiceSetID, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param initPrompt + * @param displayText + * @param interactionChoiceSetID + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void performInteraction(String initPrompt, + String displayText, Integer interactionChoiceSetID, + String helpPrompt, String timeoutPrompt, + InteractionMode interactionMode, Integer timeout, + Integer correlationID) throws SmartDeviceLinkException { + + PerformInteraction msg = RPCRequestFactory.buildPerformInteraction( + initPrompt, displayText, interactionChoiceSetID, + helpPrompt, timeoutPrompt, interactionMode, + timeout, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param initPrompt + * @param displayText + * @param interactionChoiceSetIDList + * @param helpPrompt + * @param timeoutPrompt + * @param interactionMode + * @param timeout + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void performInteraction(String initPrompt, + String displayText, Vector<Integer> interactionChoiceSetIDList, + String helpPrompt, String timeoutPrompt, + InteractionMode interactionMode, Integer timeout, + Integer correlationID) throws SmartDeviceLinkException { + + PerformInteraction msg = RPCRequestFactory.buildPerformInteraction(initPrompt, + displayText, interactionChoiceSetIDList, + helpPrompt, timeoutPrompt, interactionMode, timeout, + correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param initChunks + * @param displayText + * @param interactionChoiceSetIDList + * @param helpChunks + * @param timeoutChunks + * @param interactionMode + * @param timeout + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void performInteraction( + Vector<TTSChunk> initChunks, String displayText, + Vector<Integer> interactionChoiceSetIDList, + Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, + InteractionMode interactionMode, Integer timeout, + Integer correlationID) throws SmartDeviceLinkException { + + PerformInteraction msg = RPCRequestFactory.buildPerformInteraction( + initChunks, displayText, interactionChoiceSetIDList, + helpChunks, timeoutChunks, interactionMode, timeout, + correlationID); + + sendRPCRequest(msg); + } + + // Protected registerAppInterface used to ensure only non-ALM applications call + // reqisterAppInterface + protected void registerAppInterfacePrivate( + SyncMsgVersion SyncMsgVersion, String appName, String ngnMediaScreenAppName, + Vector<String> vrSynonyms, Boolean isMediaApp, Language languageDesired, + String autoActivateID, Integer correlationID) + throws SmartDeviceLinkException { + + RegisterAppInterface msg = RPCRequestFactory.buildRegisterAppInterface( + SyncMsgVersion, appName, ngnMediaScreenAppName, vrSynonyms, isMediaApp, + languageDesired, autoActivateID, correlationID); + + sendRPCRequestPrivate(msg); + } + + /** + * Sends a SetGlobalProperties RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param helpPrompt + * @param timeoutPrompt + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void setGlobalProperties( + String helpPrompt, String timeoutPrompt, Integer correlationID) + throws SmartDeviceLinkException { + + SetGlobalProperties req = RPCRequestFactory.buildSetGlobalProperties(helpPrompt, + timeoutPrompt, correlationID); + + sendRPCRequest(req); + } + + /** + * Sends a SetGlobalProperties RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param helpChunks + * @param timeoutChunks + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void setGlobalProperties( + Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, + Integer correlationID) throws SmartDeviceLinkException { + + SetGlobalProperties req = RPCRequestFactory.buildSetGlobalProperties( + helpChunks, timeoutChunks, correlationID); + + sendRPCRequest(req); + } + + public void resetGlobalProperties(Vector<GlobalProperty> properties, + Integer correlationID) throws SmartDeviceLinkException { + + ResetGlobalProperties req = new ResetGlobalProperties(); + + req.setCorrelationID(correlationID); + req.setProperties(properties); + + sendRPCRequest(req); + } + + + /** + * Sends a SetMediaClockTimer RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param hours + * @param minutes + * @param seconds + * @param updateMode + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void setMediaClockTimer(Integer hours, + Integer minutes, Integer seconds, UpdateMode updateMode, + Integer correlationID) throws SmartDeviceLinkException { + + SetMediaClockTimer msg = RPCRequestFactory.buildSetMediaClockTimer(hours, + minutes, seconds, updateMode, correlationID); + + sendRPCRequest(msg); + } + + /** + * Pauses the media clock. Responses are captured through callback on IProxyListener. + * + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void pauseMediaClockTimer(Integer correlationID) + throws SmartDeviceLinkException { + + SetMediaClockTimer msg = RPCRequestFactory.buildSetMediaClockTimer(0, + 0, 0, UpdateMode.PAUSE, correlationID); + + sendRPCRequest(msg); + } + + /** + * Resumes the media clock. Responses are captured through callback on IProxyListener. + * + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void resumeMediaClockTimer(Integer correlationID) + throws SmartDeviceLinkException { + + SetMediaClockTimer msg = RPCRequestFactory.buildSetMediaClockTimer(0, + 0, 0, UpdateMode.RESUME, correlationID); + + sendRPCRequest(msg); + } + + /** + * Clears the media clock. Responses are captured through callback on IProxyListener. + * + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void clearMediaClockTimer(Integer correlationID) + throws SmartDeviceLinkException { + + Show msg = RPCRequestFactory.buildShow(null, null, null, " ", null, null, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a Show RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param mainText1 + * @param mainText2 + * @param statusBar + * @param mediaClock + * @param mediaTrack + * @param alignment + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void show(String mainText1, String mainText2, + String statusBar, String mediaClock, String mediaTrack, + TextAlignment alignment, Integer correlationID) + throws SmartDeviceLinkException { + + Show msg = RPCRequestFactory.buildShow(mainText1, mainText2, + statusBar, mediaClock, mediaTrack, + alignment, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a Show RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param mainText1 + * @param mainText2 + * @param alignment + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void show(String mainText1, String mainText2, + TextAlignment alignment, Integer correlationID) + throws SmartDeviceLinkException { + + show(mainText1, mainText2, null, null, null, alignment, correlationID); + } + + /** + * Sends a Speak RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param ttsText + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void speak(String ttsText, Integer correlationID) + throws SmartDeviceLinkException { + + Speak msg = RPCRequestFactory.buildSpeak(TTSChunkFactory.createSimpleTTSChunks(ttsText), + correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a Speak RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param ttsChunks + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void speak(Vector<TTSChunk> ttsChunks, + Integer correlationID) throws SmartDeviceLinkException { + + Speak msg = RPCRequestFactory.buildSpeak(ttsChunks, correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a SubscribeButton RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param buttonName + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void subscribeButton(ButtonName buttonName, + Integer correlationID) throws SmartDeviceLinkException { + + SubscribeButton msg = RPCRequestFactory.buildSubscribeButton(buttonName, + correlationID); + + sendRPCRequest(msg); + } + + // Protected unregisterAppInterface used to ensure no non-ALM app calls + // unregisterAppInterface. + protected void unregisterAppInterfacePrivate(Integer correlationID) + throws SmartDeviceLinkException { + + UnregisterAppInterface msg = + RPCRequestFactory.buildUnregisterAppInterface(correlationID); + + sendRPCRequestPrivate(msg); + } + + /** + * Sends an UnsubscribeButton RPCRequest to SmartDeviceLink. Responses are captured through callback on IProxyListener. + * + * @param buttonName + * @param correlationID + * @throws SmartDeviceLinkException + */ + public void unsubscribeButton(ButtonName buttonName, + Integer correlationID) throws SmartDeviceLinkException { + + UnsubscribeButton msg = RPCRequestFactory.buildUnsubscribeButton( + buttonName, correlationID); + + sendRPCRequest(msg); + } + + /** + * Creates a choice to be added to a choiceset. Choice has both a voice and a visual menu component. + * + * @param choiceID -Unique ID used to identify this choice (returned in callback). + * @param choiceMenuName -Text name displayed for this choice. + * @param choiceVrCommands -Vector of vrCommands used to select this choice by voice. Must contain + * at least one non-empty element. + * @return Choice created. + * @throws SmartDeviceLinkException + */ + public Choice createChoiceSetChoice(Integer choiceID, String choiceMenuName, + Vector<String> choiceVrCommands) { + Choice returnChoice = new Choice(); + + returnChoice.setChoiceID(choiceID); + returnChoice.setMenuName(choiceMenuName); + returnChoice.setVrCommands(choiceVrCommands); + + return returnChoice; + } + + /******************** END Public Helper Methods *************************/ + + public TransportType getCurrentTransportType() throws IllegalStateException { + if (_SmartDeviceLinkConnection == null) { + throw new IllegalStateException("Incorrect state of SmartDeviceLinkProxyBase: Calling for getCurrentTransportType() while connection is not initialized"); + } + + return _SmartDeviceLinkConnection.getCurrentTransportType(); + } +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyConfigurationResources.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyConfigurationResources.java new file mode 100755 index 000000000..55bd304d7 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyConfigurationResources.java @@ -0,0 +1,37 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import android.telephony.TelephonyManager; + +public class SmartDeviceLinkProxyConfigurationResources { + private String _SmartDeviceLinkConfigurationFilePath; + private TelephonyManager _telephonyManager; + + public SmartDeviceLinkProxyConfigurationResources() { + this(null, null); + } + + public SmartDeviceLinkProxyConfigurationResources(String SmartDeviceLinkConfigurationFilePath, + TelephonyManager telephonyManager) { + _SmartDeviceLinkConfigurationFilePath = SmartDeviceLinkConfigurationFilePath; + _telephonyManager = telephonyManager; + } + + public void setSmartDeviceLinkConfigurationFilePath(String SmartDeviceLinkConfigurationFilePath) { + _SmartDeviceLinkConfigurationFilePath = SmartDeviceLinkConfigurationFilePath; + } + + public String getSmartDeviceLinkConfigurationFilePath() { + return _SmartDeviceLinkConfigurationFilePath; + } + + public void setTelephonyManager(TelephonyManager telephonyManager) { + _telephonyManager = telephonyManager; + } + + public TelephonyManager getTelephonyManager() { + return _telephonyManager; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyFactory.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyFactory.java new file mode 100755 index 000000000..51f407e58 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/SmartDeviceLinkProxyFactory.java @@ -0,0 +1,19 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import com.smartdevicelink.exception.SmartDeviceLinkException; + +public class SmartDeviceLinkProxyFactory { + + public static SmartDeviceLinkProxy buildSmartDeviceLinkProxy(IProxyListener listener) { + SmartDeviceLinkProxy ret = null; + try { + ret = new SmartDeviceLinkProxy(listener); + } catch (SmartDeviceLinkException e) { + e.printStackTrace(); + } + return ret; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/TTSChunkFactory.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/TTSChunkFactory.java new file mode 100755 index 000000000..b16cd0ba3 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/TTSChunkFactory.java @@ -0,0 +1,42 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +import java.util.Vector; + +import com.smartdevicelink.proxy.rpc.TTSChunk; +import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities; + +public class TTSChunkFactory { + + public static TTSChunk createChunk(SpeechCapabilities type, String text) { + TTSChunk ret = new TTSChunk(); + ret.setType(type); + ret.setText(text); + return ret; + } + + public static Vector<TTSChunk> createSimpleTTSChunks(String simple) { + if (simple == null) { + return null; + } + + Vector<TTSChunk> chunks = new Vector<TTSChunk>(); + + TTSChunk chunk = createChunk(SpeechCapabilities.TEXT, simple); + chunks.add(chunk); + return chunks; + } + + public static Vector<TTSChunk> createPrerecordedTTSChunks(String prerecorded) { + if (prerecorded == null) { + return null; + } + + Vector<TTSChunk> chunks = new Vector<TTSChunk>(); + TTSChunk chunk = createChunk(SpeechCapabilities.PRE_RECORDED, prerecorded); + chunks.add(chunk); + return chunks; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/Version.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/Version.java new file mode 100755 index 000000000..b1712bdaa --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/Version.java @@ -0,0 +1,8 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy; + +public class Version { + public static final String VERSION = "MAJOR.MINOR.YYMMDD.#_FOR_DAY"; +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/InternalProxyMessage.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/InternalProxyMessage.java new file mode 100755 index 000000000..3d35a504d --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/InternalProxyMessage.java @@ -0,0 +1,16 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.callbacks; + +public class InternalProxyMessage { + private String _functionName; + + public InternalProxyMessage(String functionName) { + this._functionName = functionName; + } + + public String getFunctionName() { + return _functionName; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnError.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnError.java new file mode 100755 index 000000000..fff5fefef --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnError.java @@ -0,0 +1,30 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.callbacks; + +import com.smartdevicelink.proxy.constants.Names; + +public class OnError extends InternalProxyMessage { + + private String _info; + private Exception _e; + + public OnError() { + super(Names.OnProxyError); + } + + public OnError(String info, Exception e) { + super(Names.OnProxyError); + this._info = info; + this._e = e; + } + + public String getInfo() { + return _info; + } + + public Exception getException() { + return _e; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnProxyClosed.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnProxyClosed.java new file mode 100755 index 000000000..a5ea6d70a --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnProxyClosed.java @@ -0,0 +1,30 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.callbacks; + +import com.smartdevicelink.proxy.constants.Names; + +public class OnProxyClosed extends InternalProxyMessage { + + private String _info; + private Exception _e; + + public OnProxyClosed() { + super(Names.OnProxyClosed); + } + + public OnProxyClosed(String info, Exception e) { + super(Names.OnProxyClosed); + this._info = info; + this._e = e; + } + + public String getInfo() { + return _info; + } + + public Exception getException() { + return _e; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnProxyOpened.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnProxyOpened.java new file mode 100755 index 000000000..e69f0d17a --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/callbacks/OnProxyOpened.java @@ -0,0 +1,13 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.callbacks; + +import com.smartdevicelink.proxy.constants.Names; + +public class OnProxyOpened extends InternalProxyMessage { + + public OnProxyOpened() { + super(Names.OnProxyOpened); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/constants/Jingles.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/constants/Jingles.java new file mode 100755 index 000000000..bc6060cef --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/constants/Jingles.java @@ -0,0 +1,17 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.constants; + +public class Jingles { + public static final String POSITIVE_JINGLE = "POSITIVE_JINGLE"; + + public static final String NEGATIVE_JINGLE = "NEGATIVE_JINGLE"; + + public static final String INITIAL_JINGLE = "INITIAL_JINGLE"; + + public static final String LISTEN_JINGLE = "LISTEN_JINGLE"; + + public static final String HELP_JINGLE = "HELP_JINGLE"; + +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/constants/Names.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/constants/Names.java new file mode 100755 index 000000000..586111d98 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/constants/Names.java @@ -0,0 +1,299 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.constants; + +public class Names { + public static final String request = "request"; + public static final String response = "response"; + public static final String notification = "notification"; + public static final String function_name = "name"; + public static final String parameters = "parameters"; + public static final String bulkData = "bulkData"; + + public static final String RegisterAppInterface = "RegisterAppInterface"; + public static final String UnregisterAppInterface = "UnregisterAppInterface"; + public static final String Alert = "Alert"; + public static final String Show = "Show"; + public static final String Speak = "Speak"; + public static final String AddCommand = "AddCommand"; + public static final String DeleteCommand = "DeleteCommand"; + public static final String AddSubMenu = "AddSubMenu"; + public static final String DeleteSubMenu = "DeleteSubMenu"; + public static final String CreateInteractionChoiceSet = "CreateInteractionChoiceSet"; + public static final String DeleteInteractionChoiceSet = "DeleteInteractionChoiceSet"; + public static final String PerformInteraction = "PerformInteraction"; + public static final String DialNumber = "DialNumber"; + public static final String EncodedSyncPData = "EncodedSyncPData"; + public static final String SubscribeButton = "SubscribeButton"; + public static final String UnsubscribeButton = "UnsubscribeButton"; + public static final String SubscribeVehicleData = "SubscribeVehicleData"; + public static final String UnsubscribeVehicleData = "UnsubscribeVehicleData"; + public static final String SetMediaClockTimer = "SetMediaClockTimer"; + public static final String SetGlobalProperties = "SetGlobalProperties"; + public static final String GenericResponse = "GenericResponse"; + public static final String ScrollableMessage = "ScrollableMessage"; + public static final String GetDID = "GetDID"; + public static final String GetDTCs = "GetDTCs"; + public static final String ReadDID = "ReadDID"; + public static final String OnVehicleData = "OnVehicleData"; + public static final String GetFile = "GetFile"; + public static final String PutFile = "PutFile"; + public static final String DeleteFile = "DeleteFile"; + public static final String ListFiles = "ListFiles"; + public static final String EndAudioCapture = "EndAudioCapture"; + public static final String GetVehicleData = "GetVehicleData"; + public static final String ResetGlobalProperties = "ResetGlobalProperties"; + public static final String PerformAudioCapture = "PerformAudioCapture"; + public static final String SetAppIcon = "SetAppIcon"; + public static final String ChangeRegistration = "ChangeRegistration"; + public static final String SetDisplayLayout = "SetDisplayLayout"; + public static final String OnLanguageChange = "OnLanguageChange"; + public static final String hmiDisplayLanguage = "hmiDisplayLanguage"; + public static final String displayLayout = "displayLayout"; + public static final String ttsName = "ttsName"; + public static final String hmiDisplayLanguageDesired = "hmiDisplayLanguageDesired"; + public static final String appType = "appType"; + public static final String appID = "appID"; + public static final String vrHelpTitle = "vrHelpTitle"; + public static final String graphic = "graphic"; + public static final String customPresets = "customPresets"; + public static final String softButtonCapabilities = "softButtonCapabilities"; + public static final String presetBankCapabilities = "presetBankCapabilities"; + public static final String vehicleType = "vehicleType"; + public static final String make = "make"; + public static final String model = "model"; + public static final String modelYear = "modelYear"; + public static final String trim = "trim"; + public static final String allowed = "allowed"; + public static final String userDisallowed = "userDisallowed"; + public static final String rpcName = "rpcName"; + public static final String hmiPermissions = "hmiPermissions"; + public static final String parameterPermissions = "parameterPermissions"; + public static final String permissionItem = "permissionItem"; + public static final String numTicks = "numTicks"; + public static final String sliderHeader = "sliderHeader"; + public static final String sliderFooter = "sliderFooter"; + public static final String PerformAudioPassThru = "PerformAudioPassThru"; + public static final String PerformAudioPassThruResponse = "PerformAudioPassThruResponse"; + public static final String EndAudioPassThru = "EndAudioPassThru"; + public static final String EndAudioPassThruResponse = "EndAudioPassThruResponse"; + public static final String OnAudioPassThru = "OnAudioPassThru"; + public static final String ShowConstantTBT = "ShowConstantTBT"; + public static final String AlertManeuver = "AlertManeuver"; + public static final String UpdateTurnList = "UpdateTurnList"; + + public static final String OnCommand = "OnCommand"; + public static final String OnDataPublished = "OnDataPublished"; + public static final String OnButtonPress = "OnButtonPress"; + public static final String OnButtonEvent = "OnButtonEvent"; + public static final String OnHMIStatus = "OnHMIStatus"; + public static final String OnTBTClientState = "OnTBTClientState"; + public static final String OnEncodedSyncPData = "OnEncodedSyncPData"; + public static final String OnDriverDistraction = "OnDriverDistraction"; + public static final String OnAppInterfaceUnregistered = "OnAppInterfaceUnregistered"; + public static final String OnProxyClosed = "OnProxyClosed"; + public static final String OnProxyError = "OnProxyError"; + public static final String OnProxyOpened = "OnProxyOpened"; + public static final String OnProxyUnusable = "OnProxyUnusable"; + public static final String OnHMILevelChange = "OnHMILevelChange"; + public static final String OnSyncChoiceChosen = "OnSyncChoiceChosen"; + public static final String OnPermissionsChange = "OnPermissionsChange"; + public static final String OnScreenPresetsAvailable = "OnScreenPresetsAvailable"; + public static final String isHighlighted = "isHighlighted"; + public static final String softButtonID = "softButtonID"; + public static final String fileType = "fileType"; + public static final String persistentFile = "persistentFile"; + public static final String spaceAvailable = "spaceAvailable"; + public static final String filenames = "filenames"; + public static final String cmdIcon = "cmdIcon"; + public static final String Slider = "Slider"; + public static final String sliderPosition = "sliderPosition"; + public static final String samplingRate = "samplingRate"; + public static final String audioType = "audioType"; + public static final String satRadioESN = "satRadioESN"; + public static final String encrypted = "encrypted"; + public static final String dtcList = "dtcList"; + public static final String tryAgainTime = "tryAgainTime"; + + public static final String success = "success"; + public static final String resultCode = "resultCode"; + public static final String info = "info"; + + public static final String fordURL = "fordURL"; + public static final String payload = "payload"; + public static final String reason = "reason"; + public static final String state = "state"; + public static final String cmdID = "cmdID"; + public static final String menuParams = "menuParams"; + public static final String parentID = "parentID"; + public static final String position = "position"; + public static final String menuName = "menuName"; + public static final String vrCommands = "vrCommands"; + public static final String language = "language"; + public static final String languageDesired = "languageDesired"; + public static final String triggerSource = "triggerSource"; + public static final String subscriptionType = "subscriptionType"; + public static final String data = "data"; + public static final String correlationID = "correlationID"; + public static final String syncMsgVersion = "syncMsgVersion"; + public static final String majorVersion = "majorVersion"; + public static final String minorVersion = "minorVersion"; + public static final String appName = "appName"; + public static final String ngnMediaScreenAppName = "ngnMediaScreenAppName"; + public static final String isMediaApplication = "isMediaApplication"; + public static final String vrSynonyms = "vrSynonyms"; + public static final String usesVehicleData = "usesVehicleData"; + public static final String text = "text"; + public static final String type = "type"; + public static final String ttsChunks = "ttsChunks"; + public static final String playTone = "playTone"; + public static final String duration = "duration"; + public static final String mainField1 = "mainField1"; + public static final String mainField2 = "mainField2"; + public static final String mainField3 = "mainField3"; + public static final String mainField4 = "mainField4"; + public static final String statusBar = "statusBar"; + public static final String name = "name"; + public static final String menuID = "menuID"; + public static final String longPress = "longPress"; + public static final String shortPress = "shortPress"; + public static final String buttonName = "buttonName"; + public static final String buttonPressMode = "buttonPressMode"; + public static final String buttonEventMode = "buttonEventMode"; + public static final String minutes = "minutes"; + public static final String seconds = "seconds"; + public static final String startTime = "startTime"; + public static final String updateMode = "updateMode"; + public static final String mediaClock = "mediaClock"; + public static final String initialText = "initialText"; + public static final String initialPrompt = "initialPrompt"; + public static final String helpPrompt = "helpPrompt"; + public static final String timeoutPrompt = "timeoutPrompt"; + public static final String timeout = "timeout"; + public static final String choiceSet = "choiceSet"; + public static final String interactionMode = "interactionMode"; + public static final String result = "result"; + public static final String alertText1 = "alertText1"; + public static final String alertText2 = "alertText2"; + public static final String alertText3 = "alertText3"; + public static final String shortPressAvailable = "shortPressAvailable"; + public static final String longPressAvailable = "longPressAvailable"; + public static final String upDownAvailable = "upDownAvailable"; + public static final String width = "width"; + public static final String height = "height"; + public static final String characterSet = "characterSet"; + public static final String displayType = "displayType"; + public static final String mediaClockFormats = "mediaClockFormats"; + public static final String textFields = "textFields"; + public static final String autoActivateID = "autoActivateID"; + public static final String vehicleDataCapabilities = "vehicleDataCapabilities"; + public static final String speechCapabilities = "speechCapabilities"; + public static final String vrCapabilities = "vrCapabilities"; + public static final String buttonCapabilities = "buttonCapabilities"; + public static final String displayCapabilities = "displayCapabilities"; + public static final String hmiZoneCapabilities = "hmiZoneCapabilities"; + public static final String interactionChoiceSetID = "interactionChoiceSetID"; + public static final String interactionChoiceSetIDList = "interactionChoiceSetIDList"; + public static final String audioFileName = "audioFileName"; + public static final String gpsPositionValid = "gpsPositionValid"; + public static final String longitudeDegrees = "longitudeDegrees"; + public static final String latitudeDegrees = "latitudeDegrees"; + public static final String utcYear = "utcYear"; + public static final String utcMonth = "utcMonth"; + public static final String utcDay = "utcDay"; + public static final String utcHours = "utcHours"; + public static final String utcMinutes = "utcMinutes"; + public static final String utcSeconds = "utcSeconds"; + public static final String compassDirection = "compassDirection"; + public static final String pdop = "pdop"; + public static final String vdop = "vdop"; + public static final String hdop = "hdop"; + public static final String actual = "actual"; + public static final String satellites = "satellites"; + public static final String dimension = "dimension"; + public static final String altitude = "altitude"; + public static final String heading = "heading"; + public static final String speed = "speed"; + public static final String number = "number"; + public static final String SmartDeviceLinkFileName = "SmartDeviceLinkFileName"; + public static final String localFileName = "localFileName"; + public static final String maxDuration = "maxDuration"; + public static final String timerMode = "timerMode"; + public static final String status = "status"; + public static final String pressure = "pressure"; + public static final String hours = "hours"; + public static final String rows = "rows"; + public static final String pressureTellTale = "pressureTellTale"; + public static final String leftFront = "leftFront"; + public static final String rightFront = "rightFront"; + public static final String leftRear = "leftRear"; + public static final String rightRear = "rightRear"; + public static final String innerLeftRear = "innerLeftRear"; + public static final String innerRightRear = "innerRightRear"; + public static final String VehicleData = "VehicleData"; + public static final String alignment = "alignment"; + public static final String mediaTrack = "mediaTrack"; + public static final String properties = "properties"; + public static final String choiceID = "choiceID"; + public static final String bitsPerSample = "bitsPerSample"; + public static final String hmiLevel = "hmiLevel"; + public static final String audioStreamingState = "audioStreamingState"; + public static final String systemContext = "systemContext"; + public static final String SmartDeviceLinkChoice = "SmartDeviceLinkChoice"; + public static final String SmartDeviceLinkCommand = "SmartDeviceLinkCommand"; + public static final String URL = "URL"; + public static final String PermissionGroupName = "PermissionGroupName"; + public static final String PermissionGroupStatus = "PermissionGroupStatus"; + public static final String PermissionGroupItems = "PermissionGroupItems"; + public static final String audioPacket = "audioPacket"; + public static final String audioPassThruDisplayText1 = "audioPassThruDisplayText1"; + public static final String audioPassThruDisplayText2 = "audioPassThruDisplayText2"; + public static final String bitRate = "bitRate"; + public static final String rpm = "rpm"; + public static final String fuelLevel = "fuelLevel"; + public static final String avgFuelEconomy = "avgFuelEconomy"; + public static final String batteryVoltage = "batteryVoltage"; + public static final String externalTemperature = "externalTemperature"; + public static final String vin = "vin"; + public static final String prndl = "prndl"; + public static final String tirePressure = "tirePressure"; + public static final String batteryPackVoltage = "batteryPackVoltage"; + public static final String batteryPackCurrent = "batteryPackCurrent"; + public static final String batteryPackTemperature = "batteryPackTemperature"; + public static final String engineTorque = "engineTorque"; + public static final String odometer = "odometer"; + public static final String tripOdometer = "tripOdometer"; + public static final String genericbinary = "genericbinary"; + public static final String GPSData = "GPSData"; + public static final String gps = "gps"; + public static final String dataType = "dataType"; + public static final String identifier = "identifier"; + public static final String statusByte = "statusByte"; + public static final String dataResult = "dataResult"; + public static final String ecuName = "ecuName"; + public static final String didLocation = "didLocation"; + public static final String value = "value"; + public static final String softButtonName = "softButtonName"; + public static final String imageSupported = "imageSupported"; + public static final String systemAction = "systemAction"; + public static final String image = "image"; + public static final String imageType = "imageType"; + public static final String fileData = "fileData"; + public static final String scrollableMessageBody = "scrollableMessageBody"; + public static final String softButtons = "softButtons"; + public static final String customButtonID = "customButtonID"; + public static final String vrHelp = "vrHelp"; + public static final String customButtonName = "customButtonName"; + public static final String navigationText = "navigationText"; + public static final String turnIcon = "turnIcon"; + public static final String navigationText1 = "navigationText1"; + public static final String navigationText2 = "navigationText2"; + public static final String eta = "eta"; + public static final String totalDistance = "totalDistance"; + public static final String distanceToManeuver = "distanceToManeuver"; + public static final String distanceToManeuverScale = "distanceToManeuverScale"; + public static final String maneuverComplete = "maneuverComplete"; + public static final String turnList = "turnList"; + public static final String Timeout = "Timeout"; +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/interfaces/IProxyListenerALM.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/interfaces/IProxyListenerALM.java new file mode 100755 index 000000000..64177ad14 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/interfaces/IProxyListenerALM.java @@ -0,0 +1,8 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.interfaces; + +public interface IProxyListenerALM extends IProxyListenerBase { + +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java new file mode 100755 index 000000000..c4b50782f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java @@ -0,0 +1,237 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.interfaces; + +import com.smartdevicelink.proxy.rpc.AddCommandResponse; +import com.smartdevicelink.proxy.rpc.AddSubMenuResponse; +import com.smartdevicelink.proxy.rpc.AlertResponse; +import com.smartdevicelink.proxy.rpc.CreateInteractionChoiceSetResponse; +import com.smartdevicelink.proxy.rpc.DeleteCommandResponse; +import com.smartdevicelink.proxy.rpc.DeleteInteractionChoiceSetResponse; +import com.smartdevicelink.proxy.rpc.DeleteSubMenuResponse; +import com.smartdevicelink.proxy.rpc.EncodedSyncPDataResponse; +import com.smartdevicelink.proxy.rpc.GenericResponse; +import com.smartdevicelink.proxy.rpc.OnButtonEvent; +import com.smartdevicelink.proxy.rpc.OnButtonPress; +import com.smartdevicelink.proxy.rpc.OnCommand; +import com.smartdevicelink.proxy.rpc.OnDriverDistraction; +import com.smartdevicelink.proxy.rpc.OnEncodedSyncPData; +import com.smartdevicelink.proxy.rpc.OnHMIStatus; +import com.smartdevicelink.proxy.rpc.OnPermissionsChange; +import com.smartdevicelink.proxy.rpc.OnTBTClientState; +import com.smartdevicelink.proxy.rpc.PerformInteractionResponse; +import com.smartdevicelink.proxy.rpc.ResetGlobalPropertiesResponse; +import com.smartdevicelink.proxy.rpc.SetGlobalPropertiesResponse; +import com.smartdevicelink.proxy.rpc.SetMediaClockTimerResponse; +import com.smartdevicelink.proxy.rpc.ShowResponse; +import com.smartdevicelink.proxy.rpc.SpeakResponse; +import com.smartdevicelink.proxy.rpc.SubscribeButtonResponse; +import com.smartdevicelink.proxy.rpc.UnsubscribeButtonResponse; + + +public interface IProxyListenerBase { + + /** + * onOnHMIStatus being called indicates that there has been an HMI Level change, + * system context change or audio streaming state change. + * + * @param notification - Contains information about the HMI Level, + * system context and audio streaming state. + */ + public void onOnHMIStatus(OnHMIStatus notification); + + /** + * onProxyClosed has different functionality for the different models. + * In the non-ALM model this indicates that the proxy has experienced an unrecoverable error. + * A new proxy object must be initiated to reestablish connection with SmartDeviceLink. + * In the ALM model this indicates that the app is no longer registered with SmartDeviceLink + * All resources on SmartDeviceLink (addCommands and ChoiceSets) have been deleted and will have to be + * recreated upon the next onReadyForInitialization() call-back. + * + * @param info - Includes information about the reason the proxy has been closed. + * @param e - The exception that occurred. + */ + public void onProxyClosed(String info, Exception e); + + /** + * onProxyError() being called indicates that the SmartDeviceLink Proxy experenced an error. + * + * @param info - Includes information about the Exception that occurred. + * @param e - The exception that occurred. + */ + public void onError(String info, Exception e); + + + /** + * onGenericResponse() being called indicates that SmartDeviceLink could not determine the + * type of request it is responding to. This is usually result of an unknown RPC Request + * being sent. + * + * @param response - Includes detailed information about the response. + */ + public void onGenericResponse(GenericResponse response); + + /** + * onOnCommand() being called indicates that the user selected a command on SmartDeviceLink. + * + * @param notification - Contains information about the command chosen. + */ + public void onOnCommand(OnCommand notification); + + /** + * onAddCommandResponse() being called indicates that SmartDeviceLink has responded to + * a request to add a command. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onAddCommandResponse(AddCommandResponse response); + + /** + * onAddSubMenuResponse() being called indicates that SmartDeviceLink has responded to + * a request to add a command. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onAddSubMenuResponse(AddSubMenuResponse response); + + /** + * onCreateInteractionChoiceSetResponse() being called indicates that SmartDeviceLink has + * responded to a request to add an interactionChoiceSet. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onCreateInteractionChoiceSetResponse(CreateInteractionChoiceSetResponse response); + + /** + * onAlertResponse being called indicates that SmartDeviceLink has + * responded to a request to alert the user. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onAlertResponse(AlertResponse response); + + /** + * onDeleteCommandResponse being called indicates that SmartDeviceLink has + * responded to a request to delete a command. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onDeleteCommandResponse(DeleteCommandResponse response); + + /** + * onDeleteCommandResponse being called indicates that SmartDeviceLink has + * responded to a request to delete an interaction choice set. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onDeleteInteractionChoiceSetResponse(DeleteInteractionChoiceSetResponse response); + + /** + * onDeleteCommandResponse being called indicates that SmartDeviceLink has + * responded to a request to delete a submenu. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onDeleteSubMenuResponse(DeleteSubMenuResponse response); + + /** + * onEncodedSyncPDataResponse being called indicates that SmartDeviceLink has + * responded to a request containing encodedSmartDeviceLinkPData. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onEncodedSyncPDataResponse(EncodedSyncPDataResponse response); + + /** + * onPerformInteractionResponse being called indicates that SmartDeviceLink has + * responded to a request to perform an interaction. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onPerformInteractionResponse(PerformInteractionResponse response); + + /** + * onResetGlobalPropertiesResponse being called indicates that SmartDeviceLink has + * responded to a request to reset global properties. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onResetGlobalPropertiesResponse(ResetGlobalPropertiesResponse response); + + /** + * onSetGlobalPropertiesResponse being called indicates that SmartDeviceLink has + * responded to a request to set global properties. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onSetGlobalPropertiesResponse(SetGlobalPropertiesResponse response); + + /** + * onSetMediaClockTimerResponse being called indicates that SmartDeviceLink has + * responded to a request to set the media clock timer. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onSetMediaClockTimerResponse(SetMediaClockTimerResponse response); + + /** + * onShowResponse being called indicates that SmartDeviceLink has + * responded to a request to display information to the user. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onShowResponse(ShowResponse response); + + /** + * onSpeakResponse being called indicates that SmartDeviceLink has + * responded to a request to speak information to the user. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onSpeakResponse(SpeakResponse response); + + /** + * onButtonEvent being called indicates that a button event has occurred. + * + * @param response - Contains information about the notification sent from SmartDeviceLink. + */ + public void onOnButtonEvent(OnButtonEvent notification); + + /** + * onButtonPress being called indicates that SmartDeviceLink has a button has + * been pressed by the user. + * + * @param response - Contains information about the notification sent from SmartDeviceLink. + */ + public void onOnButtonPress(OnButtonPress notification); + + /** + * onSubscribeButtonResponse being called indicates that SmartDeviceLink has + * responded to a request to subscribe to button events and button presses. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onSubscribeButtonResponse(SubscribeButtonResponse response); + + /** + * onUnsubscribeButtonResponse being called indicates that SmartDeviceLink has + * responded to a request to unsubscribe from button events and button presses. + * + * @param response - Contains information about the response sent from SmartDeviceLink. + */ + public void onUnsubscribeButtonResponse(UnsubscribeButtonResponse response); + + /** + * onOnPermissionsChange being called indicates that your app permissions have + * changed due to a policy table change. This can mean your app has received additional + * permissions OR lost permissions. + * + * @param notification - Contains information about the changed permissions. + */ + public void onOnPermissionsChange(OnPermissionsChange notification); + + public void onOnDriverDistraction(OnDriverDistraction notification); + public void onOnEncodedSyncPData(OnEncodedSyncPData notification); + public void onOnTBTClientState(OnTBTClientState notification); +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddCommand.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddCommand.java new file mode 100755 index 000000000..9d150fdfd --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddCommand.java @@ -0,0 +1,60 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class AddCommand extends RPCRequest { + + public AddCommand() { + super("AddCommand"); + } + public AddCommand(Hashtable hash) { + super(hash); + } + public Integer getCmdID() { + return (Integer) parameters.get( Names.cmdID ); + } + public void setCmdID( Integer cmdID ) { + if (cmdID != null) { + parameters.put(Names.cmdID, cmdID ); + } + } + public MenuParams getMenuParams() { + Object obj = parameters.get(Names.menuParams); + if (obj instanceof MenuParams) { + return (MenuParams)obj; + } + else if (obj instanceof Hashtable) { + return new MenuParams((Hashtable)obj); + } + return null; + } + public void setMenuParams( MenuParams menuParams ) { + if (menuParams != null) { + parameters.put(Names.menuParams, menuParams ); + } + } + public Vector<String> getVrCommands() { + if (parameters.get(Names.vrCommands) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.vrCommands); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof String) { + return (Vector<String>)list; + } + } + } + return null; + } + public void setVrCommands( Vector<String> vrCommands ) { + if (vrCommands != null) { + parameters.put(Names.vrCommands, vrCommands ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddCommandResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddCommandResponse.java new file mode 100755 index 000000000..ce3c68121 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddCommandResponse.java @@ -0,0 +1,19 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class AddCommandResponse extends RPCResponse { + + public AddCommandResponse() { + super("AddCommand"); + } + public AddCommandResponse(Hashtable hash) { + super(hash); + } +} + diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddSubMenu.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddSubMenu.java new file mode 100755 index 000000000..67811db4e --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddSubMenu.java @@ -0,0 +1,43 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class AddSubMenu extends RPCRequest { + + public AddSubMenu() { + super("AddSubMenu"); + } + public AddSubMenu(Hashtable hash) { + super(hash); + } + public Integer getMenuID() { + return (Integer) parameters.get( Names.menuID ); + } + public void setMenuID( Integer menuID ) { + if (menuID != null) { + parameters.put(Names.menuID, menuID ); + } + } + public Integer getPosition() { + return (Integer) parameters.get( Names.position ); + } + public void setPosition( Integer position ) { + if (position != null) { + parameters.put(Names.position, position ); + } + } + public String getMenuName() { + return (String) parameters.get( Names.menuName ); + } + public void setMenuName( String menuName ) { + if (menuName != null) { + parameters.put(Names.menuName, menuName ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddSubMenuResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddSubMenuResponse.java new file mode 100755 index 000000000..46982270c --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AddSubMenuResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class AddSubMenuResponse extends RPCResponse { + + public AddSubMenuResponse() { + super("AddSubMenu"); + } + public AddSubMenuResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Alert.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Alert.java new file mode 100755 index 000000000..c626bb52f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Alert.java @@ -0,0 +1,75 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class Alert extends RPCRequest { + + public Alert() { + super("Alert"); + } + public Alert(Hashtable hash) { + super(hash); + } + public String getAlertText1() { + return (String) parameters.get( Names.alertText1 ); + } + public void setAlertText1( String alertText1 ) { + if (alertText1 != null) { + parameters.put(Names.alertText1, alertText1 ); + } + } + public String getAlertText2() { + return (String) parameters.get( Names.alertText2 ); + } + public void setAlertText2( String alertText2 ) { + if (alertText2 != null) { + parameters.put(Names.alertText2, alertText2 ); + } + } + public Vector<TTSChunk> getTtsChunks() { + if (parameters.get(Names.ttsChunks) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.ttsChunks); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof TTSChunk) { + return (Vector<TTSChunk>) list; + } else if (obj instanceof Hashtable) { + Vector<TTSChunk> newList = new Vector<TTSChunk>(); + for (Object hashObj : list) { + newList.add(new TTSChunk((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setTtsChunks( Vector<TTSChunk> ttsChunks ) { + if (ttsChunks != null) { + parameters.put(Names.ttsChunks, ttsChunks ); + } + } + public Integer getDuration() { + return (Integer) parameters.get( Names.duration ); + } + public void setDuration( Integer duration ) { + if (duration != null) { + parameters.put(Names.duration, duration ); + } + } + public Boolean getPlayTone() { + return (Boolean) parameters.get( Names.playTone ); + } + public void setPlayTone( Boolean playTone ) { + if (playTone != null) { + parameters.put(Names.playTone, playTone ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AlertResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AlertResponse.java new file mode 100755 index 000000000..d2a208b68 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/AlertResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class AlertResponse extends RPCResponse { + + public AlertResponse() { + super("Alert"); + } + public AlertResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ButtonCapabilities.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ButtonCapabilities.java new file mode 100755 index 000000000..a16f31c3a --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ButtonCapabilities.java @@ -0,0 +1,63 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.ButtonName; +import com.smartdevicelink.util.DebugTool; + +public class ButtonCapabilities extends RPCStruct { + + public ButtonCapabilities() { } + public ButtonCapabilities(Hashtable hash) { + super(hash); + } + public ButtonName getName() { + Object obj = store.get(Names.name); + if (obj instanceof ButtonName) { + return (ButtonName) obj; + } else if (obj instanceof String) { + ButtonName theCode = null; + try { + theCode = ButtonName.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.name, e); + } + return theCode; + } + return null; + } + public void setName( ButtonName name ) { + if (name != null) { + store.put(Names.name, name ); + } + } + public Boolean getShortPressAvailable() { + return (Boolean) store.get( Names.shortPressAvailable ); + } + public void setShortPressAvailable( Boolean shortPressAvailable ) { + if (shortPressAvailable != null) { + store.put(Names.shortPressAvailable, shortPressAvailable ); + } + } + public Boolean getLongPressAvailable() { + return (Boolean) store.get( Names.longPressAvailable ); + } + public void setLongPressAvailable( Boolean longPressAvailable ) { + if (longPressAvailable != null) { + store.put(Names.longPressAvailable, longPressAvailable ); + } + } + public Boolean getUpDownAvailable() { + return (Boolean) store.get( Names.upDownAvailable ); + } + public void setUpDownAvailable( Boolean upDownAvailable ) { + if (upDownAvailable != null) { + store.put(Names.upDownAvailable, upDownAvailable ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Choice.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Choice.java new file mode 100755 index 000000000..67c211b89 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Choice.java @@ -0,0 +1,51 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; + +public class Choice extends RPCStruct { + + public Choice() { } + public Choice(Hashtable hash) { + super(hash); + } + public Integer getChoiceID() { + return (Integer) store.get( Names.choiceID ); + } + public void setChoiceID( Integer choiceID ) { + if (choiceID != null) { + store.put(Names.choiceID, choiceID ); + } + } + public String getMenuName() { + return (String) store.get( Names.menuName ); + } + public void setMenuName( String menuName ) { + if (menuName != null) { + store.put(Names.menuName, menuName ); + } + } + public Vector<String> getVrCommands() { + if (store.get(Names.vrCommands) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)store.get( Names.vrCommands ); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof String) { + return (Vector<String>) list; + } + } + } + return null; + } + public void setVrCommands( Vector<String> vrCommands ) { + if (vrCommands != null) { + store.put(Names.vrCommands, vrCommands ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/CreateInteractionChoiceSet.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/CreateInteractionChoiceSet.java new file mode 100755 index 000000000..12c19770d --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/CreateInteractionChoiceSet.java @@ -0,0 +1,51 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class CreateInteractionChoiceSet extends RPCRequest { + + public CreateInteractionChoiceSet() { + super("CreateInteractionChoiceSet"); + } + public CreateInteractionChoiceSet(Hashtable hash) { + super(hash); + } + public Integer getInteractionChoiceSetID() { + return (Integer) parameters.get( Names.interactionChoiceSetID ); + } + public void setInteractionChoiceSetID( Integer interactionChoiceSetID ) { + if (interactionChoiceSetID != null) { + parameters.put(Names.interactionChoiceSetID, interactionChoiceSetID ); + } + } + public Vector<Choice> getChoiceSet() { + if (parameters.get(Names.choiceSet) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.choiceSet); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof Choice) { + return (Vector<Choice>) list; + } else if (obj instanceof Hashtable) { + Vector<Choice> newList = new Vector<Choice>(); + for (Object hashObj : list) { + newList.add(new Choice((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setChoiceSet( Vector<Choice> choiceSet ) { + if (choiceSet != null) { + parameters.put(Names.choiceSet, choiceSet ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/CreateInteractionChoiceSetResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/CreateInteractionChoiceSetResponse.java new file mode 100755 index 000000000..d75c32f10 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/CreateInteractionChoiceSetResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class CreateInteractionChoiceSetResponse extends RPCResponse { + + public CreateInteractionChoiceSetResponse() { + super("CreateInteractionChoiceSet"); + } + public CreateInteractionChoiceSetResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteCommand.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteCommand.java new file mode 100755 index 000000000..567be3c93 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteCommand.java @@ -0,0 +1,27 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class DeleteCommand extends RPCRequest { + + public DeleteCommand() { + super("DeleteCommand"); + } + public DeleteCommand(Hashtable hash) { + super(hash); + } + public Integer getCmdID() { + return (Integer) parameters.get( Names.cmdID ); + } + public void setCmdID( Integer cmdID ) { + if (cmdID != null) { + parameters.put(Names.cmdID, cmdID ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteCommandResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteCommandResponse.java new file mode 100755 index 000000000..fc53f8847 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteCommandResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class DeleteCommandResponse extends RPCResponse { + + public DeleteCommandResponse() { + super("DeleteCommand"); + } + public DeleteCommandResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteInteractionChoiceSet.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteInteractionChoiceSet.java new file mode 100755 index 000000000..1935d6185 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteInteractionChoiceSet.java @@ -0,0 +1,27 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class DeleteInteractionChoiceSet extends RPCRequest { + + public DeleteInteractionChoiceSet() { + super("DeleteInteractionChoiceSet"); + } + public DeleteInteractionChoiceSet(Hashtable hash) { + super(hash); + } + public Integer getInteractionChoiceSetID() { + return (Integer) parameters.get( Names.interactionChoiceSetID ); + } + public void setInteractionChoiceSetID( Integer interactionChoiceSetID ) { + if (interactionChoiceSetID != null) { + parameters.put(Names.interactionChoiceSetID, interactionChoiceSetID ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteInteractionChoiceSetResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteInteractionChoiceSetResponse.java new file mode 100755 index 000000000..14b5e07ad --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteInteractionChoiceSetResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class DeleteInteractionChoiceSetResponse extends RPCResponse { + + public DeleteInteractionChoiceSetResponse() { + super("DeleteInteractionChoiceSet"); + } + public DeleteInteractionChoiceSetResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteSubMenu.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteSubMenu.java new file mode 100755 index 000000000..e15218d0f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteSubMenu.java @@ -0,0 +1,27 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class DeleteSubMenu extends RPCRequest { + + public DeleteSubMenu() { + super("DeleteSubMenu"); + } + public DeleteSubMenu(Hashtable hash) { + super(hash); + } + public Integer getMenuID() { + return (Integer) parameters.get( Names.menuID ); + } + public void setMenuID( Integer menuID ) { + if (menuID != null) { + parameters.put(Names.menuID, menuID ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteSubMenuResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteSubMenuResponse.java new file mode 100755 index 000000000..7dd555f26 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DeleteSubMenuResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class DeleteSubMenuResponse extends RPCResponse { + + public DeleteSubMenuResponse() { + super("DeleteSubMenu"); + } + public DeleteSubMenuResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DisplayCapabilities.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DisplayCapabilities.java new file mode 100755 index 000000000..69c604d3e --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/DisplayCapabilities.java @@ -0,0 +1,96 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.DisplayType; +import com.smartdevicelink.proxy.rpc.enums.MediaClockFormat; +import com.smartdevicelink.util.DebugTool; + +public class DisplayCapabilities extends RPCStruct { + + public DisplayCapabilities() { } + public DisplayCapabilities(Hashtable hash) { + super(hash); + } + public DisplayType getDisplayType() { + Object obj = store.get(Names.displayType); + if (obj instanceof DisplayType) { + return (DisplayType) obj; + } else if (obj instanceof String) { + DisplayType theCode = null; + try { + theCode = DisplayType.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.displayType, e); + } + return theCode; + } + return null; + } + public void setDisplayType( DisplayType displayType ) { + if (displayType != null) { + store.put(Names.displayType, displayType ); + } + } + public Vector<TextField> getTextFields() { + if (store.get(Names.textFields) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)store.get(Names.textFields); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof TextField) { + return (Vector<TextField>) list; + } else if (obj instanceof Hashtable) { + Vector<TextField> newList = new Vector<TextField>(); + for (Object hashObj : list) { + newList.add(new TextField((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setTextFields( Vector<TextField> textFields ) { + if (textFields != null) { + store.put(Names.textFields, textFields ); + } + } + public Vector<MediaClockFormat> getMediaClockFormats() { + if (store.get(Names.mediaClockFormats) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)store.get(Names.mediaClockFormats); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof MediaClockFormat) { + return (Vector<MediaClockFormat>) list; + } else if (obj instanceof String) { + Vector<MediaClockFormat> newList = new Vector<MediaClockFormat>(); + for (Object hashObj : list) { + String strFormat = (String)hashObj; + MediaClockFormat toAdd = null; + try { + toAdd = MediaClockFormat.valueForString(strFormat); + } catch (Exception e) { + DebugTool.logError("Failed to parse MediaClockFormat from " + getClass().getSimpleName() + "." + Names.mediaClockFormats, e); + } + if (toAdd != null) { + newList.add(toAdd); + } + } + return newList; + } + } + } + return null; + } + public void setMediaClockFormats( Vector<MediaClockFormat> mediaClockFormats ) { + if (mediaClockFormats != null) { + store.put(Names.mediaClockFormats, mediaClockFormats ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/EncodedSyncPData.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/EncodedSyncPData.java new file mode 100755 index 000000000..6bf9ced46 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/EncodedSyncPData.java @@ -0,0 +1,38 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class EncodedSyncPData extends RPCRequest { + public EncodedSyncPData() { + super("EncodedSyncPData"); + } + + public EncodedSyncPData(Hashtable hash) { + super(hash); + } + + public Vector<String> getData() { + if (parameters.get(Names.data) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.data); + if (list != null && list.size()>0) { + Object obj = list.get(0); + if (obj instanceof String) { + return (Vector<String>) list; + } + } + } + return null; + } + public void setData( Vector<String> data ) { + if ( data!= null) { + parameters.put(Names.data, data ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/EncodedSyncPDataResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/EncodedSyncPDataResponse.java new file mode 100755 index 000000000..060b3dfa3 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/EncodedSyncPDataResponse.java @@ -0,0 +1,17 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class EncodedSyncPDataResponse extends RPCResponse { + public EncodedSyncPDataResponse() { + super("EncodedSyncPData"); + } + public EncodedSyncPDataResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/GenericResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/GenericResponse.java new file mode 100755 index 000000000..308f17dd1 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/GenericResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class GenericResponse extends RPCResponse { + + public GenericResponse() { + super("GenericResponse"); + } + public GenericResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/MenuParams.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/MenuParams.java new file mode 100755 index 000000000..5612062e6 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/MenuParams.java @@ -0,0 +1,41 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; + +public class MenuParams extends RPCStruct { + + public MenuParams() { } + public MenuParams(Hashtable hash) { + super(hash); + } + public Integer getParentID() { + return (Integer) store.get( Names.parentID ); + } + public void setParentID( Integer parentID ) { + if (parentID != null) { + store.put(Names.parentID, parentID ); + } + } + public Integer getPosition() { + return (Integer) store.get( Names.position ); + } + public void setPosition( Integer position ) { + if (position != null) { + store.put(Names.position, position ); + } + } + public String getMenuName() { + return (String) store.get( Names.menuName ); + } + public void setMenuName( String menuName ) { + if (menuName != null) { + store.put(Names.menuName, menuName ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnAppInterfaceUnregistered.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnAppInterfaceUnregistered.java new file mode 100755 index 000000000..108363825 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnAppInterfaceUnregistered.java @@ -0,0 +1,41 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.AppInterfaceUnregisteredReason; +import com.smartdevicelink.util.DebugTool; + +public class OnAppInterfaceUnregistered extends RPCNotification { + + public OnAppInterfaceUnregistered() { + super("OnAppInterfaceUnregistered"); + } + public OnAppInterfaceUnregistered(Hashtable hash) { + super(hash); + } + public AppInterfaceUnregisteredReason getReason() { + Object obj = parameters.get(Names.reason); + if (obj instanceof AppInterfaceUnregisteredReason) { + return (AppInterfaceUnregisteredReason) obj; + } else if (obj instanceof String) { + AppInterfaceUnregisteredReason theCode = null; + try { + theCode = AppInterfaceUnregisteredReason.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.reason, e); + } + return theCode; + } + return null; + } + public void setReason( AppInterfaceUnregisteredReason reason ) { + if (reason != null) { + parameters.put(Names.reason, reason ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnButtonEvent.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnButtonEvent.java new file mode 100755 index 000000000..24411e05f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnButtonEvent.java @@ -0,0 +1,62 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.ButtonEventMode; +import com.smartdevicelink.proxy.rpc.enums.ButtonName; +import com.smartdevicelink.util.DebugTool; + +public class OnButtonEvent extends RPCNotification { + + public OnButtonEvent() { + super("OnButtonEvent"); + } + public OnButtonEvent(Hashtable hash) { + super(hash); + } + public ButtonName getButtonName() { + Object obj = parameters.get(Names.buttonName); + if (obj instanceof ButtonName) { + return (ButtonName) obj; + } else if (obj instanceof String) { + ButtonName theCode = null; + try { + theCode = ButtonName.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.buttonName, e); + } + return theCode; + } + return null; + } + public void setButtonName( ButtonName buttonName ) { + if (buttonName != null) { + parameters.put(Names.buttonName, buttonName ); + } + } + public ButtonEventMode getButtonEventMode() { + Object obj = parameters.get(Names.buttonEventMode); + if (obj instanceof ButtonEventMode) { + return (ButtonEventMode) obj; + } else if (obj instanceof String) { + ButtonEventMode theCode = null; + try { + theCode = ButtonEventMode.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.buttonEventMode, e); + } + return theCode; + } + return null; + } + public void setButtonEventMode( ButtonEventMode buttonEventMode ) { + if (buttonEventMode != null) { + parameters.put(Names.buttonEventMode, buttonEventMode ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnButtonPress.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnButtonPress.java new file mode 100755 index 000000000..bb9e789cb --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnButtonPress.java @@ -0,0 +1,62 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.ButtonName; +import com.smartdevicelink.proxy.rpc.enums.ButtonPressMode; +import com.smartdevicelink.util.DebugTool; + +public class OnButtonPress extends RPCNotification { + + public OnButtonPress() { + super("OnButtonPress"); + } + public OnButtonPress(Hashtable hash) { + super(hash); + } + public ButtonName getButtonName() { + Object obj = parameters.get(Names.buttonName); + if (obj instanceof ButtonName) { + return (ButtonName) obj; + } else if (obj instanceof String) { + ButtonName theCode = null; + try { + theCode = ButtonName.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.buttonName, e); + } + return theCode; + } + return null; + } + public void setButtonName( ButtonName buttonName ) { + if (buttonName != null) { + parameters.put(Names.buttonName, buttonName ); + } + } + public ButtonPressMode getButtonPressMode() { + Object obj = parameters.get(Names.buttonPressMode); + if (obj instanceof ButtonPressMode) { + return (ButtonPressMode) obj; + } else if (obj instanceof String) { + ButtonPressMode theCode = null; + try { + theCode = ButtonPressMode.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.buttonPressMode, e); + } + return theCode; + } + return null; + } + public void setButtonPressMode( ButtonPressMode buttonPressMode ) { + if (buttonPressMode != null) { + parameters.put(Names.buttonPressMode, buttonPressMode ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnCommand.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnCommand.java new file mode 100755 index 000000000..a5f0eb81b --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnCommand.java @@ -0,0 +1,49 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.TriggerSource; +import com.smartdevicelink.util.DebugTool; + +public class OnCommand extends RPCNotification { + + public OnCommand() { + super("OnCommand"); + } + public OnCommand(Hashtable hash) { + super(hash); + } + public Integer getCmdID() { + return (Integer) parameters.get( Names.cmdID ); + } + public void setCmdID( Integer cmdID ) { + if (cmdID != null) { + parameters.put(Names.cmdID, cmdID ); + } + } + public TriggerSource getTriggerSource() { + Object obj = parameters.get(Names.triggerSource); + if (obj instanceof TriggerSource) { + return (TriggerSource) obj; + } else if (obj instanceof String) { + TriggerSource theCode = null; + try { + theCode = TriggerSource.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.triggerSource, e); + } + return theCode; + } + return null; + } + public void setTriggerSource( TriggerSource triggerSource ) { + if (triggerSource != null) { + parameters.put(Names.triggerSource, triggerSource ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnDriverDistraction.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnDriverDistraction.java new file mode 100755 index 000000000..e5540a8c5 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnDriverDistraction.java @@ -0,0 +1,42 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.DriverDistractionState; +import com.smartdevicelink.util.DebugTool; + +public class OnDriverDistraction extends RPCNotification { + public OnDriverDistraction() { + super("OnDriverDistraction"); + } + public OnDriverDistraction(Hashtable hash) { + super(hash); + } + + public DriverDistractionState getState() { + Object obj = parameters.get(Names.state); + if (obj instanceof DriverDistractionState) { + return (DriverDistractionState)obj; + } else if(obj instanceof String) { + DriverDistractionState theCode = null; + try { + theCode = DriverDistractionState.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.state, e); + } + return theCode; + } + return null; + } + public void setState( DriverDistractionState state ) { + if (state != null) { + parameters.put(Names.state, state ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnEncodedSyncPData.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnEncodedSyncPData.java new file mode 100755 index 000000000..0e5b5a2b7 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnEncodedSyncPData.java @@ -0,0 +1,39 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; + +public class OnEncodedSyncPData extends RPCNotification { + public OnEncodedSyncPData() { + super("OnEncodedSyncPData"); + } + public OnEncodedSyncPData(Hashtable hash) { + super(hash); + } + + public Vector<String> getData() { + if (parameters.get(Names.data) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.data); + if (list != null && list.size()>0) { + Object obj = list.get(0); + if (obj instanceof String) { + return (Vector<String>)list; + } + } + } + return null; + } + + public void setData( Vector<String> data ) { + if (data != null) { + parameters.put(Names.data, data ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnHMIStatus.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnHMIStatus.java new file mode 100755 index 000000000..7d4d37a85 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnHMIStatus.java @@ -0,0 +1,90 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.AudioStreamingState; +import com.smartdevicelink.proxy.rpc.enums.HMILevel; +import com.smartdevicelink.proxy.rpc.enums.SystemContext; +import com.smartdevicelink.util.DebugTool; + +public class OnHMIStatus extends RPCNotification { + private Boolean firstRun; + + public OnHMIStatus() { + super("OnHMIStatus"); + } + public OnHMIStatus(Hashtable hash) { + super(hash); + } + public HMILevel getHmiLevel() { + Object obj = parameters.get(Names.hmiLevel); + if (obj instanceof HMILevel) { + return (HMILevel) obj; + } else if (obj instanceof String) { + HMILevel theCode = null; + try { + theCode = HMILevel.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.hmiLevel, e); + } + return theCode; + } + return null; + } + public void setHmiLevel( HMILevel hmiLevel ) { + if (hmiLevel != null) { + parameters.put(Names.hmiLevel, hmiLevel ); + } + } + public AudioStreamingState getAudioStreamingState() { + Object obj = parameters.get(Names.audioStreamingState); + if (obj instanceof AudioStreamingState) { + return (AudioStreamingState) obj; + } else if (obj instanceof String) { + AudioStreamingState theCode = null; + try { + theCode = AudioStreamingState.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.audioStreamingState, e); + } + return theCode; + } + return null; + } + public void setAudioStreamingState( AudioStreamingState audioStreamingState ) { + if (audioStreamingState != null) { + parameters.put(Names.audioStreamingState, audioStreamingState ); + } + } + public SystemContext getSystemContext() { + Object obj = parameters.get(Names.systemContext); + if (obj instanceof SystemContext) { + return (SystemContext) obj; + } else if (obj instanceof String) { + SystemContext theCode = null; + try { + theCode = SystemContext.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.systemContext, e); + } + return theCode; + } + return null; + } + public void setSystemContext( SystemContext systemContext ) { + if (systemContext != null) { + parameters.put(Names.systemContext, systemContext ); + } + } + public Boolean getFirstRun() { + return this.firstRun; + } + public void setFirstRun(Boolean firstRun) { + this.firstRun = firstRun; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnPermissionsChange.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnPermissionsChange.java new file mode 100755 index 000000000..4ccfa3797 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnPermissionsChange.java @@ -0,0 +1,42 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; + +public class OnPermissionsChange extends RPCNotification { + + public OnPermissionsChange() { + super("OnPermissionsChange"); + } + public OnPermissionsChange(Hashtable hash) { + super(hash); + } + + public Vector<PermissionGroupItem> getPermissionGroupItems() { + Vector<?> list = (Vector<?>)parameters.get(Names.PermissionGroupItems); + if (list != null && list.size()>0) { + Object obj = list.get(0); + if(obj instanceof PermissionGroupItem){ + return (Vector<PermissionGroupItem>) list; + } else if(obj instanceof Hashtable) { + Vector<PermissionGroupItem> newList = new Vector<PermissionGroupItem>(); + for (Object hash:list) { + newList.add(new PermissionGroupItem((Hashtable)hash)); + } + return newList; + } + } + return null; + } + public void setPermissionGroupItems(Vector<PermissionGroupItem> permissionGroupItems) { + if (permissionGroupItems != null) { + parameters.put(Names.PermissionGroupItems, permissionGroupItems); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnTBTClientState.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnTBTClientState.java new file mode 100755 index 000000000..53259b5fe --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/OnTBTClientState.java @@ -0,0 +1,41 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.TBTState; +import com.smartdevicelink.util.DebugTool; + +public class OnTBTClientState extends RPCNotification { + + public OnTBTClientState() { + super("OnTBTClientState"); + } + public OnTBTClientState(Hashtable hash) { + super(hash); + } + public TBTState getState() { + Object obj = parameters.get(Names.state); + if (obj instanceof TBTState) { + return (TBTState)obj; + } else if(obj instanceof String) { + TBTState theCode = null; + try{ + theCode = TBTState.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.state, e); + } + return theCode; + } + return null; + } + public void setState( TBTState state ) { + if (state != null) { + parameters.put(Names.state, state ); + } + } +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PerformInteraction.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PerformInteraction.java new file mode 100755 index 000000000..c382e3c65 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PerformInteraction.java @@ -0,0 +1,144 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.InteractionMode; +import com.smartdevicelink.util.DebugTool; + +public class PerformInteraction extends RPCRequest { + + public PerformInteraction() { + super("PerformInteraction"); + } + public PerformInteraction(Hashtable hash) { + super(hash); + } + public String getInitialText() { + return (String) parameters.get( Names.initialText ); + } + public void setInitialText( String initialText ) { + if (initialText != null) { + parameters.put(Names.initialText, initialText ); + } + } + public Vector<TTSChunk> getInitialPrompt() { + if (parameters.get(Names.initialPrompt) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.initialPrompt); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof TTSChunk) { + return (Vector<TTSChunk>) list; + } else if (obj instanceof Hashtable) { + Vector<TTSChunk> newList = new Vector<TTSChunk>(); + for (Object hashObj : list) { + newList.add(new TTSChunk((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setInitialPrompt( Vector<TTSChunk> initialPrompt ) { + if (initialPrompt != null) { + parameters.put(Names.initialPrompt, initialPrompt ); + } + } + public InteractionMode getInteractionMode() { + Object obj = parameters.get(Names.interactionMode); + if (obj instanceof InteractionMode) { + return (InteractionMode) obj; + } else if (obj instanceof String) { + InteractionMode theCode = null; + try { + theCode = InteractionMode.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.interactionMode, e); + } + return theCode; + } + return null; + } + public void setInteractionMode( InteractionMode interactionMode ) { + if (interactionMode != null) { + parameters.put(Names.interactionMode, interactionMode ); + } + } + public Vector<Integer> getInteractionChoiceSetIDList() { + if(parameters.get(Names.interactionChoiceSetIDList) instanceof Vector<?>){ + Vector<?> list = (Vector<?>)parameters.get(Names.interactionChoiceSetIDList); + if(list != null && list.size()>0){ + Object obj = list.get(0); + if(obj instanceof Integer){ + return (Vector<Integer>) list; + } + } + } + return null; + } + public void setInteractionChoiceSetIDList( Vector<Integer> interactionChoiceSetIDList ) { + if (interactionChoiceSetIDList != null) { + parameters.put(Names.interactionChoiceSetIDList, interactionChoiceSetIDList ); + } + } + public Vector<TTSChunk> getHelpPrompt() { + if(parameters.get(Names.helpPrompt) instanceof Vector<?>){ + Vector<?> list = (Vector<?>)parameters.get(Names.helpPrompt); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof TTSChunk) { + return (Vector<TTSChunk>) list; + } else if (obj instanceof Hashtable) { + Vector<TTSChunk> newList = new Vector<TTSChunk>(); + for (Object hashObj : list) { + newList.add(new TTSChunk((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setHelpPrompt( Vector<TTSChunk> helpPrompt ) { + if (helpPrompt != null) { + parameters.put(Names.helpPrompt, helpPrompt ); + } + } + public Vector<TTSChunk> getTimeoutPrompt() { + if (parameters.get(Names.timeoutPrompt) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.timeoutPrompt); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof TTSChunk) { + return (Vector<TTSChunk>) list; + } else if (obj instanceof Hashtable) { + Vector<TTSChunk> newList = new Vector<TTSChunk>(); + for (Object hashObj : list) { + newList.add(new TTSChunk((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setTimeoutPrompt( Vector<TTSChunk> timeoutPrompt ) { + if (timeoutPrompt != null) { + parameters.put(Names.timeoutPrompt, timeoutPrompt ); + } + } + public Integer getTimeout() { + return (Integer) parameters.get( Names.timeout ); + } + public void setTimeout( Integer timeout ) { + if (timeout != null) { + parameters.put(Names.timeout, timeout ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PerformInteractionResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PerformInteractionResponse.java new file mode 100755 index 000000000..6a55c489e --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PerformInteractionResponse.java @@ -0,0 +1,49 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.TriggerSource; +import com.smartdevicelink.util.DebugTool; + +public class PerformInteractionResponse extends RPCResponse { + + public PerformInteractionResponse() { + super("PerformInteraction"); + } + public PerformInteractionResponse(Hashtable hash) { + super(hash); + } + public Integer getChoiceID() { + return (Integer) parameters.get( Names.choiceID ); + } + public void setChoiceID( Integer choiceID ) { + if (choiceID != null) { + parameters.put(Names.choiceID, choiceID ); + } + } + public TriggerSource getTriggerSource() { + Object obj = parameters.get(Names.triggerSource); + if (obj instanceof TriggerSource) { + return (TriggerSource) obj; + } else if (obj instanceof String) { + TriggerSource theCode = null; + try { + theCode = TriggerSource.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.triggerSource, e); + } + return theCode; + } + return null; + } + public void setTriggerSource( TriggerSource triggerSource ) { + if (triggerSource != null) { + parameters.put(Names.triggerSource, triggerSource ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PermissionGroupItem.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PermissionGroupItem.java new file mode 100755 index 000000000..553acfa56 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/PermissionGroupItem.java @@ -0,0 +1,51 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.PermissionStatus; +import com.smartdevicelink.util.DebugTool; + +public class PermissionGroupItem extends RPCStruct { + + public PermissionGroupItem() { } + public PermissionGroupItem(Hashtable hash) { + super(hash); + } + public String getPermissionGroupName() { + Object obj = store.get(Names.PermissionGroupName); + if (obj instanceof String) { + return (String)obj; + } + return null; + } + public void setPermissionGroupName(String permissionGroupName) { + if (permissionGroupName != null) { + store.put(Names.PermissionGroupName, permissionGroupName); + } + } + public PermissionStatus getPermissionGroupStatus() { + Object obj = store.get(Names.PermissionGroupStatus); + if (obj instanceof PermissionStatus) { + return (PermissionStatus)obj; + } else if(obj instanceof String) { + PermissionStatus theCode = null; + try { + theCode = PermissionStatus.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.name, e); + } + return theCode; + } + return null; + } + public void setPermissionGroupStatus(PermissionStatus permissionStatus) { + if (permissionStatus != null) { + store.put(Names.PermissionGroupStatus, permissionStatus); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/RegisterAppInterface.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/RegisterAppInterface.java new file mode 100755 index 000000000..d27688db7 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/RegisterAppInterface.java @@ -0,0 +1,105 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.util.DebugTool; + +public class RegisterAppInterface extends RPCRequest { + + public RegisterAppInterface() { + super("RegisterAppInterface"); + } + public RegisterAppInterface(Hashtable hash) { + super(hash); + } + public SyncMsgVersion getSyncMsgVersion() { + Object obj = parameters.get(Names.syncMsgVersion); + if (obj instanceof SyncMsgVersion) { + return (SyncMsgVersion)obj; + } else if (obj instanceof Hashtable) { + return new SyncMsgVersion((Hashtable)obj); + } + return null; + } + public void setSyncMsgVersion( SyncMsgVersion SyncMsgVersion ) { + if (SyncMsgVersion != null) { + parameters.put(Names.syncMsgVersion, SyncMsgVersion ); + } + } + public String getAppName() { + return (String) parameters.get( Names.appName ); + } + public void setAppName( String appName ) { + if (appName != null) { + parameters.put(Names.appName, appName ); + } + } + public String getNgnMediaScreenAppName() { + return (String) parameters.get( Names.ngnMediaScreenAppName ); + } + public void setNgnMediaScreenAppName( String ngnMediaScreenAppName ) { + if (ngnMediaScreenAppName != null) { + parameters.put(Names.ngnMediaScreenAppName, ngnMediaScreenAppName ); + } + } + public Vector<String> getVrSynonyms() { + if (parameters.get( Names.vrSynonyms ) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get( Names.vrSynonyms ); + if (list != null && list.size()>0) { + Object obj = list.get(0); + if (obj instanceof String) { + return (Vector<String>) list; + } + } + } + return null; + } + public void setVrSynonyms( Vector<String> vrSynonyms ) { + if (vrSynonyms != null) { + parameters.put(Names.vrSynonyms, vrSynonyms ); + } + } + public Boolean getIsMediaApplication() { + return (Boolean) parameters.get( Names.isMediaApplication ); + } + public void setIsMediaApplication( Boolean isMediaApplication ) { + if (isMediaApplication != null) { + parameters.put(Names.isMediaApplication, isMediaApplication ); + } + } + public Language getLanguageDesired() { + Object obj = parameters.get(Names.languageDesired); + if (obj instanceof Language) { + return (Language) obj; + } else if (obj instanceof String) { + Language theCode = null; + try { + theCode = Language.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.languageDesired, e); + } + return theCode; + } + return null; + } + public void setLanguageDesired( Language languageDesired ) { + if (languageDesired != null) { + parameters.put(Names.languageDesired, languageDesired ); + } + } + public String getAutoActivateID() { + return (String) parameters.get( Names.autoActivateID ); + } + public void setAutoActivateID( String autoActivateID ) { + if (autoActivateID != null) { + parameters.put(Names.autoActivateID, autoActivateID ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/RegisterAppInterfaceResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/RegisterAppInterfaceResponse.java new file mode 100755 index 000000000..8f6809c1c --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/RegisterAppInterfaceResponse.java @@ -0,0 +1,200 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCResponse; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.HmiZoneCapabilities; +import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities; +import com.smartdevicelink.proxy.rpc.enums.VrCapabilities; +import com.smartdevicelink.util.DebugTool; + +public class RegisterAppInterfaceResponse extends RPCResponse { + + public RegisterAppInterfaceResponse() { + super("RegisterAppInterface"); + } + public RegisterAppInterfaceResponse(Hashtable hash) { + super(hash); + } + public SyncMsgVersion getSyncMsgVersion() { + Object obj = parameters.get(Names.syncMsgVersion); + if (obj instanceof SyncMsgVersion) { + return (SyncMsgVersion)obj; + } else if (obj instanceof Hashtable) { + return new SyncMsgVersion((Hashtable)obj); + } + return null; + } + public void setSyncMsgVersion( SyncMsgVersion SyncMsgVersion ) { + if (SyncMsgVersion != null) { + parameters.put(Names.syncMsgVersion, SyncMsgVersion ); + } + } + public String getAutoActivateID() { + return (String) parameters.get( Names.autoActivateID ); + } + public void setAutoActivateID( String autoActivateID ) { + if (autoActivateID != null) { + parameters.put(Names.autoActivateID, autoActivateID ); + } + } + public Language getLanguage() { + Object obj = parameters.get(Names.language); + if (obj instanceof Language) { + return (Language) obj; + } else if (obj instanceof String) { + Language theCode = null; + try { + theCode = Language.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.language, e); + } + return theCode; + } + return null; + } + public void setLanguage( Language language ) { + if (language != null) { + parameters.put(Names.language, language ); + } + } + public DisplayCapabilities getDisplayCapabilities() { + Object obj = parameters.get(Names.displayCapabilities); + if (obj instanceof DisplayCapabilities) { + return (DisplayCapabilities)obj; + } else if (obj instanceof Hashtable) { + return new DisplayCapabilities((Hashtable)obj); + } + return null; + } + public void setDisplayCapabilities( DisplayCapabilities displayCapabilities ) { + if (displayCapabilities != null) { + parameters.put(Names.displayCapabilities, displayCapabilities ); + } + } + public Vector<ButtonCapabilities> getButtonCapabilities() { + if (parameters.get(Names.buttonCapabilities) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.buttonCapabilities); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof ButtonCapabilities) { + return (Vector<ButtonCapabilities>) list; + } else if (obj instanceof Hashtable) { + Vector<ButtonCapabilities> newList = new Vector<ButtonCapabilities>(); + for (Object hashObj : list) { + newList.add(new ButtonCapabilities((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setButtonCapabilities( Vector<ButtonCapabilities> buttonCapabilities ) { + if (buttonCapabilities != null) { + parameters.put(Names.buttonCapabilities, buttonCapabilities ); + } + } + public Vector<HmiZoneCapabilities> getHmiZoneCapabilities() { + if (parameters.get(Names.hmiZoneCapabilities) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.hmiZoneCapabilities); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof HmiZoneCapabilities) { + return (Vector<HmiZoneCapabilities>) list; + } else if (obj instanceof String) { + Vector<HmiZoneCapabilities> newList = new Vector<HmiZoneCapabilities>(); + for (Object hashObj : list) { + String strFormat = (String)hashObj; + HmiZoneCapabilities toAdd = null; + try { + toAdd = HmiZoneCapabilities.valueForString(strFormat); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.hmiZoneCapabilities, e); + } + if (toAdd != null) { + newList.add(toAdd); + } + } + return newList; + } + } + } + return null; + } + public void setHmiZoneCapabilities( Vector<HmiZoneCapabilities> hmiZoneCapabilities ) { + if (hmiZoneCapabilities != null) { + parameters.put(Names.hmiZoneCapabilities, hmiZoneCapabilities ); + } + } + public Vector<SpeechCapabilities> getSpeechCapabilities() { + if (parameters.get(Names.speechCapabilities) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.speechCapabilities); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof SpeechCapabilities) { + return (Vector<SpeechCapabilities>) list; + } else if (obj instanceof String) { + Vector<SpeechCapabilities> newList = new Vector<SpeechCapabilities>(); + for (Object hashObj : list) { + String strFormat = (String)hashObj; + SpeechCapabilities toAdd = null; + try { + toAdd = SpeechCapabilities.valueForString(strFormat); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.speechCapabilities, e); + } + if (toAdd != null) { + newList.add(toAdd); + } + } + return newList; + } + } + } + return null; + } + public void setSpeechCapabilities( Vector<SpeechCapabilities> speechCapabilities ) { + if (speechCapabilities != null) { + parameters.put(Names.speechCapabilities, speechCapabilities ); + } + } + public Vector<VrCapabilities> getVrCapabilities() { + if (parameters.get(Names.vrCapabilities) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.vrCapabilities); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof VrCapabilities) { + return (Vector<VrCapabilities>) list; + } else if (obj instanceof String) { + Vector<VrCapabilities> newList = new Vector<VrCapabilities>(); + for (Object hashObj : list) { + String strFormat = (String)hashObj; + VrCapabilities toAdd = null; + try { + toAdd = VrCapabilities.valueForString(strFormat); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.vrCapabilities, e); + } + if (toAdd != null) { + newList.add(toAdd); + } + } + return newList; + } + } + } + return null; + } + public void setVrCapabilities( Vector<VrCapabilities> vrCapabilities ) { + if (vrCapabilities != null) { + parameters.put(Names.vrCapabilities, vrCapabilities ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ResetGlobalProperties.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ResetGlobalProperties.java new file mode 100755 index 000000000..38775b498 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ResetGlobalProperties.java @@ -0,0 +1,54 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.GlobalProperty; +import com.smartdevicelink.util.DebugTool; + +public class ResetGlobalProperties extends RPCRequest { + + public ResetGlobalProperties() { + super("ResetGlobalProperties"); + } + public ResetGlobalProperties(Hashtable hash) { + super(hash); + } + public Vector<GlobalProperty> getProperties() { + if (parameters.get(Names.properties) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.properties); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof GlobalProperty) { + return (Vector<GlobalProperty>) list; + } else if (obj instanceof String) { + Vector<GlobalProperty> newList = new Vector<GlobalProperty>(); + for (Object hashObj : list) { + String strFormat = (String)hashObj; + GlobalProperty toAdd = null; + try { + toAdd = GlobalProperty.valueForString(strFormat); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.properties, e); + } + if (toAdd != null) { + newList.add(toAdd); + } + } + return newList; + } + } + } + return null; + } + public void setProperties( Vector<GlobalProperty> properties ) { + if (properties != null) { + parameters.put(Names.properties, properties ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ResetGlobalPropertiesResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ResetGlobalPropertiesResponse.java new file mode 100755 index 000000000..56c3170d7 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ResetGlobalPropertiesResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class ResetGlobalPropertiesResponse extends RPCResponse { + + public ResetGlobalPropertiesResponse() { + super("ResetGlobalProperties"); + } + public ResetGlobalPropertiesResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetGlobalProperties.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetGlobalProperties.java new file mode 100755 index 000000000..b086b9eb9 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetGlobalProperties.java @@ -0,0 +1,66 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class SetGlobalProperties extends RPCRequest { + + public SetGlobalProperties() { + super("SetGlobalProperties"); + } + public SetGlobalProperties(Hashtable hash) { + super(hash); + } + public Vector<TTSChunk> getHelpPrompt() { + if (parameters.get(Names.helpPrompt) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.helpPrompt); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof TTSChunk) { + return (Vector<TTSChunk>) list; + } else if (obj instanceof Hashtable) { + Vector<TTSChunk> newList = new Vector<TTSChunk>(); + for (Object hashObj : list) { + newList.add(new TTSChunk((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setHelpPrompt( Vector<TTSChunk> helpPrompt ) { + if (helpPrompt != null) { + parameters.put(Names.helpPrompt, helpPrompt ); + } + } + public Vector<TTSChunk> getTimeoutPrompt() { + if (parameters.get(Names.timeoutPrompt) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.timeoutPrompt); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof TTSChunk) { + return (Vector<TTSChunk>) list; + } else if (obj instanceof Hashtable) { + Vector<TTSChunk> newList = new Vector<TTSChunk>(); + for (Object hashObj : list) { + newList.add(new TTSChunk((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setTimeoutPrompt( Vector<TTSChunk> timeoutPrompt ) { + if (timeoutPrompt != null) { + parameters.put(Names.timeoutPrompt, timeoutPrompt ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetGlobalPropertiesResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetGlobalPropertiesResponse.java new file mode 100755 index 000000000..1d7e17894 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetGlobalPropertiesResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class SetGlobalPropertiesResponse extends RPCResponse { + + public SetGlobalPropertiesResponse() { + super("SetGlobalProperties"); + } + public SetGlobalPropertiesResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetMediaClockTimer.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetMediaClockTimer.java new file mode 100755 index 000000000..e21c8f7fa --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetMediaClockTimer.java @@ -0,0 +1,55 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.UpdateMode; +import com.smartdevicelink.util.DebugTool; + +public class SetMediaClockTimer extends RPCRequest { + + public SetMediaClockTimer() { + super("SetMediaClockTimer"); + } + public SetMediaClockTimer(Hashtable hash) { + super(hash); + } + public StartTime getStartTime() { + Object obj = parameters.get(Names.startTime); + if (obj instanceof StartTime) { + return (StartTime)obj; + } else if (obj instanceof Hashtable) { + return new StartTime((Hashtable)obj); + } + return null; + } + public void setStartTime( StartTime startTime ) { + if (startTime != null) { + parameters.put(Names.startTime, startTime ); + } + } + public UpdateMode getUpdateMode() { + Object obj = parameters.get(Names.updateMode); + if (obj instanceof UpdateMode) { + return (UpdateMode) obj; + } else if (obj instanceof String) { + UpdateMode theCode = null; + try { + theCode = UpdateMode.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.updateMode, e); + } + return theCode; + } + return null; + } + public void setUpdateMode( UpdateMode updateMode ) { + if (updateMode != null) { + parameters.put(Names.updateMode, updateMode ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetMediaClockTimerResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetMediaClockTimerResponse.java new file mode 100755 index 000000000..c224b457f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SetMediaClockTimerResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class SetMediaClockTimerResponse extends RPCResponse { + + public SetMediaClockTimerResponse() { + super("SetMediaClockTimer"); + } + public SetMediaClockTimerResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Show.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Show.java new file mode 100755 index 000000000..5093606cb --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Show.java @@ -0,0 +1,81 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.TextAlignment; +import com.smartdevicelink.util.DebugTool; + +public class Show extends RPCRequest { + + public Show() { + super("Show"); + } + public Show(Hashtable hash) { + super(hash); + } + public String getMainField1() { + return (String) parameters.get( Names.mainField1 ); + } + public void setMainField1( String mainField1 ) { + if (mainField1 != null) { + parameters.put(Names.mainField1, mainField1 ); + } + } + public String getMainField2() { + return (String) parameters.get( Names.mainField2 ); + } + public void setMainField2( String mainField2 ) { + if (mainField2 != null) { + parameters.put(Names.mainField2, mainField2 ); + } + } + public TextAlignment getAlignment() { + Object obj = parameters.get(Names.alignment); + if (obj instanceof TextAlignment) { + return (TextAlignment) obj; + } else if (obj instanceof String) { + TextAlignment theCode = null; + try { + theCode = TextAlignment.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.alignment, e); + } + return theCode; + } + return null; + } + public void setAlignment( TextAlignment alignment ) { + if (alignment != null) { + parameters.put(Names.alignment, alignment ); + } + } + public String getStatusBar() { + return (String) parameters.get( Names.statusBar ); + } + public void setStatusBar( String statusBar ) { + if (statusBar != null) { + parameters.put(Names.statusBar, statusBar ); + } + } + public String getMediaClock() { + return (String) parameters.get( Names.mediaClock ); + } + public void setMediaClock( String mediaClock ) { + if (mediaClock != null) { + parameters.put(Names.mediaClock, mediaClock ); + } + } + public String getMediaTrack() { + return (String) parameters.get( Names.mediaTrack ); + } + public void setMediaTrack( String mediaTrack ) { + if (mediaTrack != null) { + parameters.put(Names.mediaTrack, mediaTrack ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ShowResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ShowResponse.java new file mode 100755 index 000000000..b97db003c --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/ShowResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class ShowResponse extends RPCResponse { + + public ShowResponse() { + super("Show"); + } + public ShowResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Speak.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Speak.java new file mode 100755 index 000000000..9c5ed4a1a --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/Speak.java @@ -0,0 +1,43 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; + +public class Speak extends RPCRequest { + + public Speak() { + super("Speak"); + } + public Speak(Hashtable hash) { + super(hash); + } + public Vector<TTSChunk> getTtsChunks() { + if (parameters.get(Names.ttsChunks) instanceof Vector<?>) { + Vector<?> list = (Vector<?>)parameters.get(Names.ttsChunks); + if (list != null && list.size() > 0) { + Object obj = list.get(0); + if (obj instanceof TTSChunk) { + return (Vector<TTSChunk>) list; + } else if (obj instanceof Hashtable) { + Vector<TTSChunk> newList = new Vector<TTSChunk>(); + for (Object hashObj : list) { + newList.add(new TTSChunk((Hashtable)hashObj)); + } + return newList; + } + } + } + return null; + } + public void setTtsChunks( Vector<TTSChunk> ttsChunks ) { + if (ttsChunks != null) { + parameters.put(Names.ttsChunks, ttsChunks ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SpeakResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SpeakResponse.java new file mode 100755 index 000000000..06fa77f6a --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SpeakResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class SpeakResponse extends RPCResponse { + + public SpeakResponse() { + super("Speak"); + } + public SpeakResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/StartTime.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/StartTime.java new file mode 100755 index 000000000..23802de5d --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/StartTime.java @@ -0,0 +1,41 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; + +public class StartTime extends RPCStruct { + + public StartTime() { } + public StartTime(Hashtable hash) { + super(hash); + } + public Integer getHours() { + return (Integer) store.get( Names.hours ); + } + public void setHours( Integer hours ) { + if (hours != null) { + store.put(Names.hours, hours ); + } + } + public Integer getMinutes() { + return (Integer) store.get( Names.minutes ); + } + public void setMinutes( Integer minutes ) { + if (minutes != null) { + store.put(Names.minutes, minutes ); + } + } + public Integer getSeconds() { + return (Integer) store.get( Names.seconds ); + } + public void setSeconds( Integer seconds ) { + if (seconds != null) { + store.put(Names.seconds, seconds ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SubscribeButton.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SubscribeButton.java new file mode 100755 index 000000000..671ffcf93 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SubscribeButton.java @@ -0,0 +1,41 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.ButtonName; +import com.smartdevicelink.util.DebugTool; + +public class SubscribeButton extends RPCRequest { + + public SubscribeButton() { + super("SubscribeButton"); + } + public SubscribeButton(Hashtable hash) { + super(hash); + } + public ButtonName getButtonName() { + Object obj = parameters.get(Names.buttonName); + if (obj instanceof ButtonName) { + return (ButtonName) obj; + } else if (obj instanceof String) { + ButtonName theCode = null; + try { + theCode = ButtonName.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.buttonName, e); + } + return theCode; + } + return null; + } + public void setButtonName( ButtonName buttonName ) { + if (buttonName != null) { + parameters.put(Names.buttonName, buttonName ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SubscribeButtonResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SubscribeButtonResponse.java new file mode 100755 index 000000000..1e3393159 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SubscribeButtonResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class SubscribeButtonResponse extends RPCResponse { + + public SubscribeButtonResponse() { + super("SubscribeButton"); + } + public SubscribeButtonResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SyncMsgVersion.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SyncMsgVersion.java new file mode 100755 index 000000000..8d6cbde40 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/SyncMsgVersion.java @@ -0,0 +1,33 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; + +public class SyncMsgVersion extends RPCStruct { + + public SyncMsgVersion() { } + public SyncMsgVersion(Hashtable hash) { + super(hash); + } + public Integer getMajorVersion() { + return (Integer) store.get( Names.majorVersion ); + } + public void setMajorVersion( Integer majorVersion ) { + if (majorVersion != null) { + store.put(Names.majorVersion, majorVersion ); + } + } + public Integer getMinorVersion() { + return (Integer) store.get( Names.minorVersion ); + } + public void setMinorVersion( Integer minorVersion ) { + if (minorVersion != null) { + store.put(Names.minorVersion, minorVersion ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/TTSChunk.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/TTSChunk.java new file mode 100755 index 000000000..c46919d39 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/TTSChunk.java @@ -0,0 +1,47 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities; +import com.smartdevicelink.util.DebugTool; + +public class TTSChunk extends RPCStruct { + + public TTSChunk() { } + public TTSChunk(Hashtable hash) { + super(hash); + } + public String getText() { + return (String) store.get( Names.text ); + } + public void setText( String text ) { + if (text != null) { + store.put(Names.text, text ); + } + } + public SpeechCapabilities getType() { + Object obj = store.get(Names.type); + if (obj instanceof SpeechCapabilities) { + return (SpeechCapabilities) obj; + } else if (obj instanceof String) { + SpeechCapabilities theCode = null; + try { + theCode = SpeechCapabilities.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.type, e); + } + return theCode; + } + return null; + } + public void setType( SpeechCapabilities type ) { + if (type != null) { + store.put(Names.type, type ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/TextField.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/TextField.java new file mode 100755 index 000000000..33a5c40de --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/TextField.java @@ -0,0 +1,76 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCStruct; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.CharacterSet; +import com.smartdevicelink.proxy.rpc.enums.TextFieldName; +import com.smartdevicelink.util.DebugTool; + +public class TextField extends RPCStruct { + + public TextField() { } + public TextField(Hashtable hash) { + super(hash); + } + public TextFieldName getName() { + Object obj = store.get(Names.name); + if (obj instanceof TextFieldName) { + return (TextFieldName) obj; + } else if (obj instanceof String) { + TextFieldName theCode = null; + try { + theCode = TextFieldName.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.name, e); + } + return theCode; + } + return null; + } + public void setName( TextFieldName name ) { + if (name != null) { + store.put(Names.name, name ); + } + } + public CharacterSet getCharacterSet() { + Object obj = store.get(Names.characterSet); + if (obj instanceof CharacterSet) { + return (CharacterSet) obj; + } else if (obj instanceof String) { + CharacterSet theCode = null; + try { + theCode = CharacterSet.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.characterSet, e); + } + return theCode; + } + return null; + } + public void setCharacterSet( CharacterSet characterSet ) { + if (characterSet != null) { + store.put(Names.characterSet, characterSet ); + } + } + public Integer getWidth() { + return (Integer) store.get( Names.width ); + } + public void setWidth( Integer width ) { + if (width != null) { + store.put(Names.width, width ); + } + } + public Integer getRows() { + return (Integer) store.get( Names.rows ); + } + public void setRows( Integer rows ) { + if (rows != null) { + store.put(Names.rows, rows ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnregisterAppInterface.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnregisterAppInterface.java new file mode 100755 index 000000000..b30942624 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnregisterAppInterface.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; + +public class UnregisterAppInterface extends RPCRequest { + + public UnregisterAppInterface() { + super("UnregisterAppInterface"); + } + public UnregisterAppInterface(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnregisterAppInterfaceResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnregisterAppInterfaceResponse.java new file mode 100755 index 000000000..599ef2f1a --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnregisterAppInterfaceResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class UnregisterAppInterfaceResponse extends RPCResponse { + + public UnregisterAppInterfaceResponse() { + super("UnregisterAppInterface"); + } + public UnregisterAppInterfaceResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnsubscribeButton.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnsubscribeButton.java new file mode 100755 index 000000000..02787ad46 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnsubscribeButton.java @@ -0,0 +1,41 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.constants.Names; +import com.smartdevicelink.proxy.rpc.enums.ButtonName; +import com.smartdevicelink.util.DebugTool; + +public class UnsubscribeButton extends RPCRequest { + + public UnsubscribeButton() { + super("UnsubscribeButton"); + } + public UnsubscribeButton(Hashtable hash) { + super(hash); + } + public ButtonName getButtonName() { + Object obj = parameters.get(Names.buttonName); + if (obj instanceof ButtonName) { + return (ButtonName) obj; + } else if (obj instanceof String) { + ButtonName theCode = null; + try { + theCode = ButtonName.valueForString((String) obj); + } catch (Exception e) { + DebugTool.logError("Failed to parse " + getClass().getSimpleName() + "." + Names.buttonName, e); + } + return theCode; + } + return null; + } + public void setButtonName( ButtonName buttonName ) { + if (buttonName != null) { + parameters.put(Names.buttonName, buttonName ); + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnsubscribeButtonResponse.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnsubscribeButtonResponse.java new file mode 100755 index 000000000..e5d790744 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/UnsubscribeButtonResponse.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc; + +import java.util.Hashtable; + +import com.smartdevicelink.proxy.RPCResponse; + +public class UnsubscribeButtonResponse extends RPCResponse { + + public UnsubscribeButtonResponse() { + super("UnsubscribeButton"); + } + public UnsubscribeButtonResponse(Hashtable hash) { + super(hash); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/AppInterfaceUnregisteredReason.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/AppInterfaceUnregisteredReason.java new file mode 100755 index 000000000..8c96fb469 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/AppInterfaceUnregisteredReason.java @@ -0,0 +1,22 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + + +public enum AppInterfaceUnregisteredReason { + USER_EXIT, + IGNITION_OFF, + BLUETOOTH_OFF, + USB_DISCONNECTED, + REQUEST_WHILE_IN_NONE_HMI_LEVEL, + TOO_MANY_REQUESTS, + DRIVER_DISTRACTION_VIOLATION, + LANGUAGE_CHANGE, + MASTER_RESET, + FACTORY_DEFAULTS; + + public static AppInterfaceUnregisteredReason valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/AudioStreamingState.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/AudioStreamingState.java new file mode 100755 index 000000000..4c9d945ac --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/AudioStreamingState.java @@ -0,0 +1,13 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum AudioStreamingState { + AUDIBLE, + NOT_AUDIBLE; + + public static AudioStreamingState valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonEventMode.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonEventMode.java new file mode 100755 index 000000000..7a7534592 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonEventMode.java @@ -0,0 +1,13 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum ButtonEventMode { + BUTTONUP, + BUTTONDOWN; + + public static ButtonEventMode valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonName.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonName.java new file mode 100755 index 000000000..0c7cf5965 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonName.java @@ -0,0 +1,75 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum ButtonName{ + OK, + SEEKLEFT, + SEEKRIGHT, + TUNEUP, + TUNEDOWN, + PRESET_0, + PRESET_1, + PRESET_2, + PRESET_3, + PRESET_4, + PRESET_5, + PRESET_6, + PRESET_7, + PRESET_8, + PRESET_9; + + public static ButtonName valueForString(String value) { + return valueOf(value); + } + + /** + * indexForPresetButton returns the integer index for preset buttons + * which match the preset order. E.G.: indexForPresetButton(PRESET_1) + * returns the value 1. If the buttonName given is not a preset button, + * the method will return null. + * + * @param buttonName + * @return Integer + */ + public static Integer indexForPresetButton(ButtonName buttonName) { + + Integer returnIndex = null; + + switch(buttonName) { + case PRESET_0: + returnIndex = 0; + break; + case PRESET_1: + returnIndex = 1; + break; + case PRESET_2: + returnIndex = 2; + break; + case PRESET_3: + returnIndex = 3; + break; + case PRESET_4: + returnIndex = 4; + break; + case PRESET_5: + returnIndex = 5; + break; + case PRESET_6: + returnIndex = 6; + break; + case PRESET_7: + returnIndex = 7; + break; + case PRESET_8: + returnIndex = 8; + break; + case PRESET_9: + returnIndex = 9; + break; + } + + return returnIndex; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonPressMode.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonPressMode.java new file mode 100755 index 000000000..caf1b9012 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/ButtonPressMode.java @@ -0,0 +1,13 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum ButtonPressMode { + LONG, + SHORT; + + public static ButtonPressMode valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/CharacterSet.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/CharacterSet.java new file mode 100755 index 000000000..608383529 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/CharacterSet.java @@ -0,0 +1,15 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum CharacterSet { + TYPE2SET, + TYPE5SET, + CID1SET, + CID2SET; + + public static CharacterSet valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/DisplayType.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/DisplayType.java new file mode 100755 index 000000000..df8dd1a71 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/DisplayType.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum DisplayType { + CID, + TYPE2, + TYPE5, + NGN, + GEN2_4_DMA, + GEN2_8_DMA, + GEN2_4_HUD; + + public static DisplayType valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/DriverDistractionState.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/DriverDistractionState.java new file mode 100755 index 000000000..112881e23 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/DriverDistractionState.java @@ -0,0 +1,13 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum DriverDistractionState { + DD_ON, + DD_OFF; + + public static DriverDistractionState valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/GlobalProperty.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/GlobalProperty.java new file mode 100755 index 000000000..d30523dbd --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/GlobalProperty.java @@ -0,0 +1,13 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum GlobalProperty{ + HELPPROMPT, + TIMEOUTPROMPT; + + public static GlobalProperty valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/HMILevel.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/HMILevel.java new file mode 100755 index 000000000..eb3ace7fb --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/HMILevel.java @@ -0,0 +1,32 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +import java.util.EnumSet; + +public enum HMILevel { + HMI_FULL("FULL"), + HMI_LIMITED("LIMITED"), + HMI_BACKGROUND("BACKGROUND"), + HMI_NONE("NONE"); + + String internalName; + + private HMILevel(String internalName) { + this.internalName = internalName; + } + + public String toString() { + return this.internalName; + } + + public static HMILevel valueForString(String value) { + for (HMILevel anEnum : EnumSet.allOf(HMILevel.class)) { + if (anEnum.toString().equals(value)) { + return anEnum; + } + } + return null; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/HmiZoneCapabilities.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/HmiZoneCapabilities.java new file mode 100755 index 000000000..e652999bb --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/HmiZoneCapabilities.java @@ -0,0 +1,13 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum HmiZoneCapabilities { + FRONT, + BACK; + + public static HmiZoneCapabilities valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/InteractionMode.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/InteractionMode.java new file mode 100755 index 000000000..cc898dc04 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/InteractionMode.java @@ -0,0 +1,14 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum InteractionMode { + MANUAL_ONLY, + VR_ONLY, + BOTH; + + public static InteractionMode valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/Language.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/Language.java new file mode 100755 index 000000000..f4d204050 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/Language.java @@ -0,0 +1,31 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +import java.util.EnumSet; + +public enum Language { + EN_US("EN-US"), + ES_MX("ES-MX"), + FR_CA("FR-CA"); + + String internalName; + + private Language(String internalName) { + this.internalName = internalName; + } + + public String toString() { + return this.internalName; + } + + public static Language valueForString(String value) { + for (Language anEnum : EnumSet.allOf(Language.class)) { + if (anEnum.toString().equals(value)) { + return anEnum; + } + } + return null; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/MediaClockFormat.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/MediaClockFormat.java new file mode 100755 index 000000000..98f40cce0 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/MediaClockFormat.java @@ -0,0 +1,16 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum MediaClockFormat { + CLOCK1, + CLOCK2, + CLOCKTEXT1, + CLOCKTEXT2, + CLOCKTEXT3; + + public static MediaClockFormat valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/PermissionStatus.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/PermissionStatus.java new file mode 100755 index 000000000..4ae99bfed --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/PermissionStatus.java @@ -0,0 +1,15 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum PermissionStatus { + ALLOWED, + DISALLOWED, + USER_DISALLOWED, + USER_CONSENT_PENDING; + + public static PermissionStatus valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/Result.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/Result.java new file mode 100755 index 000000000..daf6f2812 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/Result.java @@ -0,0 +1,33 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum Result { + SUCCESS, + INVALID_DATA, + UNSUPPORTED_REQUEST, + OUT_OF_MEMORY, + TOO_MANY_PENDING_REQUESTS, + INVALID_ID, + DUPLICATE_NAME, + TOO_MANY_APPLICATIONS, + APPLICATION_REGISTERED_ALREADY, + UNSUPPORTED_VERSION, + WRONG_LANGUAGE, + APPLICATION_NOT_REGISTERED, + IN_USE, + SUBSCRIBED_ALREADY, + VEHICLE_DATA_NOT_ALLOWED, + VEHICLE_DATA_NOT_AVAILABLE, + REJECTED, + ABORTED, + IGNORED, + UNSUPPORTED_BUTTON, + FILE_NOT_FOUND, + GENERIC_ERROR; + + public static Result valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkConnectionState.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkConnectionState.java new file mode 100755 index 000000000..64d4d4ce4 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkConnectionState.java @@ -0,0 +1,9 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum SmartDeviceLinkConnectionState { + SMARTDEVICELINK_CONNECTED, + SMARTDEVICELINK_DISCONNECTED; +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkDisconnectedReason.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkDisconnectedReason.java new file mode 100755 index 000000000..47abbcf37 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkDisconnectedReason.java @@ -0,0 +1,55 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum SmartDeviceLinkDisconnectedReason { + USER_EXIT, + IGNITION_OFF, + BLUETOOTH_OFF, + USB_DISCONNECTED, + REQUEST_WHILE_IN_NONE_HMI_LEVEL, + TOO_MANY_REQUESTS, + DRIVER_DISTRACTION_VIOLATION, + LANGUAGE_CHANGE, + MASTER_RESET, + FACTORY_DEFAULTS, + HEARTBEAT_PAST_DUE, + TRANSPORT_ERROR, + APPLICATION_REQUESTED_DISCONNECT, + DEFAULT; + + public static SmartDeviceLinkDisconnectedReason valueForString(String value) { + return valueOf(value); + } + + public static SmartDeviceLinkDisconnectedReason convertAppInterfaceUnregisteredReason(AppInterfaceUnregisteredReason reason) { + + SmartDeviceLinkDisconnectedReason returnReason = SmartDeviceLinkDisconnectedReason.DEFAULT; + + switch(reason) { + case USER_EXIT: + returnReason = SmartDeviceLinkDisconnectedReason.USER_EXIT; + case IGNITION_OFF: + returnReason = SmartDeviceLinkDisconnectedReason.IGNITION_OFF; + case BLUETOOTH_OFF: + returnReason = SmartDeviceLinkDisconnectedReason.BLUETOOTH_OFF; + case USB_DISCONNECTED: + returnReason = SmartDeviceLinkDisconnectedReason.USB_DISCONNECTED; + case REQUEST_WHILE_IN_NONE_HMI_LEVEL: + returnReason = SmartDeviceLinkDisconnectedReason.REQUEST_WHILE_IN_NONE_HMI_LEVEL; + case TOO_MANY_REQUESTS: + returnReason = SmartDeviceLinkDisconnectedReason.TOO_MANY_REQUESTS; + case DRIVER_DISTRACTION_VIOLATION: + returnReason = SmartDeviceLinkDisconnectedReason.DRIVER_DISTRACTION_VIOLATION; + case LANGUAGE_CHANGE: + returnReason = SmartDeviceLinkDisconnectedReason.LANGUAGE_CHANGE; + case MASTER_RESET: + returnReason = SmartDeviceLinkDisconnectedReason.MASTER_RESET; + case FACTORY_DEFAULTS: + returnReason = SmartDeviceLinkDisconnectedReason.FACTORY_DEFAULTS; + } + + return returnReason; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkInterfaceAvailability.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkInterfaceAvailability.java new file mode 100755 index 000000000..d50e84c46 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SmartDeviceLinkInterfaceAvailability.java @@ -0,0 +1,9 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum SmartDeviceLinkInterfaceAvailability { + SMARTDEVICELINK_INTERFACE_AVAILABLE, + SMARTDEVICELINK_INTERFACE_UNAVAILABLE; +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SpeechCapabilities.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SpeechCapabilities.java new file mode 100755 index 000000000..f47f285b7 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SpeechCapabilities.java @@ -0,0 +1,16 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum SpeechCapabilities { + TEXT, + SAPI_PHONEMES, + LHPLUS_PHONEMES, + PRE_RECORDED, + SILENCE; + + public static SpeechCapabilities valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SystemContext.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SystemContext.java new file mode 100755 index 000000000..b2619a7aa --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/SystemContext.java @@ -0,0 +1,31 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +import java.util.EnumSet; + +public enum SystemContext { + SYSCTXT_MAIN("MAIN"), + SYSCTXT_VRSESSION("VRSESSION"), + SYSCTXT_MENU("MENU"); + + String internalName; + + private SystemContext(String internalName) { + this.internalName = internalName; + } + + public String toString() { + return this.internalName; + } + + public static SystemContext valueForString(String value) { + for (SystemContext anEnum : EnumSet.allOf(SystemContext.class)) { + if (anEnum.toString().equals(value)) { + return anEnum; + } + } + return null; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TBTState.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TBTState.java new file mode 100755 index 000000000..eb818d7d7 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TBTState.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum TBTState { + ROUTE_CANCELLED, + DESTINATION_REACHED, + ROUTE_UPDATE_MANUAL, + OFF_ROUTE_UPDATE, + OFF_ROUTE_DECLINED, + ROUTE_ACCEPTED, + ROUTE_REFUSED; + + public static TBTState valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TextAlignment.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TextAlignment.java new file mode 100755 index 000000000..6ed72080f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TextAlignment.java @@ -0,0 +1,14 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum TextAlignment { + LEFT_ALIGNED, + RIGHT_ALIGNED, + CENTERED; + + public static TextAlignment valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TextFieldName.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TextFieldName.java new file mode 100755 index 000000000..666708954 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TextFieldName.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum TextFieldName { + mainField1, + mainField2, + statusBar, + mediaClock, + mediaTrack, + alertText1, + alertText2; + + public static TextFieldName valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TriggerSource.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TriggerSource.java new file mode 100755 index 000000000..1d5428225 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/TriggerSource.java @@ -0,0 +1,30 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +import java.util.EnumSet; + +public enum TriggerSource { + TS_MENU("MENU"), + TS_VR("VR"); + + String internalName; + + private TriggerSource(String internalName) { + this.internalName = internalName; + } + + public String toString() { + return this.internalName; + } + + public static TriggerSource valueForString(String value) { + for (TriggerSource anEnum : EnumSet.allOf(TriggerSource.class)) { + if (anEnum.toString().equals(value)) { + return anEnum; + } + } + return null; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/UpdateMode.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/UpdateMode.java new file mode 100755 index 000000000..0938ef6fc --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/UpdateMode.java @@ -0,0 +1,15 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum UpdateMode { + COUNTUP, + COUNTDOWN, + PAUSE, + RESUME; + + public static UpdateMode valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/VrCapabilities.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/VrCapabilities.java new file mode 100755 index 000000000..74fc25f09 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/proxy/rpc/enums/VrCapabilities.java @@ -0,0 +1,12 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.proxy.rpc.enums; + +public enum VrCapabilities { + Text; + + public static VrCapabilities valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/syncConnection/ISmartDeviceLinkConnectionListener.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/syncConnection/ISmartDeviceLinkConnectionListener.java new file mode 100755 index 000000000..e70bdfa59 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/syncConnection/ISmartDeviceLinkConnectionListener.java @@ -0,0 +1,23 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.syncConnection; + +import com.smartdevicelink.protocol.ProtocolMessage; +import com.smartdevicelink.protocol.enums.SessionType; + +public interface ISmartDeviceLinkConnectionListener { + public void onTransportDisconnected(String info); + + public void onTransportError(String info, Exception e); + + public void onProtocolMessageReceived(ProtocolMessage msg); + + public void onProtocolSessionStarted(SessionType sessionType, + byte sessionID, byte version, String correlationID); + + public void onProtocolSessionEnded(SessionType sessionType, + byte sessionID, String correlationID); + + public void onProtocolError(String info, Exception e); +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/syncConnection/SmartDeviceLinkConnection.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/syncConnection/SmartDeviceLinkConnection.java new file mode 100755 index 000000000..1eeb0acfa --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/syncConnection/SmartDeviceLinkConnection.java @@ -0,0 +1,169 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.syncConnection; + +import com.smartdevicelink.exception.SmartDeviceLinkException; +import com.smartdevicelink.protocol.AbstractProtocol; +import com.smartdevicelink.protocol.IProtocolListener; +import com.smartdevicelink.protocol.ProtocolMessage; +import com.smartdevicelink.protocol.SmartDeviceLinkProtocol; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.transport.BTTransport; +import com.smartdevicelink.transport.BaseTransportConfig; +import com.smartdevicelink.transport.ITransportListener; +import com.smartdevicelink.transport.SmartDeviceLinkTransport; +import com.smartdevicelink.transport.TCPTransport; +import com.smartdevicelink.transport.TCPTransportConfig; +import com.smartdevicelink.transport.TransportType; + +public class SmartDeviceLinkConnection implements IProtocolListener, ITransportListener { + + SmartDeviceLinkTransport _transport = null; + AbstractProtocol _protocol = null; + ISmartDeviceLinkConnectionListener _connectionListener = null; + + // Thread safety locks + Object TRANSPORT_REFERENCE_LOCK = new Object(); + Object PROTOCOL_REFERENCE_LOCK = new Object(); + + public SmartDeviceLinkConnection(ISmartDeviceLinkConnectionListener listener, BaseTransportConfig transportConfig) { + _connectionListener = listener; + + // Initialize the transport + synchronized(TRANSPORT_REFERENCE_LOCK) { + // Ensure transport is null + if (_transport != null) { + if (_transport.getIsConnected()) { + _transport.disconnect(); + } + _transport = null; + } + + if (transportConfig.getTransportType() == TransportType.BLUETOOTH) + { + _transport = new BTTransport(this); + } + else if (transportConfig.getTransportType() == TransportType.TCP) + { + _transport = new TCPTransport((TCPTransportConfig) transportConfig, this); + } + } + + // Initialize the protocol + synchronized(PROTOCOL_REFERENCE_LOCK) { + // Ensure protocol is null + if (_protocol != null) { + _protocol = null; + } + + _protocol = new SmartDeviceLinkProtocol(this); + } + } + + public void closeConnection(byte rpcSessionID) { + synchronized(PROTOCOL_REFERENCE_LOCK) { + if (_protocol != null) { + // If transport is still connected, sent EndProtocolSessionMessage + if (_transport != null && _transport.getIsConnected()) { + _protocol.EndProtocolSession(SessionType.RPC, rpcSessionID); + } + _protocol = null; + } // end-if + } + + synchronized (TRANSPORT_REFERENCE_LOCK) { + if (_transport != null) { + _transport.disconnect(); + } + _transport = null; + } + } + + public void startTransport() throws SmartDeviceLinkException { + _transport.openConnection(); + } + + public Boolean getIsConnected() { + + // If _transport is null, then it can't be connected + if (_transport == null) { + return false; + } + + return _transport.getIsConnected(); + } + + public void sendMessage(ProtocolMessage msg) { + _protocol.SendMessage(msg); + } + + @Override + public void onTransportBytesReceived(byte[] receivedBytes, + int receivedBytesLength) { + // Send bytes to protocol to be interpreted + synchronized(PROTOCOL_REFERENCE_LOCK) { + if (_protocol != null) { + _protocol.HandleReceivedBytes(receivedBytes, receivedBytesLength); + } + } + } + + @Override + public void onTransportConnected() { + synchronized(PROTOCOL_REFERENCE_LOCK){ + if(_protocol != null){ + _protocol.StartProtocolSession(SessionType.RPC); + } + } + } + + @Override + public void onTransportDisconnected(String info) { + // Pass directly to connection listener + _connectionListener.onTransportDisconnected(info); + } + + @Override + public void onTransportError(String info, Exception e) { + // Pass directly to connection listener + _connectionListener.onTransportError(info, e); + } + + @Override + public void onProtocolMessageBytesToSend(byte[] msgBytes, int offset, + int length) { + // Protocol has packaged bytes to send, pass to transport for transmission + synchronized(TRANSPORT_REFERENCE_LOCK) { + if (_transport != null) { + _transport.sendBytes(msgBytes, offset, length); + } + } + } + + @Override + public void onProtocolMessageReceived(ProtocolMessage msg) { + _connectionListener.onProtocolMessageReceived(msg); + } + + @Override + public void onProtocolSessionStarted(SessionType sessionType, + byte sessionID, byte version, String correlationID) { + _connectionListener.onProtocolSessionStarted(sessionType, sessionID, version, correlationID); + } + + @Override + public void onProtocolSessionEnded(SessionType sessionType, byte sessionID, + String correlationID) { + _connectionListener.onProtocolSessionEnded(sessionType, sessionID, correlationID); + } + + @Override + public void onProtocolError(String info, Exception e) { + _connectionListener.onProtocolError(info, e); + } + + public TransportType getCurrentTransportType() { + return _transport.getTransportType(); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/DiagLevel.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/DiagLevel.java new file mode 100755 index 000000000..f4b326e5a --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/DiagLevel.java @@ -0,0 +1,54 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace; + +import com.smartdevicelink.trace.enums.DetailLevel; +import com.smartdevicelink.trace.enums.Mod; + +public class DiagLevel { + + static private DetailLevel[] levels; + + static { // this is a static c-tor!! + levels = new DetailLevel[Mod.values().length]; + setAllLevels(DetailLevel.OFF); + } + + public static void setAllLevels(DetailLevel thisDetail) { + for (int i=0; i < levels.length; i++) { + levels[i] = thisDetail; // + } + } + + public static void setLevel(Mod thisMod, DetailLevel thisDetail) { + levels[thisMod.ordinal()] = thisDetail; + } + + public static DetailLevel getLevel(Mod thisMod) { + return levels[thisMod.ordinal()]; + } + + public static boolean isValidDetailLevel(String dtString) { + // Assume false + Boolean isValid = false; + + if (dtString.equalsIgnoreCase("verbose")) + isValid = true; + else if (dtString.equalsIgnoreCase("terse")) + isValid = true; + else if (dtString.equalsIgnoreCase("off")) + isValid = true; + + return isValid; + } + + public static DetailLevel toDetailLevel(String dtString) { + DetailLevel dt = DetailLevel.OFF; + if (dtString.equalsIgnoreCase("verbose")) + dt = DetailLevel.VERBOSE; + else if (dtString.equalsIgnoreCase("terse")) + dt = DetailLevel.TERSE; + return dt; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/ISTListener.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/ISTListener.java new file mode 100755 index 000000000..b4050d103 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/ISTListener.java @@ -0,0 +1,8 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace; + +public interface ISTListener { + void logXmlMsg(String msg, String token); +} // end-interface diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/Mime.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/Mime.java new file mode 100755 index 000000000..d2b28dfd2 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/Mime.java @@ -0,0 +1,186 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace; + +public class Mime { + + private static String m_base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + public static String base64Encode(String str) { + String b64String = ""; + try { + byte[] strBytes = str.getBytes("US-ASCII"); + b64String = base64Encode(strBytes); + } catch (Exception ex) { + // Don't care? + } // end-catch + return b64String; + } // end-method + + public static String base64Encode(byte bytesToEncode[]) { + return base64Encode(bytesToEncode, 0, bytesToEncode.length); + } // end-method + + public static String base64Encode(byte bytesToEncode[], int offset, int length) { + StringBuilder sb = new StringBuilder(); + + int idxin = 0; + int b64idx = 0; + + for (idxin=offset;idxin < offset + length;idxin++) { + switch ((idxin-offset) % 3) { + case 0: + b64idx = (bytesToEncode[idxin] >> 2) & 0x3f; + break; + case 1: + b64idx = (bytesToEncode[idxin] >> 4) & 0x0f; + b64idx |= ((bytesToEncode[idxin-1] << 4)& 0x30); + break; + case 2: + b64idx = (bytesToEncode[idxin] >> 6) & 0x03; + b64idx |= ((bytesToEncode[idxin-1] << 2)& 0x3c); + sb.append(m_base64Chars.charAt(b64idx)); + b64idx = bytesToEncode[idxin] & 0x3f; + break; + } // end-switch + sb.append(m_base64Chars.charAt(b64idx)); + } // end-for + + switch ((idxin-offset) % 3) { + case 0: + break; + case 1: + b64idx = (bytesToEncode[idxin-1] << 4) & 0x30; + sb.append(m_base64Chars.charAt(b64idx)); + sb.append("=="); + break; + case 2: + b64idx = ((bytesToEncode[idxin-1] << 2)& 0x3c); + sb.append(m_base64Chars.charAt(b64idx)); + sb.append('='); + break; + } // end-switch + + return sb.toString(); + + } // end-method + + private byte[] base64Decode(String base64String) { + byte[] outBytes = null; + byte[] base64ASCIIString = null; + final String ASCII_Encoding = "US-ASCII"; + + // Convert b64 string to raw bytes + try { + base64ASCIIString = base64String.getBytes(ASCII_Encoding); + } catch (Exception ex) { + return null; + } + + if (!m_decodeInitComplete) { + m_decodeInitComplete = true; + initForDecode(); + } // end-if + + int numInChars = base64ASCIIString.length; + + if ((numInChars % 4) > 0) { + return null; + } // end-if + + int numOutBytes = base64ASCIIString.length / 4; + numOutBytes *= 3; + int eqpos = base64String.indexOf("="); + if (eqpos >= 0) { + numOutBytes--; + if (base64String.substring(eqpos).indexOf("==") >= 0) { + numOutBytes--; + } // end-if + } // end-if + outBytes = new byte[numOutBytes]; + + byte b64idxbits = 0x00; + int iidx = 0, oidx = 0; + byte writeByte = 0x00; + byte b64ASCIIChar = 0x00; + for (iidx=0, oidx=0;iidx < numInChars;iidx++) { + b64ASCIIChar = base64ASCIIString[iidx]; + if (b64ASCIIChar == 0x3d /*'='*/) { + return outBytes; + } // end-if + + if (!isb64char(b64ASCIIChar)) { + return null; + } // end-if + + switch (iidx % 4) { + case 0: + break; + case 1: + b64idxbits = b64decode[base64ASCIIString[iidx-1]]; + writeByte = (byte)((b64idxbits << 2) | ((b64decode[b64ASCIIChar] >> 4) & 0x03)); + outBytes[oidx++] = writeByte; + break; + case 2: + b64idxbits = b64decode[base64ASCIIString[iidx-1]]; + writeByte = (byte)(((b64idxbits << 4) & 0xf0) | ((b64decode[b64ASCIIChar] >> 2) & 0x0f)); + outBytes[oidx++] = writeByte; + break; + case 3: + b64idxbits = b64decode[base64ASCIIString[iidx-1]]; + writeByte = (byte)(((b64idxbits << 6) & 0xc0) | ((b64decode[b64ASCIIChar]) & 0x3f)); + outBytes[oidx++] = writeByte; + break; + } // end-switch + } // end-for + + return outBytes; + + } // end-method + + + private static byte[] b64decode = new byte[256]; + // A-Z is 0x41-0x5a + // a-z is 0x61-0x7a + // 0-9 is 0x30-0x39 + // + is 0x2b + // / is 0x2f + + private static boolean m_decodeInitComplete = false; + + private void initForDecode() { + int aidx = 0; + int lidx = 0; + // Set A-Z + for (aidx=0x41, lidx=0;aidx <= 0x5a;aidx++, lidx++) { + b64decode[aidx] = (byte)lidx; + } // end-for + // Set a-z + for (aidx=0x61;aidx <= 0x7a;aidx++, lidx++) { + b64decode[aidx] = (byte)lidx; + } // end-for + // Set 0-9 + for (aidx=0x30;aidx <= 0x39;aidx++, lidx++) { + b64decode[aidx] = (byte)lidx; + } // end-for + // Set '+' + b64decode[0x2b] = (byte)lidx++; + // Set '/' + b64decode[0x2f] = (byte)lidx++; + } // end-method + + private boolean isb64char(byte b) { + // A-Z is 0x41-0x5a + // a-z is 0x61-0x7a + // 0-9 is 0x30-0x39 + // + is 0x2b + // / is 0x2f + return ( (b >= 0x41 && b <= 0x5a) + || (b >= 0x61 && b <= 0x7a) + || (b >= 0x30 && b <= 0x39) + || (b == 0x2b) + || (b == 0x2f) + ); + } // end-method +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/OpenRPCMessage.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/OpenRPCMessage.java new file mode 100755 index 000000000..47ea747f5 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/OpenRPCMessage.java @@ -0,0 +1,88 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; + +import com.smartdevicelink.proxy.RPCMessage; +import com.smartdevicelink.proxy.RPCStruct; + +class OpenRPCMessage extends RPCMessage { + private OpenRPCMessage() {super("");} + public OpenRPCMessage(RPCMessage rpcm) { + super(rpcm); + } // end-method + + public OpenRPCMessage(RPCStruct rpcs) { + super(rpcs); + } // end-method + + public String msgDump() { + StringBuilder pd = new StringBuilder(); + + pd.append(this.getFunctionName() + " " + this.getMessageType()); + + msgDump(pd); + + return pd.toString(); + } // end-method + + public void msgDump(StringBuilder pd) { + pd.append("["); + + dumpParams(parameters, pd); + + pd.append("]"); + + return; + } // end-method + + private void dumpParams(Hashtable ht, StringBuilder pd) { + Iterator keySet = ht.keySet().iterator(); + Object obj = null; + String key = ""; + boolean isFirstParam = true; + + while (keySet.hasNext()) { + key = (String)keySet.next(); + obj = ht.get(key); + if (isFirstParam) { + isFirstParam = false; + } else { + pd.append(", "); + } // end-if + + dumpParamNode(key, obj, pd); + + } // end-while + } // end-method + + private void dumpParamNode(String key, Object obj, StringBuilder pd) { + + if (obj instanceof Hashtable) { + pd.append("["); + dumpParams((Hashtable)obj, pd); + pd.append("]"); + } else if (obj instanceof RPCStruct) { + pd.append("["); + OpenRPCMessage orpcm = new OpenRPCMessage((RPCStruct)obj); + orpcm.msgDump(pd); + pd.append("]"); + } else if (obj instanceof Vector) { + pd.append("["); + Vector vec = (Vector)obj; + for (int idx=0;idx < vec.size();idx++) { + if (idx > 0) { + pd.append(", "); + } + dumpParamNode(key, vec.elementAt(idx), pd); + } // end-for + pd.append("]"); + } else { + pd.append("\"" + key + "\" = \"" + obj.toString() + "\""); + } + } // end-method +} // end-class OpenRPCMessage diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/SyncTrace.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/SyncTrace.java new file mode 100755 index 000000000..cc95ae0fc --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/SyncTrace.java @@ -0,0 +1,466 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace; + +import java.sql.Timestamp; + +import android.bluetooth.BluetoothDevice; +import android.os.Build; +import android.os.Debug; +import android.os.Process; + +import com.smartdevicelink.protocol.ProtocolFrameHeader; +import com.smartdevicelink.protocol.enums.FrameDataControlFrameType; +import com.smartdevicelink.protocol.enums.FrameType; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.proxy.RPCMessage; +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.RPCResponse; +import com.smartdevicelink.trace.enums.DetailLevel; +import com.smartdevicelink.trace.enums.InterfaceActivityDirection; +import com.smartdevicelink.trace.enums.Mod; +import com.smartdevicelink.transport.SiphonServer; +import com.smartdevicelink.util.BitConverter; +import com.smartdevicelink.util.DebugTool; +import com.smartdevicelink.util.NativeLogTool; + +/* This class handles the global TraceSettings as requested by the users either through the combination of the following + 1. System defaults + 2. Application XML config + 3. Programmatic requests from application itself + + It is manifested in the <SmartDeviceLink>...</SmartDeviceLink> tags + */ + +public class SyncTrace { + private static final String SmartDeviceLink_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + + static boolean canWriteLogs = false; + + public static final String SYSTEM_LOG_TAG = "SyncTrace"; + + private static long baseTics = java.lang.System.currentTimeMillis(); + private final static String KeyStr = SmartDeviceLink_LIB_TRACE_KEY; + private static boolean acceptAPITraceAdjustments = true; + + protected static ISTListener m_appTraceListener = null; + + /// + /// The PUBLIC interface to SyncTrace starts here + /// + + + public static void setAcceptAPITraceAdjustments(Boolean APITraceAdjustmentsAccepted) { + if (APITraceAdjustmentsAccepted != null) { + acceptAPITraceAdjustments = APITraceAdjustmentsAccepted; + } + } + + public static boolean getAcceptAPITraceAdjustments() { + return acceptAPITraceAdjustments; + } + + public static void setAppTraceListener(ISTListener listener) { + m_appTraceListener = listener; + } // end-method + + public static void setTracingEnable(Boolean enable) { + if (enable != null) { + canWriteLogs = enable; + } + } // end-method + + public static void setAppTraceLevel(DetailLevel dt) { + if ( dt != null && acceptAPITraceAdjustments) + DiagLevel.setLevel(Mod.app, dt); + } // end-method + + public static void setProxyTraceLevel(DetailLevel dt) { + if (dt != null && acceptAPITraceAdjustments) + DiagLevel.setLevel(Mod.proxy, dt); + } // end-method + + public static void setRpcTraceLevel(DetailLevel dt) { + if (dt != null && acceptAPITraceAdjustments) + DiagLevel.setLevel(Mod.rpc, dt); + } // end-method + + public static void setMarshallingTraceLevel(DetailLevel dt) { + if (dt != null && acceptAPITraceAdjustments) + DiagLevel.setLevel(Mod.mar, dt); + } // end-method + + public static void setProtocolTraceLevel(DetailLevel dt) { + if (dt != null && acceptAPITraceAdjustments) + DiagLevel.setLevel(Mod.proto, dt); + } // end-method + + public static void setTransportTraceLevel(DetailLevel dt) { + if (dt != null && acceptAPITraceAdjustments) + DiagLevel.setLevel(Mod.tran, dt); + } // end-method + + private static String encodeTraceMessage(long timestamp, Mod module, InterfaceActivityDirection msgDirection, String msgBodyXml) { + StringBuilder sb = new StringBuilder("<msg><dms>"); + sb.append(timestamp); + sb.append("</dms><pid>"); + sb.append(Process.myPid()); + sb.append("</pid><tid>"); + sb.append(Thread.currentThread().getId()); + sb.append("</tid><mod>"); + sb.append(module.toString()); + sb.append("</mod>"); + if (msgDirection != InterfaceActivityDirection.None) { + sb.append("<dir>"); + sb.append(interfaceActivityDirectionToString(msgDirection)); + sb.append("</dir>"); + } // end-if + sb.append(msgBodyXml); + sb.append("</msg>"); + + return sb.toString(); + } // end-method + + private static String interfaceActivityDirectionToString(InterfaceActivityDirection iaDirection) { + String str = ""; + switch (iaDirection) { + case Receive: + str = "rx"; + break; + case Transmit: + str = "tx"; + break; + } // end-switch + return str; + } // end-method + + static String B64EncodeForXML(String data) { + return Mime.base64Encode(data); + } // end-method + + public static void logProxyEvent(String eventText, String token) { + if (DiagLevel.getLevel(Mod.proxy) == DetailLevel.OFF || !token.equals(KeyStr)) { + return; + } // end-if + + String msg = SyncTrace.B64EncodeForXML(eventText); + String xml = SyncTrace.encodeTraceMessage(SyncTrace.getBaseTicsDelta(), Mod.proxy, InterfaceActivityDirection.None, "<d>" + msg + "</d>"); + writeXmlTraceMessage(xml); + } // end-method + + public static void logAppEvent(String eventText) { + if (DiagLevel.getLevel(Mod.app) == DetailLevel.OFF) { + return; + } // end-if + + long timestamp = SyncTrace.getBaseTicsDelta(); + String msg = SyncTrace.B64EncodeForXML(eventText); + String xml = SyncTrace.encodeTraceMessage(timestamp, Mod.app, InterfaceActivityDirection.None, "<d>" + msg + "</d>"); + writeXmlTraceMessage(xml); + } // end-method + + public static void logRPCEvent(InterfaceActivityDirection msgDirection, RPCMessage rpcMsg, String token) { + DetailLevel dl = DiagLevel.getLevel(Mod.rpc); + if (dl == DetailLevel.OFF || !token.equals(KeyStr)) { + return; + } // end-if + + long timestamp = SyncTrace.getBaseTicsDelta(); + String xml = SyncTrace.encodeTraceMessage(timestamp, Mod.rpc, msgDirection, rpc2Xml(dl, rpcMsg)); + writeXmlTraceMessage(xml); + } // end-method + + private static String rpc2Xml(DetailLevel dl, RPCMessage rpcMsg) { + StringBuilder rpcAsXml = new StringBuilder(); + rpcAsXml.append("<op>"); + rpcAsXml.append(rpcMsg.getFunctionName()); + rpcAsXml.append("</op>"); + boolean hasCorrelationID = false; + Integer correlationID = -1; + if (rpcMsg instanceof RPCRequest) { + hasCorrelationID = true; + correlationID = ((RPCRequest)rpcMsg).getCorrelationID(); + } else if (rpcMsg instanceof RPCResponse) { + hasCorrelationID = true; + correlationID = ((RPCResponse)rpcMsg).getCorrelationID(); + } // end-if + if (hasCorrelationID) { + rpcAsXml.append("<cid>"); + rpcAsXml.append(correlationID); + rpcAsXml.append("</cid>"); + } // end-if + rpcAsXml.append("<type>"); + rpcAsXml.append(rpcMsg.getMessageType()); + rpcAsXml.append("</type>"); + + if (dl == DetailLevel.VERBOSE) { + OpenRPCMessage orpcmsg = new OpenRPCMessage(rpcMsg); + String rpcParamList = orpcmsg.msgDump(); + String msg = SyncTrace.B64EncodeForXML(rpcParamList); + rpcAsXml.append("<d>"); + rpcAsXml.append(msg); + rpcAsXml.append("</d>"); + } // end-if + return rpcAsXml.toString(); + } // end-method + + public static void logMarshallingEvent(InterfaceActivityDirection msgDirection, byte[] marshalledMessage, String token) { + DetailLevel dl = DiagLevel.getLevel(Mod.mar); + if (dl == DetailLevel.OFF || !token.equals(KeyStr)) { + return; + } // end-fif + + long timestamp = SyncTrace.getBaseTicsDelta(); + StringBuilder msg = new StringBuilder(); + msg.append("<sz>"); + msg.append(marshalledMessage.length); + msg.append("</sz>"); + if (dl == DetailLevel.VERBOSE) { + msg.append("<d>"); + msg.append(Mime.base64Encode(marshalledMessage)); + msg.append("</d>"); + } // end-if + String xml = SyncTrace.encodeTraceMessage(timestamp, Mod.mar, msgDirection, msg.toString()); + writeXmlTraceMessage(xml); + } // end-method + + public static void logProtocolEvent(InterfaceActivityDirection frameDirection, ProtocolFrameHeader frameHeader, byte[] frameData, int frameDataOffset, int frameDataLength, String token) { + DetailLevel dl = DiagLevel.getLevel(Mod.proto); + if (dl == DetailLevel.OFF || !token.equals(KeyStr)) { + return; + } // end-if + + StringBuffer protoMsg = new StringBuffer(); + protoMsg.append("<frame>"); + protoMsg.append(SyncTrace.getProtocolFrameHeaderInfo(frameHeader, frameData)); + if (dl == DetailLevel.VERBOSE) { + if (frameData != null && frameDataLength > 0) { + protoMsg.append("<d>"); + String bytesInfo = ""; + bytesInfo = Mime.base64Encode(frameData, frameDataOffset, frameDataLength); + protoMsg.append(bytesInfo); + protoMsg.append("</d>"); + } // end-if + } // end-if + protoMsg.append("</frame>"); + String xml = SyncTrace.encodeTraceMessage(SyncTrace.getBaseTicsDelta(), Mod.proto, frameDirection, protoMsg.toString()); + writeXmlTraceMessage(xml); + } // end-method + + private static String getProtocolFrameType(FrameType f) { + if (f == FrameType.Control) + return "Control"; + else if (f == FrameType.Consecutive) + return "Consecutive"; + else if (f == FrameType.First) + return "First"; + else if (f == FrameType.Single) + return "Single"; + + return "Unknown"; + } // end-method + + private static String getProtocolSessionType(SessionType serviceType) { + String s; + if (serviceType == SessionType.RPC ) + s = "rpc"; + else if (serviceType == SessionType.Bulk_Data) + s = "bulk"; + else + s = "Unknown"; + return s; + } // end-method + + private static String getProtocolFrameHeaderInfo(ProtocolFrameHeader hdr, byte[] buf) { + StringBuilder sb = new StringBuilder(); + sb.append("<hdr>"); + sb.append("<ver>"); + sb.append(hdr.getVersion()); + sb.append("</ver><cmp>"); + sb.append(hdr.isCompressed()); + sb.append("</cmp><ft>"); + sb.append(getProtocolFrameType(hdr.getFrameType())); + sb.append("</ft><st>"); + sb.append(getProtocolSessionType(hdr.getSessionType())); + sb.append("</st><sid>"); + sb.append(hdr.getSessionID()); + sb.append("</sid><sz>"); + sb.append(hdr.getDataSize()); + sb.append("</sz>"); + + int frameData = hdr.getFrameData(); + if (hdr.getFrameType() == FrameType.Control) { + sb.append("<ca>"); + if (frameData == FrameDataControlFrameType.StartSession.getValue()) + sb.append("StartSession"); + else if (frameData == FrameDataControlFrameType.StartSessionACK.getValue()) + sb.append("StartSessionACK"); + else if (frameData == FrameDataControlFrameType.StartSessionNACK.getValue()) + sb.append("StartSessionNACK"); + else if (frameData == FrameDataControlFrameType.EndSession.getValue()) + sb.append("EndSession"); + sb.append("</ca>"); + } else if (hdr.getFrameType() == FrameType.Consecutive ) { + sb.append("<fsn>"); + if (frameData == 0 ) + sb.append("lastFrame"); + else + sb.append(String.format("%02X",frameData)); + sb.append("</fsn>"); + } else if (hdr.getFrameType() == FrameType.First ) { + int totalSize = BitConverter.intFromByteArray(buf, 0); + int numFrames = BitConverter.intFromByteArray(buf, 4); + sb.append("<total>" + totalSize + "</total><numframes>" + numFrames + "</numframes>"); + } else if (hdr.getFrameType() == FrameType.Single ) { + sb.append("<single/>"); + } + + sb.append("</hdr>"); + + return sb.toString(); + } // end-method + + public static String getBTDeviceInfo(BluetoothDevice btDevice) { + StringBuilder sb = new StringBuilder(); + sb.append("<btp>"); + String btdn = btDevice.getName(); + sb.append("<btn>"); + sb.append(SyncTrace.B64EncodeForXML(btdn)); + sb.append("</btn>"); + sb.append("<bta>" + btDevice.getAddress() + "</bta>"); + sb.append("<bts>" + btDevice.getBondState() + "</bts>"); + sb.append("</btp>"); + return sb.toString(); + } // end-method + + public static void logTransportEvent(String preamble, String transportSpecificInfoXml, InterfaceActivityDirection msgDirection, byte buf[], int byteLength, String token) { + logTransportEvent(preamble, transportSpecificInfoXml, msgDirection, buf, 0, byteLength, token); + } // end-method + + private static void checkB64(String x, byte[] buf, int offset, int byteLength) { + if ((x.length() % 4) != 0) { + NativeLogTool.logWarning(SyncTrace.SYSTEM_LOG_TAG, "b64 string length (" + x.length() + ") isn't multiple of 4: buf.length=" + buf.length + ", offset=" + offset + ", len=" + byteLength); + } // end-if + } // end-method + + public static void logTransportEvent(String preamble, String transportSpecificInfoXml, InterfaceActivityDirection msgDirection, byte buf[], int offset, int byteLength, String token) { + if (DiagLevel.getLevel(Mod.tran) == DetailLevel.OFF || !token.equals(KeyStr)) { + return; + } // end-if + + StringBuilder msg = new StringBuilder(); + if (transportSpecificInfoXml != null && transportSpecificInfoXml.length() > 0) { + msg.append(transportSpecificInfoXml); + } // end-if + if (preamble != null && preamble.length() > 0) { + msg.append("<desc>"); + msg.append(preamble); + msg.append("</desc>"); + } // end-if + if (buf != null) { + msg.append("<sz>"); + msg.append(byteLength); + msg.append("</sz>"); + DetailLevel dl = DiagLevel.getLevel(Mod.tran); + if (dl == DetailLevel.VERBOSE) { + if (buf != null && byteLength > 0) { + msg.append("<d>"); + String bytesInfo = Mime.base64Encode(buf, offset, byteLength); + checkB64(bytesInfo, buf, offset, byteLength); + msg.append(bytesInfo); + msg.append("</d>"); + } // end-if + } // end-if + } // end-if + String xml = SyncTrace.encodeTraceMessage(SyncTrace.getBaseTicsDelta(), Mod.tran, msgDirection, msg.toString()); + writeXmlTraceMessage(xml); + } // end-method + + // Package-scoped + static long getBaseTicsDelta() { + return java.lang.System.currentTimeMillis() - getBaseTics(); + } + + // Package-scoped + static long getBaseTics() { + return baseTics; + } // end-method + + public static Boolean writeMessageToSiphonServer(String info) { + return SiphonServer.sendFormattedTraceMessage(info); + } + + private static void writeXmlTraceMessage(String msg) { + try { + // Attempt to write formatted message to the Siphon + if (false == writeMessageToSiphonServer(msg)) { + // If writing to the Siphon fails, write to the native log + NativeLogTool.logInfo(SyncTrace.SYSTEM_LOG_TAG, msg); + } + + ISTListener localTraceListener = m_appTraceListener; + + if (localTraceListener != null) { + try { + localTraceListener.logXmlMsg(msg, KeyStr); + } catch (Exception ex) { + DebugTool.logError("Failure calling ISTListener: " + ex.toString(), ex); + } // end-catch + } // end-if + } catch (Exception ex) { + NativeLogTool.logError(SyncTrace.SYSTEM_LOG_TAG, "Failure writing XML trace message: " + ex.toString()); + } + } // end-method + + // Package-scoped + public static String getLogHeader(String dumpReason, int seqNo) { + final String Sep = "-"; + StringBuilder write = new StringBuilder("<?xml version=\"1.0\"?>" + "<logs>"); + write.append("<info>"); + StringBuilder infoBlock = new StringBuilder(); + String hostInfo = Build.BRAND + Sep + Build.MANUFACTURER + Sep + Build.MODEL + "(" + Build.HOST + ")"; + infoBlock.append("<host>" + SyncTrace.B64EncodeForXML(hostInfo) + "</host>"); + String osv = Build.VERSION.RELEASE + " (" + Build.VERSION.CODENAME + ")"; + infoBlock.append("<osv>" + SyncTrace.B64EncodeForXML(osv) + "</osv>"); + infoBlock.append(TraceDeviceInfo.getTelephonyHeader()); + + long heapSize = Debug.getNativeHeapFreeSize() / 1024; + long heapAllocated = Debug.getNativeHeapAllocatedSize() / 1024; + infoBlock.append("<mem><hf>" + heapSize + "KB</hf><ha>" + heapAllocated + "KB</ha></mem>"); + infoBlock.append("<np>" + Runtime.getRuntime().availableProcessors() + "</np>"); + infoBlock.append("<pid>" + Process.myPid() + "</pid>"); + infoBlock.append("<tid>" + Thread.currentThread().getId() + "</tid>"); + + Timestamp stamp = new Timestamp(SyncTrace.getBaseTics()); + String GMTtime = stamp.toGMTString().substring(0, 19); + long fracSec = stamp.getNanos() / 1000000; // divide by a million + String fracSecStr = String.format("%03d", fracSec); + infoBlock.append("<utc>" + GMTtime + "." + fracSecStr + "</utc>"); + + infoBlock.append(TraceDeviceInfo.getLogHeaderBluetoothPairs()); + infoBlock.append(getSmartDeviceLinkTraceRoot(dumpReason, seqNo)); + + write.append(infoBlock); + + write.append("</info>" + "<msgs>"); + return write.toString(); + } // end-method + + private static String getSmartDeviceLinkTraceRoot(String dumpReason, int seqNo) { + StringBuilder write = new StringBuilder("<SmartDeviceLinktraceroot>" + "<sequencenum>" + seqNo + + "</sequencenum>" + "<dumpreason>" + dumpReason + + "</dumpreason><tracelevel>"); + + write.append("<tran>" + DiagLevel.getLevel(Mod.tran) + "</tran>"); + write.append("<proto>" + DiagLevel.getLevel(Mod.proto) + "</proto>"); + write.append("<mar>" + DiagLevel.getLevel(Mod.mar) + "</mar>"); + write.append("<rpc>" + DiagLevel.getLevel(Mod.rpc) + "</rpc>"); + write.append("<proxy>" + DiagLevel.getLevel(Mod.proxy) + "</proxy>"); + write.append("<app>" + DiagLevel.getLevel(Mod.app) + "</app>"); + + write.append("</tracelevel>"); + write.append("</SmartDeviceLinktraceroot>"); + return write.toString(); + } // end-method +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/TraceDeviceInfo.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/TraceDeviceInfo.java new file mode 100755 index 000000000..6d67aea39 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/TraceDeviceInfo.java @@ -0,0 +1,120 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace; + +import java.util.Iterator; +import java.util.Set; + +import com.smartdevicelink.util.DebugTool; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.telephony.TelephonyManager; + +public class TraceDeviceInfo { + // http://developer.android.com/guide/topics/data/data-storage.html + + private static TelephonyManager m_telephonyManager; + + // Constructor + public TraceDeviceInfo(TelephonyManager telephonyManager) { + m_telephonyManager = telephonyManager; + } + + public static void setTelephonyManager(TelephonyManager telephonyManager) { + m_telephonyManager = telephonyManager; + } + + public static TelephonyManager getTelephonyManager() { + return m_telephonyManager; + } + + // package scoped + static String getTelephonyHeader() { + // Telephony manager can tell us a few things... + String info = ""; + + if (m_telephonyManager != null) { + try { // getDeviceId() requires android.permission.READ_PHONE_STATE + info = "<deviceid>" + m_telephonyManager.getDeviceId() + "</deviceid>"; + } catch (Exception e1) { + DebugTool.logError("Failure getting telephony device ID: " + e1.toString(), e1); + } + + info = "<pt>"; + switch (m_telephonyManager.getPhoneType()) { + case TelephonyManager.PHONE_TYPE_NONE: + info += "NONE"; + break; + case TelephonyManager.PHONE_TYPE_GSM: + info += "GSM"; + break; + case TelephonyManager.PHONE_TYPE_CDMA: + info += "CDMA"; + break; + default: + info += "UNKNOWN"; + } // end-switch + + info += "</pt>" + "<nt>"; + + switch (m_telephonyManager.getNetworkType()) { + case TelephonyManager.NETWORK_TYPE_UNKNOWN: + info += "UKNOWN"; + break; + case TelephonyManager.NETWORK_TYPE_GPRS: + info += "GPRS"; + break; + case TelephonyManager.NETWORK_TYPE_EDGE: + info += "EDGE"; + break; + case TelephonyManager.NETWORK_TYPE_UMTS: + info += "UMTS"; + break; + case TelephonyManager.NETWORK_TYPE_HSDPA: + info += "HSDPA"; + break; + case TelephonyManager.NETWORK_TYPE_HSUPA: + info += "HSUPA"; + break; + case TelephonyManager.NETWORK_TYPE_HSPA: + info += "HSPA"; + break; + case TelephonyManager.NETWORK_TYPE_CDMA: + info += "CDMA"; + break; + case TelephonyManager.NETWORK_TYPE_EVDO_0: + info += "EVDO_O"; + break; + case TelephonyManager.NETWORK_TYPE_EVDO_A: + info += "EVDO_A"; + break; + case TelephonyManager.NETWORK_TYPE_1xRTT: + info += "1xRTT"; + break; + default: + info += "UNKNOWN"; + break; + } // end-switch + + info += "</nt>"; + } // end-if + return info; + } // end-method + + // Package scoped + static String getLogHeaderBluetoothPairs() { + Set<BluetoothDevice> btDevices = BluetoothAdapter.getDefaultAdapter() + .getBondedDevices(); + + StringBuilder write = new StringBuilder("<btpairs>"); + Iterator<BluetoothDevice> iter = btDevices.iterator(); + while (iter.hasNext()) { + write.append(SyncTrace.getBTDeviceInfo(iter.next())); + } + write.append("</btpairs>"); + + return write.toString(); + } // end-method +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/DetailLevel.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/DetailLevel.java new file mode 100755 index 000000000..b0f3ad886 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/DetailLevel.java @@ -0,0 +1,14 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace.enums; + +public enum DetailLevel { + OFF, + TERSE, + VERBOSE; + + public static DetailLevel valueForString(String value) { + return valueOf(value); + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/InterfaceActivityDirection.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/InterfaceActivityDirection.java new file mode 100755 index 000000000..ce430cb2c --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/InterfaceActivityDirection.java @@ -0,0 +1,10 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace.enums; + +public enum InterfaceActivityDirection { + Transmit, + Receive, + None; +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/Mod.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/Mod.java new file mode 100755 index 000000000..dc16112fd --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/trace/enums/Mod.java @@ -0,0 +1,17 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.trace.enums; + +public enum Mod { + tran, + proto, + mar, + rpc, + app, + proxy; + + public static Mod valueForString(String value) { + return valueOf(value); + } +}; diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BTTransport.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BTTransport.java new file mode 100755 index 000000000..c2a60b80d --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BTTransport.java @@ -0,0 +1,370 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.UUID; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothServerSocket; +import android.bluetooth.BluetoothSocket; + +import com.smartdevicelink.exception.SmartDeviceLinkException; +import com.smartdevicelink.exception.SmartDeviceLinkExceptionCause; +import com.smartdevicelink.trace.SyncTrace; +import com.smartdevicelink.trace.enums.InterfaceActivityDirection; +import com.smartdevicelink.util.DebugTool; + +/** + * Bluetooth Transport Implementation. This transport advertises its existence to SmartDeviceLink by publishing an SDP record and waiting for an incoming connection from SmartDeviceLink. Connection is verified by checking for the SmartDeviceLink UUID. For more detailed information please refer to the <a href="#bluetoothTransport">Bluetooth Transport Guide</a>. + * + */ +public class BTTransport extends SmartDeviceLinkTransport { + //936DA01F9ABD4D9D80C702AF85C822A8 + private final static UUID SMARTDEVICELINK_V4_MOBILE_APPLICATION_SVC_CLASS = new UUID(0x936DA01F9ABD4D9DL, 0x80C702AF85C822A8L); + + private static final String SMARTDEVICELINK_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + + private BluetoothAdapter _adapter = null; + private BluetoothSocket _activeSocket = null; + private InputStream _input = null; + private UUID _listeningServiceUUID = SMARTDEVICELINK_V4_MOBILE_APPLICATION_SVC_CLASS; + private BluetoothAdapterMonitor _bluetoothAdapterMonitor = null; + private TransportReaderThread _transportReader = null; + private OutputStream _output = null; + private BluetoothServerSocket _serverSocket = null; + + // Boolean to monitor if the transport is in a disconnecting state + private boolean _disconnecting = false; + + public BTTransport(ITransportListener transportListener) { + super(transportListener); + } // end-ctor + + public void openConnection () throws SmartDeviceLinkException { + // Get the device's default Bluetooth Adapter + _adapter = BluetoothAdapter.getDefaultAdapter(); + + // Test if Adapter exists + if (_adapter == null) { + throw new SmartDeviceLinkException("No Bluetooth adapter found. Bluetooth adapter must exist to communicate with SmartDeviceLink.", SmartDeviceLinkExceptionCause.BLUETOOTH_ADAPTER_NULL); + } + + // Test if Bluetooth is enabled + try { + if (!_adapter.isEnabled()) { + throw new SmartDeviceLinkException("Bluetooth adapter must be enabled to instantiate a SmartDeviceLinkProxy object.", SmartDeviceLinkExceptionCause.BLUETOOTH_DISABLED); + } + } catch (SecurityException e) { + throw new SmartDeviceLinkException("Insufficient permissions to interact with the Bluetooth Adapter.", SmartDeviceLinkExceptionCause.PERMISSION_DENIED); + } + + // Start BluetoothAdapterMonitor to ensure the Bluetooth Adapter continues to be enabled + _bluetoothAdapterMonitor = new BluetoothAdapterMonitor(_adapter); + + try { + _serverSocket = _adapter.listenUsingRfcommWithServiceRecord("SmartDeviceLinkProxy", _listeningServiceUUID); + } catch (IOException ex) { + + // Test to determine if the bluetooth has been disabled since last check + if (!_adapter.isEnabled()) { + throw new SmartDeviceLinkException("Bluetooth adapter must be on to instantiate a SmartDeviceLinkProxy object.", SmartDeviceLinkExceptionCause.BLUETOOTH_DISABLED); + } + + throw new SmartDeviceLinkException("Could not open connection to SmartDeviceLink.", ex, SmartDeviceLinkExceptionCause.SMARTDEVICELINK_CONNECTION_FAILED); + } + + // Test to ensure serverSocket is not null + if (_serverSocket == null) { + throw new SmartDeviceLinkException("Could not open connection to SmartDeviceLink.", SmartDeviceLinkExceptionCause.SMARTDEVICELINK_CONNECTION_FAILED); + } + + SyncTrace.logTransportEvent("BTTransport: listening for incoming connect to service ID " + _listeningServiceUUID, null, InterfaceActivityDirection.Receive, null, 0, SMARTDEVICELINK_LIB_TRACE_KEY); + + // Setup transportReader thread + _transportReader = new TransportReaderThread(); + _transportReader.setName("TransportReader"); + _transportReader.setDaemon(true); + _transportReader.start(); + + // Initialize the SiphonServer + SiphonServer.init(); + } // end-method + + public void disconnect() { + disconnect(null, null); + } + + /** + * Destroys the transport between SmartDeviceLink and the mobile app + * + * @param msg + * @param ex + */ + private synchronized void disconnect(String msg, Exception ex) { + // If already disconnecting, return + if (_disconnecting) { + // No need to recursively call + return; + } + _disconnecting = true; + + String disconnectMsg = (msg == null ? "" : msg); + if (ex != null) { + disconnectMsg += ", " + ex.toString(); + } // end-if + + SyncTrace.logTransportEvent("BTTransport.disconnect: " + disconnectMsg, null, InterfaceActivityDirection.Transmit, null, 0, SMARTDEVICELINK_LIB_TRACE_KEY); + + try { + if (_transportReader != null) { + _transportReader.halt(); + _transportReader = null; + } + } catch (Exception e) { + DebugTool.logError("Failed to stop transport reader thread.", e); + } // end-catch + + try { + if (_bluetoothAdapterMonitor != null) { + _bluetoothAdapterMonitor.halt(); + _bluetoothAdapterMonitor = null; + } + } catch (Exception e) { + DebugTool.logError("Failed to stop adapter monitor thread.", e); + } + + try { + if (_serverSocket != null) { + _serverSocket.close(); + _serverSocket = null; + } + } catch (Exception e) { + DebugTool.logError("Failed to close serverSocket", e); + } // end-catch + + try { + if (_activeSocket != null) { + _activeSocket.close(); + _activeSocket = null; + } + } catch (Exception e) { + DebugTool.logError("Failed to close activeSocket", e); + } // end-catch + + try { + if (_input != null) { + _input.close(); + _input = null; + } + } catch (Exception e) { + DebugTool.logError("Failed to close input stream", e); + } // end-catch + + try { + if (_output != null) { + _output.close(); + _output = null; + } + } catch (Exception e) { + DebugTool.logError("Failed to close output stream", e); + } // end-catch + + if (ex == null) { + // This disconnect was not caused by an error, notify the proxy that + // the trasport has been disconnected. + handleTransportDisconnected(msg); + } else { + // This disconnect was caused by an error, notify the proxy + // that there was a transport error. + handleTransportError(msg, ex); + } + } // end-method + + + /** + * Sends data over the transport. Takes a byte array and transmits data provided starting at the + * offset and of the provided length to fragment transmission. + */ + public boolean sendBytesOverTransport(byte[] msgBytes, int offset, int length) { + boolean sendResult = false; + try { + _output.write(msgBytes, offset, length); + sendResult = true; + } catch (Exception ex) { + DebugTool.logError("Error writing to Bluetooth socket: " + ex.toString(), ex); + handleTransportError("Error writing to Bluetooth socket:", ex); + sendResult = false; + } // end-catch + return sendResult; + } // end-method + + + + private class TransportReaderThread extends Thread { + + byte[] buf = new byte[4096]; + private Boolean isHalted = false; + + public void halt() { + isHalted = true; + } + + private void acceptConnection() { + SyncTrace.logTransportEvent("BTTransport: Waiting for incoming RFCOMM connect", "", InterfaceActivityDirection.Receive, null, 0, SMARTDEVICELINK_LIB_TRACE_KEY); + + try { + // Blocks thread until connection established. + _activeSocket = _serverSocket.accept(); + + // If halted after serverSocket.accept(), then return immediately + if (isHalted) { + return; + } + + // Log info of the connected device + BluetoothDevice btDevice = _activeSocket.getRemoteDevice(); + String btDeviceInfoXml = SyncTrace.getBTDeviceInfo(btDevice); + SyncTrace.logTransportEvent("BTTransport: RFCOMM Connection Accepted", btDeviceInfoXml, InterfaceActivityDirection.Receive, null, 0, SMARTDEVICELINK_LIB_TRACE_KEY); + + _output = _activeSocket.getOutputStream(); + _input = _activeSocket.getInputStream(); + + handleTransportConnected(); + + } catch (Exception e) { + + if (!isHalted) { + // Only call disconnect if the thread has not been halted + + // Check to see if Bluetooth was disabled + if (_adapter != null && !_adapter.isEnabled()) { + disconnect("Bluetooth Adapater has been disabled.", new SmartDeviceLinkException("Bluetooth adapter must be enabled to instantiate a SmartDeviceLinkProxy object.", e, SmartDeviceLinkExceptionCause.BLUETOOTH_DISABLED)); + } else { + disconnect("Failed to accept connection", e); + } + } + } finally { + if (_serverSocket != null && !isHalted) { + try { + _serverSocket.close(); + } catch (IOException e) { + //do nothing + } + _serverSocket = null; + } + } + } + + private void readFromTransport() { + try { + int bytesRead = -1; + try { + bytesRead = _input.read(buf); + } catch (Exception e) { + if (!isHalted) { + // Only call disconnect if the thread has not been halted + + // Check to see if Bluetooth was disabled + if (_adapter != null && !_adapter.isEnabled()) { + disconnect("Bluetooth Adapater has been disabled.", new SmartDeviceLinkException("Bluetooth adapter must be enabled to instantiate a SmartDeviceLinkProxy object.", e, SmartDeviceLinkExceptionCause.BLUETOOTH_DISABLED)); + } else { + disconnect("Failed to read from Bluetooth transport.", e); + } + } + return; + } // end-catch + + if (bytesRead != -1) { + handleReceivedBytes(buf, bytesRead); + } else { + // When bytesRead == -1, it indicates end of stream + if (!isHalted) { + // Only call disconnect if the thread has not been halted + DebugTool.logError("End of stream reached!"); + disconnect("End of stream reached.", null); + } + } + } catch (Exception excp) { + if (!isHalted) { + // Only call disconnect if the thread has not been halted + String errString = "Failure in BTTransport reader thread: " + excp.toString(); + DebugTool.logError(errString, excp); + disconnect(errString, excp); + } + return; + } // end-catch + } // end-method + + public void run() { + // acceptConnection blocks until the connection has been accepted + acceptConnection(); + + while (!isHalted) { + readFromTransport(); + } + } + } + + private class BluetoothAdapterMonitor { + private boolean _isHalted = false; + private BluetoothAdapter _bluetoothAdapter = null; + private final String THREAD_NAME = "BluetoothAdapterMonitor"; + private Thread _bluetoothAdapterMonitorThread = null; + + public BluetoothAdapterMonitor(BluetoothAdapter bluetoothAdapter) { + if (bluetoothAdapter == null) { + throw new IllegalArgumentException("BluetoothAdapter cannot be null."); + } + + // Set the bluetooth adapter + _bluetoothAdapter = bluetoothAdapter; + + _bluetoothAdapterMonitorThread = new Thread(new Runnable() { + @Override + public void run() { + while (!_isHalted) { + checkIfBluetoothAdapterDisabled(); + try { + Thread.sleep(15000); + } catch (InterruptedException e) { + // Break if interrupted + break; + } + } + } + }); + _bluetoothAdapterMonitorThread.setName(THREAD_NAME); + _bluetoothAdapterMonitorThread.setDaemon(true); + _bluetoothAdapterMonitorThread.start(); + } + + private void checkIfBluetoothAdapterDisabled() { + if (_bluetoothAdapter != null && !_bluetoothAdapter.isEnabled()) { + // Bluetooth adapter has been disabled, disconnect the transport + disconnect("Bluetooth adapter has been disabled.", + new SmartDeviceLinkException("Bluetooth adapter must be enabled to instantiate a SmartDeviceLinkProxy object.", SmartDeviceLinkExceptionCause.BLUETOOTH_DISABLED)); + } + } + + public void halt() { + _isHalted = true; + _bluetoothAdapterMonitorThread.interrupt(); + } + } + + /** + * Overridden abstract method which returns specific type of this transport. + * + * @return Constant value - TransportType.BLUETOOTH. + * + * @see TransportType + */ + public TransportType getTransportType() { + return TransportType.BLUETOOTH; + } +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BTTransportConfig.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BTTransportConfig.java new file mode 100644 index 000000000..88efc1e82 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BTTransportConfig.java @@ -0,0 +1,22 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +/** + * Container of Bluetooth transport specific configuration. + */ +public final class BTTransportConfig extends BaseTransportConfig { + + /** + * Overridden abstract method which returns specific type of this transport configuration. + * + * @return Constant value TransportType.BLUETOOTH. + * + * @see TransportType + */ + public TransportType getTransportType() { + return TransportType.BLUETOOTH; + } + +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BaseTransportConfig.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BaseTransportConfig.java new file mode 100644 index 000000000..1a14affa5 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/BaseTransportConfig.java @@ -0,0 +1,17 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +/** + * Defines base abstract class for transport configurations. + */ +public abstract class BaseTransportConfig { + + /** + * Gets transport type for this transport configuration. + * + * @return One of {@link TransportType} enumeration values that represents type of this transport configuration. + */ + public abstract TransportType getTransportType(); +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/ISmartDeviceLinkTransport.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/ISmartDeviceLinkTransport.java new file mode 100755 index 000000000..cff557a84 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/ISmartDeviceLinkTransport.java @@ -0,0 +1,22 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +import com.smartdevicelink.exception.SmartDeviceLinkException; + +public interface ISmartDeviceLinkTransport { + + void connect() throws SmartDeviceLinkException; + + void disconnect(); + + boolean sendBytes(byte[] message); + boolean sendBytes(byte[] message, int offset, int length); + + void addTransportListener(ITransportListener transListener); + + String getGuid(); + String getAppName(); + void setAppName(String appName); +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/ITransportListener.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/ITransportListener.java new file mode 100755 index 000000000..ac8c63833 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/ITransportListener.java @@ -0,0 +1,18 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +public interface ITransportListener { + // Called to indicate and deliver bytes received from transport + void onTransportBytesReceived(byte[] receivedBytes, int receivedBytesLength); + + // Called to indicate that transport connection was established + void onTransportConnected(); + + // Called to indicate that transport was disconnected (by either side) + void onTransportDisconnected(String info); + + // Called to indicate that some error occurred on the transport + void onTransportError(String info, Exception e); +} // end-interface diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/SiphonServer.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/SiphonServer.java new file mode 100755 index 000000000..d479d6d05 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/SiphonServer.java @@ -0,0 +1,364 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.BindException; +import java.net.ServerSocket; +import java.net.Socket; + +import com.smartdevicelink.util.*; + +public class SiphonServer { + // Prohibit use of no-arg ctor + private SiphonServer() {} + + enum SiphonDataType { + fromSmartDeviceLink, + fromApp, + appLog, + formattedTrace, + baselineTimeStamp, + traceSettings + } + + // Boolean to enable/disable the siphon + private static Boolean m_siphonEnabled = false; + + // Boolean to determine if the siphon has been initialized + private static Boolean m_siphonInitialized = false; + + private static Socket m_siphonSocket = null; + private static Object m_siphonLock = new Object(); + private static ServerSocket m_listeningSocket = null; + private static OutputStream m_siphonSocketOutputStream = null; + private static SiphonServerThread m_siphonClientThread = null; + + // Initial timestamp in MS + private static long m_startTimeStamp = 0; + + // SmartDeviceLink Trace Message Version + private static byte m_SyncTraceMsgVersionNumber = 1; + + // Max number of ports to attempt a connection on + private final static Integer MAX_NUMBER_OF_PORT_ATTEMPTS = 1000; + + // Starting port for future port attempts + private final static short FIRST_PORT_TO_ATTEMPT_CONNECTION = 7474; + + // Boolean to determine if formatted trace is being sent + private static Boolean m_sendingFormattedTrace = false; + + public static void enableSiphonServer() { + m_siphonEnabled = true; + } + + public static void disableSiphonServer() { + m_siphonEnabled = false; + } + + public static boolean init() { + // Only initialize if the siphon has not been initialized previously + + // Check here to be lean. If true, no need to SmartDeviceLinkhronize + if (m_siphonInitialized) { + return true; + } + + synchronized (m_siphonLock) { + // To prevent a race condition, re-check m_siphonInitialized inside of SmartDeviceLinkhronize block + if (!m_siphonInitialized) { + if (m_siphonClientThread == null) { + // Set current time stamp + m_startTimeStamp = System.currentTimeMillis(); + + // Start Siphon Thread + m_siphonClientThread = new SiphonServerThread(); + m_siphonClientThread.setName("Siphon"); + m_siphonClientThread.setDaemon(true); + m_siphonClientThread.start(); + + m_siphonInitialized = true; + } // end-if + } // end-lock + } + + return m_siphonInitialized; + } // end-method + + public static void closeServer() throws IOException { + + if (m_siphonClientThread != null) { + m_siphonClientThread.halt(); + m_siphonClientThread = null; + } + + if (m_listeningSocket != null) { + m_listeningSocket.close(); + m_listeningSocket = null; + } + + if (m_siphonSocket != null) { + m_siphonSocket.close(); + m_siphonSocket = null; + } + + if (m_siphonSocketOutputStream != null) { + m_siphonSocketOutputStream.close(); + m_siphonSocketOutputStream = null; + } + } + + public static Boolean sendBytesFromAPP(byte[] msgBytes, int offset, int length) { + + if (m_sendingFormattedTrace) { + return false; + } + + return sendSiphonData(SiphonDataType.fromApp, msgBytes, offset, length); + } // end-method + + public static Boolean sendBytesFromSmartDeviceLink(byte[] msgBytes, int offset, int length) { + + if (m_sendingFormattedTrace) { + return false; + } + + return sendSiphonData(SiphonDataType.fromSmartDeviceLink, msgBytes, offset, length); + } // end-method + + public static Boolean sendSiphonLogData(String message) { + + if (m_sendingFormattedTrace) { + return false; + } + + if (message == null || message.length() == 0) { + return false; + } + + byte messageBytes[] = null; + int messageLength = 0; + + try { + messageBytes = message.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + return false; + } + + messageLength = messageBytes.length; + return sendSiphonData(SiphonDataType.appLog, messageBytes, 0, messageLength); + + } + + public static Boolean sendFormattedTraceMessage(String message) { + + if (message == null || message.length() == 0) { + return false; + } + + byte messageBytes[] = null; + int messageLength = 0; + + try { + messageBytes = message.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + return false; + } + + messageLength = messageBytes.length; + if (sendSiphonData(SiphonDataType.formattedTrace, messageBytes, 0, messageLength)) { + m_sendingFormattedTrace = true; + return true; + } else { + return false; + } + } + + private static Boolean sendSiphonData(SiphonDataType direction, byte[] msgBytes, int offset, int length) { + byte siphonDataTypeIndicator = 0x00; + + long currentDateTime = System.currentTimeMillis(); + Integer deltaTimeMills = null; + + deltaTimeMills = (int)(currentDateTime - m_startTimeStamp); + + switch(direction) { + case fromSmartDeviceLink: + siphonDataTypeIndicator = 0x00; + break; + case fromApp: + siphonDataTypeIndicator = 0x01; + break; + case appLog: + siphonDataTypeIndicator = 0x02; + break; + case formattedTrace: + siphonDataTypeIndicator = 0x03; + break; + case baselineTimeStamp: + siphonDataTypeIndicator = 0x04; + break; + case traceSettings: + siphonDataTypeIndicator = 0x05; + break; + default: + siphonDataTypeIndicator = 0x00; + break; + } + + // Set high bit to indicate new format + siphonDataTypeIndicator = (byte)((byte)0x80 | siphonDataTypeIndicator); + + return sendDataToSiphonSocket(siphonDataTypeIndicator, deltaTimeMills, msgBytes, offset, length); + } + + private synchronized static Boolean sendDataToSiphonSocket(byte directionIndicator, Integer timeStamp, + byte[] msgBytes, int offset, int length) { + if (!m_siphonEnabled) { + return false; + } + + if (msgBytes == null || length == 0) { + return false; + } + + OutputStream siphonOutputStream = null; + + synchronized (m_siphonLock) { + siphonOutputStream = m_siphonSocketOutputStream; + } // end-lock + + if (siphonOutputStream == null) { + return false; + } + + try { + // blobSize = length(of message) + 1(size of direction indicator) + // + 1 (size of msgVersionNumber) + 4 (size of timeStamp) + int blobSize = length + 1 + 1 + 4; + + siphonOutputStream.write(BitConverter.intToByteArray(blobSize)); + siphonOutputStream.write(new byte[] {directionIndicator}); + siphonOutputStream.write(new byte[] {m_SyncTraceMsgVersionNumber}); + siphonOutputStream.write(intToByteArray(timeStamp)); + siphonOutputStream.write(msgBytes, offset, length); + } catch (Exception ex) { + return false; + } // end-catch + + return true; + } // end-method + + private static class SiphonServerThread extends Thread { + + private Boolean isHalted = false; + short listenPort; + + public void halt() { + isHalted = true; + } + + private boolean findOpenSocket(short port) { + // Accept incoming sihpon connection from trace utility. + Boolean foundOpenPort = false; + listenPort = port; + + // Listen to accept incoming connection from SmartDeviceLink + while (!foundOpenPort) { + try { + m_listeningSocket = new ServerSocket(listenPort); + foundOpenPort = true; + } catch (BindException ex) { + listenPort++; + if(listenPort > port + MAX_NUMBER_OF_PORT_ATTEMPTS) { + return false; + } + } catch (IOException e) { + return false; + } + } + + return foundOpenPort; + } + + private void startServerOnPort() throws IOException { + Socket newSocket = null; + + // Wait for a connection + newSocket = m_listeningSocket.accept(); + + // If isHalted after accept() delay, return + if (isHalted) { + return; + } + + synchronized (m_siphonLock) { + // Reset siphonSocketOutputStream + if (m_siphonSocketOutputStream != null) { + try { + m_siphonSocketOutputStream.close(); + } catch (IOException e) { + // Do nothing + } + m_siphonSocketOutputStream = null; + } + + // Reset siphonSocket + if (m_siphonSocket != null) { + try { + m_siphonSocket.close(); + } catch (IOException e) { + // Do nothing + } + m_siphonSocket = null; + } + + // Store the new socket + m_siphonSocket = newSocket; + + // Set Socket Options + m_siphonSocket.setKeepAlive(true); + + // Get the output stream of the connection + m_siphonSocketOutputStream = m_siphonSocket.getOutputStream(); + + // Output version number to the Siphon upon connection (version number prepending to logInfo) + DebugTool.logInfo("Siphon connected."); + } // end-lock + } // end-method + + @Override + public void run() { + try { + if (findOpenSocket(FIRST_PORT_TO_ATTEMPT_CONNECTION)) { + while (!isHalted) { + startServerOnPort(); + } + } + } catch (Exception ex) { + // Do nothing + } finally { + if (m_listeningSocket != null) { + try { + m_listeningSocket.close(); + } catch (IOException e) { + // Do nothing + } + m_listeningSocket = null; + } + } + } + } + + private static final byte[] intToByteArray(int value) { + return new byte[] { + (byte)(value >>> 24), + (byte)(value >>> 16), + (byte)(value >>> 8), + (byte)value}; + } +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/SmartDeviceLinkTransport.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/SmartDeviceLinkTransport.java new file mode 100755 index 000000000..7f3e8d4f3 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/SmartDeviceLinkTransport.java @@ -0,0 +1,120 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +import com.smartdevicelink.exception.SmartDeviceLinkException; +import com.smartdevicelink.trace.SyncTrace; +import com.smartdevicelink.trace.enums.InterfaceActivityDirection; +import com.smartdevicelink.util.DebugTool; + +public abstract class SmartDeviceLinkTransport { + private static final String SMARTDEVICELINK_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + + private final static String FailurePropagating_Msg = "Failure propagating "; + private Boolean isConnected = false; + + private String _sendLockObj = "lock"; + + // Get status of transport connection + public Boolean getIsConnected() { + return isConnected; + } + + //protected SmartDeviceLinkTransport(String endpointName, String param2, ITransportListener transportListener) + protected SmartDeviceLinkTransport(ITransportListener transportListener) { + if (transportListener == null) { + throw new IllegalArgumentException("Provided transport listener interface reference is null"); + } // end-if + _transportListener = transportListener; + } // end-method + + // This method is called by the subclass to indicate that data has arrived from + // the transport. + protected void handleReceivedBytes(byte[] receivedBytes, int receivedBytesLength) { + try { + // Trace received data + if (receivedBytesLength > 0) { + // Send transport data to the siphon server + SiphonServer.sendBytesFromSmartDeviceLink(receivedBytes, 0, receivedBytesLength); + SyncTrace.logTransportEvent("", null, InterfaceActivityDirection.Receive, receivedBytes, receivedBytesLength, SMARTDEVICELINK_LIB_TRACE_KEY); + + _transportListener.onTransportBytesReceived(receivedBytes, receivedBytesLength); + } // end-if + } catch (Exception excp) { + DebugTool.logError(FailurePropagating_Msg + "handleBytesFromTransport: " + excp.toString(), excp); + handleTransportError(FailurePropagating_Msg, excp); + } // end-catch + } // end-method + + // This method must be implemented by transport subclass, and is called by this + // base class to actually send an array of bytes out over the transport. This + // method is meant to only be callable within the class hierarchy. + protected abstract boolean sendBytesOverTransport(byte[] msgBytes, int offset, int length); + + // This method is called by whomever has reference to transport to have bytes + // sent out over transport. + public boolean sendBytes(byte[] message) { + return sendBytes(message, 0, message.length); + } // end-method + + // This method is called by whomever has reference to transport to have bytes + // sent out over transport. + public boolean sendBytes(byte[] message, int offset, int length) { + boolean bytesWereSent = false; + synchronized (_sendLockObj) { + bytesWereSent = sendBytesOverTransport(message, offset, length); + } // end-lock + // Send transport data to the siphon server + SiphonServer.sendBytesFromAPP(message, offset, length); + + SyncTrace.logTransportEvent("", null, InterfaceActivityDirection.Transmit, message, offset, length, SMARTDEVICELINK_LIB_TRACE_KEY); + return bytesWereSent; + } // end-method + + private ITransportListener _transportListener = null; + + // This method is called by the subclass to indicate that transport connection + // has been established. + protected void handleTransportConnected() { + isConnected = true; + try { + SyncTrace.logTransportEvent("Transport.connected", null, InterfaceActivityDirection.Receive, null, 0, SMARTDEVICELINK_LIB_TRACE_KEY); + _transportListener.onTransportConnected(); + } catch (Exception excp) { + DebugTool.logError(FailurePropagating_Msg + "onTransportConnected: " + excp.toString(), excp); + handleTransportError(FailurePropagating_Msg + "onTransportConnected", excp); + } // end-catch + } // end-method + + // This method is called by the subclass to indicate that transport disconnection + // has occurred. + protected void handleTransportDisconnected(final String info) { + isConnected = false; + + try { + SyncTrace.logTransportEvent("Transport.disconnect: " + info, null, InterfaceActivityDirection.Transmit, null, 0, SMARTDEVICELINK_LIB_TRACE_KEY); + _transportListener.onTransportDisconnected(info); + } catch (Exception excp) { + DebugTool.logError(FailurePropagating_Msg + "onTransportDisconnected: " + excp.toString(), excp); + } // end-catch + } // end-method + + // This method is called by the subclass to indicate a transport error has occurred. + protected void handleTransportError(final String message, final Exception ex) { + isConnected = false; + _transportListener.onTransportError(message, ex); + } + + public abstract void openConnection() throws SmartDeviceLinkException; + public abstract void disconnect(); + + /** + * Abstract method which should be implemented by subclasses in order to return actual type of the transport. + * + * @return One of {@link TransportType} enumeration values. + * + * @see TransportType + */ + public abstract TransportType getTransportType(); +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TCPTransport.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TCPTransport.java new file mode 100755 index 000000000..465f3d8c2 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TCPTransport.java @@ -0,0 +1,501 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +import android.util.Log; +import com.smartdevicelink.exception.SmartDeviceLinkException; +import com.smartdevicelink.exception.SmartDeviceLinkExceptionCause; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; + +/** + * General comments: + * + * 1) Transport layer can be reorganized to properly incapsulate thread-related code according to Android OS guidelines + * 2) Currently there are different cases when transport error information sent to listener components + * a) when there are some errors during writing data to transport + * b) when there are errors during connection establishing/reading data + * But information about transport disconnection is sent only if disconnection was successful. So we have following + * sequences: + * a) handleTransportConnected -> read without errors -> handleTransportDisconnected + * b) handleTransportConnected -> handleTransportError(write with errors) -> handleTransportDisconnected + * c) handleTransportConnected -> handleTransportError(read with errors) -> handleTransportError(socket closed) + * + * They can be changed to be more natural and easy to use. + * + * 3) Public api is inconsistent. During single call of some api method (for example "openConnection") some of the + * following result can appears: + * a) SmartDeviceLinkException thrown + * b) onTransportError callback called on listeners + * + * 4) Handling of connection must be more stable + * 5) General solution in case of reconnecting must be implemented + * 6) It must be common and same solution for handling information about physical device adapters (BT, WiFi etc.) + */ + +/** + * Class that implements TCP transport + */ +public class TCPTransport extends SmartDeviceLinkTransport { + + /** + * Size of the read buffer. + */ + private static final int READ_BUFFER_SIZE = 4096; + + /** + * Delay between reconnect attempts + */ + private static final int RECONNECT_DELAY = 5000; + + /** + * Count of the reconnect retries + */ + private static final int RECONNECT_RETRY_COUNT = 30; + + /** + * Instance of TCP transport configuration + */ + private TCPTransportConfig mConfig = null; + + /** + * Instance of the client socket + */ + private Socket mSocket = null; + + /** + * Instance of the input stream. Used to read data from SmartDeviceLinkCore + */ + private InputStream mInputStream = null; + + /** + * Instance of the output stream. Used to send data to SmartDeviceLinkCore + */ + private OutputStream mOutputStream = null; + + /** + * Instance of the separate thread, that does actual work, related to connecting/reading/writing data + */ + private TCPTransportThread mThread = null; + + /** + * Initial internal state of the component. Used like a simple lightweight FSM replacement while component + * must behave differently in response to it's public function calls depending of it's current state + */ + private TCPTransportState mCurrentState = TCPTransportState.IDLE; + + /** + * Constructs TCP transport component instance + * + * @param tcpTransportConfig Instance of the TCP transport configuration + * @param transportListener Listener that will be notified on different TCP transport activities + */ + public TCPTransport(TCPTransportConfig tcpTransportConfig, ITransportListener transportListener) { + super(transportListener); + this.mConfig = tcpTransportConfig; + } + + /** + * Performs actual work of sending array of bytes over the transport + * @param msgBytes Bytes to send + * @param offset Offset in the bytes array to send data from + * @param length Number of bytes to send + * @return True if data was sent successfully, False otherwise + */ + @Override + protected boolean sendBytesOverTransport(byte[] msgBytes, int offset, int length) { + TCPTransportState currentState = getCurrentState(); + logInfo(String.format("TCPTransport: sendBytesOverTransport requested. Size: %d, Offset: %d, Length: %d, Current state is: %s" + , msgBytes.length, offset, length, currentState.name())); + + boolean bResult = false; + + if(currentState == TCPTransportState.CONNECTED) { + synchronized (this) { + if (mOutputStream != null) { + logInfo("TCPTransport: sendBytesOverTransport request accepted. Trying to send data"); + try { + mOutputStream.write(msgBytes, offset, length); + bResult = true; + logInfo("TCPTransport.sendBytesOverTransport: successfully send data"); + } catch (IOException e) { + logWarning("TCPTransport.sendBytesOverTransport: error during sending data: " + e.getMessage()); + bResult = false; + } + } else { + logError("TCPTransport: sendBytesOverTransport request accepted, but output stream is null"); + } + } + } else { + logInfo("TCPTransport: sendBytesOverTransport request rejected. Transport is not connected"); + bResult = false; + } + + return bResult; + } + + /** + * Tries to open connection to SmartDeviceLinkCore. + * Actual try will be performed only if no actual connection is available + * @throws SmartDeviceLinkException + */ + @Override + public void openConnection() throws SmartDeviceLinkException { + TCPTransportState currentState = getCurrentState(); + logInfo(String.format("TCPTransport: openConnection requested. Current state is: %s", currentState.name())); + + if(currentState == TCPTransportState.IDLE) { + synchronized (this) { + setCurrentState(TCPTransportState.CONNECTING); + logInfo("TCPTransport: openConnection request accepted. Starting transport thread"); + try { + mThread = new TCPTransportThread(); + mThread.setDaemon(true); + mThread.start(); + + // Initialize the SiphonServer + SiphonServer.init(); + } catch (Exception e) { + logError("TCPTransport: Exception during transport thread starting", e); + throw new SmartDeviceLinkException(e); + } + } + } else { + logInfo("TCPTransport: openConnection request rejected. Another connection is not finished"); + } + } + + + /** + * Tries to disconnect from SmartDeviceLinkCore. + * Actual try will be performed only if connection is available + */ + @Override + public void disconnect() { + TCPTransportState currentState = getCurrentState(); + logInfo(String.format("TCPTransport: disconnect requested from client. Current state is: %s", currentState.name())); + + if(currentState == TCPTransportState.CONNECTED) { + logInfo("TCPTransport: disconnect request accepted."); + synchronized (this) { + disconnect(null, null, true); + } + } else { + logInfo("TCPTransport: disconnect request rejected. Transport is not connected"); + } + } + + /** + * Performs actual work related to disconnecting from SmartDeviceLinkCore. + * + * @param message Message that describes disconnect reason + * @param exception Some of the possible exceptions that was the reason of disconnecting + * @param stopThread True if not only disconnection must be done but also thread that handles connection must be + * also stopped so no reconnect attempts will be made + */ + private synchronized void disconnect(String message, Exception exception, boolean stopThread) { + + if(getCurrentState() == TCPTransportState.DISCONNECTING) { + logInfo("TCPTransport: disconnecting already in progress"); + return; + } + + setCurrentState(TCPTransportState.DISCONNECTING); + + String disconnectMsg = (message == null ? "" : message); + if (exception != null) { + disconnectMsg += ", " + exception.toString(); + } + + try { + if(mThread != null && stopThread) { + mThread.halt(); + mThread.interrupt(); + } + + if(mSocket != null){ + mSocket.close(); + } + mSocket = null; + } catch (IOException e) { + logInfo("TCPTransport.disconnect: Exception during disconnect: " + e.getMessage()); + } + + if (exception == null) { + // This disconnect was not caused by an error, notify the proxy that + // the transport has been disconnected. + logInfo("Disconnect is correct. Handling it"); + handleTransportDisconnected(disconnectMsg); + } else { + // This disconnect was caused by an error, notify the proxy + // that there was a transport error. + logInfo("Disconnect is incorrect. Handling it as error"); + handleTransportError(disconnectMsg, exception); + } + } + + /** + * Overridden abstract method which returns specific type of this transport. + * + * @return Constant value - TransportType.TCP. + * @see TransportType + */ + public TransportType getTransportType() { + return TransportType.TCP; + } + + /** + * Internal method for logging information messages + * @param message Message to log + */ + protected void logInfo(String message) { + Log.i(getClass().getName(), message); + } + + /** + * Internal method for logging error messages + * @param message Message to log + */ + protected void logError(String message) { + Log.e(getClass().getName(), message); + } + + /** + * Internal method for logging warning messages + * @param message Message to log + */ + protected void logWarning(String message) { + Log.w(getClass().getName(), message); + } + + /** + * Internal method for logging error message together with information about exception that was the reason of it + * @param message Message to log + * @param throwable Exception, that was the main reason for logged error message + */ + protected void logError(String message, Throwable throwable) { + Log.e(getClass().getName(), message, throwable); + } + + /** + * Internal class that represents separate thread, that does actual work, related to connecting/reading/writing data + */ + private class TCPTransportThread extends Thread { + + /** + * Represents current thread state - halted or not. This flag is used to change internal behavior depending + * on current state. + */ + private Boolean isHalted = false; + + /** + * Method that marks thread as halted. + */ + public void halt() { + isHalted = true; + } + + /** + * Tries to connect to the SmartDeviceLink core. Behavior depends autoReconnect configuration param: + * a) If autoReconnect is false, then only one connect try will be performed. + * b) If autoReconnect is true, then in case of connection error continuous reconnect will be performed + * after short delay until connection will be established or retry count will be reached + * + * @return true if connection established and false otherwise + */ + private boolean connect() { + boolean bConnected; + int remainingRetry = RECONNECT_RETRY_COUNT; + + synchronized (TCPTransport.this) { + do { + try { + + if ((null != mSocket) && (!mSocket.isClosed())) { + logInfo("TCPTransport.connect: Socket is not closed. Trying to close it"); + mSocket.close(); + } + + logInfo(String.format("TCPTransport.connect: Socket is closed. Trying to connect to %s", mConfig)); + mSocket = new Socket(); + mSocket.connect(new InetSocketAddress(mConfig.getIPAddress(), mConfig.getPort())); + mOutputStream = mSocket.getOutputStream(); + mInputStream = mSocket.getInputStream(); + + } catch (IOException e) { + logInfo("TCPTransport.connect: Exception during connect stage: " + e.getMessage()); + } + + bConnected = (null != mSocket) && mSocket.isConnected(); + + if(bConnected){ + logInfo("TCPTransport.connect: Socket connected"); + }else{ + if(mConfig.getAutoReconnect()){ + remainingRetry--; + logInfo(String.format("TCPTransport.connect: Socket not connected. AutoReconnect is ON. retryCount is: %d. Waiting for reconnect delay: %d" + , remainingRetry, RECONNECT_DELAY)); + waitFor(RECONNECT_DELAY); + } else { + logInfo("TCPTransport.connect: Socket not connected. AutoReconnect is OFF"); + } + } + } while ((!bConnected) && (mConfig.getAutoReconnect()) && (remainingRetry > 0) && (!isHalted)); + + return bConnected; + } + } + + /** + * Performs actual thread work + */ + @Override + public void run() { + logInfo("TCPTransport.run: transport thread created. Starting connect stage"); + + while(!isHalted) { + setCurrentState(TCPTransportState.CONNECTING); + if(!connect()){ + if (isHalted) { + logInfo("TCPTransport.run: Connection failed, but thread already halted"); + } else { + disconnect("Failed to connect to SmartDeviceLink", new SmartDeviceLinkException("Failed to connect to SmartDeviceLink" + , SmartDeviceLinkExceptionCause.SMARTDEVICELINK_CONNECTION_FAILED), true); + } + break; + } + + synchronized (TCPTransport.this) { + setCurrentState(TCPTransportState.CONNECTED); + handleTransportConnected(); + } + + byte[] buffer = new byte[READ_BUFFER_SIZE]; + + while (!isHalted) { + logInfo("TCPTransport.run: Waiting for data..."); + int bytesRead; + try { + bytesRead = mInputStream.read(buffer); + } catch (IOException e) { + internalHandleStreamReadError(); + break; + } + + synchronized (TCPTransport.this) { + if (mThread.isInterrupted()) { + logInfo("TCPTransport.run: Got new data but thread is interrupted"); + break; + } + } + + logInfo("TCPTransport.run: Got new data"); + if (-1 == bytesRead) { + internalHandleTCPDisconnect(); + break; + } else if (0 == bytesRead) { + logInfo("TCPTransport.run: Received zero bytes"); + } else { + logInfo(String.format("TCPTransport.run: Received %d bytes", bytesRead)); + synchronized (TCPTransport.this) { + handleReceivedBytes(buffer, bytesRead); + } + } + } + } + + logInfo("TCPTransport.run: Thread terminated"); + setCurrentState(TCPTransportState.IDLE); + } + + /** + * Internal handling of Tcp disconnection + */ + private void internalHandleTCPDisconnect() { + if(isHalted){ + logInfo("TCPTransport.run: TCP disconnect received, but thread already halted"); + } else { + logInfo("TCPTransport.run: TCP disconnect received"); + disconnect("TCPTransport.run: End of stream reached", null, false); + } + } + + /** + * Internal handling of reading data from input stream + */ + private void internalHandleStreamReadError() { + if(isHalted){ + logInfo("TCPTransport.run: Exception during reading data, but thread already halted"); + } else { + logInfo("TCPTransport.run: Exception during reading data"); + disconnect("Failed to read data from SmartDeviceLink", new SmartDeviceLinkException("Failed to read data from SmartDeviceLink" + , SmartDeviceLinkExceptionCause.SMARTDEVICELINK_CONNECTION_FAILED), false); + } + } + } + + /** + * Returns current TCP transport state + * + * @return current state + */ + private synchronized TCPTransportState getCurrentState() { + return mCurrentState; + } + + /** + * Sets current TCP transport state + * @param currentState New state + */ + private synchronized void setCurrentState(TCPTransportState currentState) { + logInfo(String.format("Current state changed to: %s", currentState)); + this.mCurrentState = currentState; + } + + /** + * Implementation of waiting required delay that cannot be interrupted + * @param timeMs Time in milliseconds of required delay + */ + private void waitFor(long timeMs) { + long endTime = System.currentTimeMillis() +timeMs; + while (System.currentTimeMillis() < endTime) { + synchronized (this) { + try { + wait(endTime - System.currentTimeMillis()); + } catch (Exception e) { + // Nothing To Do, simple wait + } + } + } + } + + /** + * Defines available states of the TCP transport + */ + private enum TCPTransportState { + /** + * TCP transport is created. No connection opened + */ + IDLE, + + /** + * TCP transport is in progress of establishing connection. + */ + CONNECTING, + + /** + * TCP transport is connected to SmartDeviceLink core + */ + CONNECTED, + + /** + * TCP transport is in progress of disconnecting + */ + DISCONNECTING + } +} // end-class diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TCPTransportConfig.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TCPTransportConfig.java new file mode 100644 index 000000000..78358f91f --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TCPTransportConfig.java @@ -0,0 +1,85 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +/** + * Container of TCP transport specific configuration. + */ +public final class TCPTransportConfig extends BaseTransportConfig { + + /** + * Value of port to use in TCP connection. + */ + private final int mPort; + + /** + * Value of IP address to use in TCP connection. + */ + private final String mIpAddress; + + /** + * Value of flag which is set to true if tcp connection must be automatically reestablished in case of disconnection + */ + private final boolean mAutoReconnect; + + /** + * Constructor. Objects of this class must be created for known port and IP address value. + * + * @param port Port for TCP connection. + * @param ipAddress IP address for TCP connection. + * @param autoReconnect Flag which must be set to true if tcp connection must be automatically reestablished in + * case of disconnection + */ + public TCPTransportConfig(int port, String ipAddress, boolean autoReconnect) { + mPort = port; + mIpAddress = ipAddress; + mAutoReconnect = autoReconnect; + } + + /** + * Gets value of Port. + * + * @return Port for TCP connection. + */ + public int getPort() { + return mPort; + } + + /** + * Gets value of IP address. + * + * @return IP address for TCP connection. + */ + public String getIPAddress() { + return mIpAddress; + } + + /** + * Gets value of AutoReconnect + * @return Flag that determines automatic reconnection + */ + public boolean getAutoReconnect() { + return mAutoReconnect; + } + + /** + * Overridden abstract method which returns specific type of this transport configuration. + * + * @return Constant value TransportType.TCP. + * + * @see TransportType + */ + public TransportType getTransportType() { + return TransportType.TCP; + } + + @Override + public String toString() { + return "TCPTransportConfig{" + + "Port=" + mPort + + ", IpAddress='" + mIpAddress + '\'' + + ", AutoReconnect=" + mAutoReconnect + + '}'; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TransportType.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TransportType.java new file mode 100644 index 000000000..62cdc3420 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/transport/TransportType.java @@ -0,0 +1,20 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.transport; + +/** + * Defines available types of the transports. + */ +public enum TransportType { + + /** + * Transport type is Bluetooth. + */ + BLUETOOTH, + + /** + * Transport type is TCP. + */ + TCP +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/Base64.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/Base64.java new file mode 100755 index 000000000..d7f6a6490 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/Base64.java @@ -0,0 +1,114 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.util; + +public class Base64 { + + private static final String defaultString = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure"; + + private static char[] map = new char[64]; + private static byte[] unmap = new byte['z' + 1]; + static { + byte i = 0; + for (char c = 'A'; c <= 'Z'; c++) { + unmap[c] = i; + map[i++] = c; + } + for (char c = 'a'; c <= 'z'; c++) { + unmap[c] = i; + map[i++] = c; + } + for (char c = '0'; c <= '9'; c++) { + unmap[c] = i; + map[i++] = c; + } + unmap['+'] = i; + map[i++] = '+'; + unmap['/'] = i; + map[i++] = '/'; + + unmap['='] = 0; + } + + /** + * @param args + */ + public static void main(String[] args) { + + String toEncode = defaultString; + if (args.length > 0) { + toEncode = args[0]; + } + System.out.println(toEncode); + String encoded = encode(toEncode.getBytes()); + System.out.println(encoded); + String decoded = new String(decode(encoded)); + System.out.println(decoded); + } + + public static String encode(byte[] toEncode) { + + int iSrc = 0; + int iDest = 0; + int srcLen = toEncode.length; + int destLen = (srcLen * 4 + 2) / 3; + int padLen = ((srcLen + 2) / 3) * 4; + char[] dest = new char[padLen]; + + while (iSrc < srcLen) { + int src1 = toEncode[iSrc++]; + int src2 = (iSrc < srcLen) ? toEncode[iSrc++] : 0; + int src3 = (iSrc < srcLen) ? toEncode[iSrc++] : 0; + int dest1 = (src1 >>> 2); + int dest2 = (src1 << 4) | (src2 >> 4); + dest2 &= 0x3F; + int dest3 = (src2 << 2) | (src3 >>> 6); + dest3 &= 0x3F; + int dest4 = src3 & 0x3F; + dest[iDest++] = map[dest1]; + dest[iDest++] = map[dest2]; + dest[iDest] = iDest < destLen ? map[dest3] : '='; + iDest++; + dest[iDest] = iDest < destLen ? map[dest4] : '='; + iDest++; + } + + return new String(dest); + } + + public static byte[] decode(String toDecode) { + int iSrc = 0; + int iDest = 0; + char[] src = toDecode.toCharArray(); + int srcLen = src.length; + int destLen = ((srcLen / 4) * 3); + if (src[srcLen - 1] == '=') { + destLen--; + } + if (src[srcLen - 2] == '=') { + destLen--; + } + byte[] dest = new byte[destLen]; + + while (iSrc < srcLen) { + byte src1 = unmap[src[iSrc++]]; + byte src2 = unmap[src[iSrc++]]; + byte src3 = unmap[src[iSrc++]]; + byte src4 = unmap[src[iSrc++]]; + int dest1 = (src1 << 2) | (src2 >>> 4); + int dest2 = (src2 << 4) | (src3 >>> 2); + int dest3 = (src3 << 6) | src4; + dest[iDest++] = (byte) dest1; + if (iDest < destLen) { + dest[iDest++] = (byte) dest2; + } + if (iDest < destLen) { + dest[iDest++] = (byte) dest3; + } + } + + return dest; + } + +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/BitConverter.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/BitConverter.java new file mode 100755 index 000000000..f74856d1d --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/BitConverter.java @@ -0,0 +1,75 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.util; + +public class BitConverter { + public static String bytesToHex(byte [] bytes) { + return bytesToHex(bytes, 0, bytes.length); + } // end-method + + public static String bytesToHex(byte[] bytes, int offset, int length) { + if (bytes == null) { return null; } + final char[] HexDigits = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + byte b; + char[] hexChars = new char[2 * length]; + //StringBuffer sb = new StringBuffer(); + int upperBound = Math.min(bytes.length, (offset + length)); + int baidx = 0; + int sidx = 0; + for (baidx = offset; baidx < upperBound; baidx++) { + // Get the byte from the array + b = bytes[baidx]; + // Use nibbles as index into hex digit array (left nibble, then right) + hexChars[sidx++] = HexDigits[(b & 0xf0) >> 4]; + hexChars[sidx++] = HexDigits[(b & 0x0f)]; + } // end-for + return new String(hexChars); + } // end-method + + public static byte [] hexToBytes(String hexString) { + if (hexString == null) { return null; } + if (hexString.length() % 2 != 0) { + hexString = "0" + hexString; + } + byte [] theBytes = new byte[hexString.length() / 2]; + for (int i = 0; i < hexString.length(); i += 2) { + String byteString = hexString.substring(i, i + 2); + byte theByte = (byte)Integer.parseInt(byteString, 16); + theBytes[i/2] = theByte; + } + return theBytes; + } // end-method + + public static final byte[] intToByteArray(int value) { + return new byte[] { + (byte)(value >>> 24), + (byte)(value >>> 16), + (byte)(value >>> 8), + (byte)value}; + } + + public static int intFromByteArray(byte[] sizeBuf, int offset) { + int ret = 0; + for (int i = offset; i < offset + 4; i++) { + ret <<= 8; + ret |= 0xFF & sizeBuf[i]; + } + return ret; + } + + public static final byte[] shortToByteArray(short value) { + return new byte[] { + (byte)(value >>> 8), + (byte)value}; + } + + public static short shortFromByteArray(byte[] sizeBuf, int offset) { + short ret = 0; + for (int i = offset; i < offset + 2; i++) { + ret <<= 8; + ret |= 0xFF & sizeBuf[i]; + } + return ret; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/ByteEnumer.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/ByteEnumer.java new file mode 100755 index 000000000..6ccdebe57 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/ByteEnumer.java @@ -0,0 +1,55 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.util; + +import java.util.Enumeration; +import java.util.Vector; + +public abstract class ByteEnumer { + + protected ByteEnumer(byte value, String name) { + this.value = value; + this.name = name; + } + + private byte value; + private String name; + + public byte getValue() { return value; } + public String getName() { return name; } + + public boolean equals(ByteEnumer other) { + return name == other.getName(); + } + + public boolean eq(ByteEnumer other) { + return equals(other); + } + + public byte value() { + return value; + } + + public static ByteEnumer get(Vector theList, byte value) { + Enumeration enumer = theList.elements(); + while (enumer.hasMoreElements()) { + ByteEnumer current = (ByteEnumer)enumer.nextElement(); + if (current.getValue() == value) { + return current; + } + } + return null; + } + + public static ByteEnumer get(Vector theList, String name) { + Enumeration enumer = theList.elements(); + while (enumer.hasMoreElements()) { + ByteEnumer current = (ByteEnumer)enumer.nextElement(); + if (current.getName().equals(name)) { + return current; + } + } + return null; + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/DebugTool.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/DebugTool.java new file mode 100755 index 000000000..f8e0001a2 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/DebugTool.java @@ -0,0 +1,245 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.util; + +import java.util.Vector; + +import android.util.Log; + +import com.smartdevicelink.exception.SmartDeviceLinkException; +import com.smartdevicelink.proxy.Version; +import com.smartdevicelink.transport.SiphonServer; + +public class DebugTool { + + public static final String TAG = "SmartDeviceLinkProxy"; + + private static boolean isErrorEnabled = false; + private static boolean isWarningEnabled = false; + private static boolean isInfoEnabled = false; + + public static void enableDebugTool() { + isErrorEnabled = true; + isWarningEnabled = true; + isInfoEnabled = true; + } + + public static void disableDebugTool() { + isErrorEnabled = false; + isWarningEnabled = false; + isInfoEnabled = false; + } + + private static String prependProxyVersionNumberToString(String string) { + if (Version.VERSION != null && string != null) { + string = Version.VERSION + ": " + string; + } + + return string; + } + + public static void logError(String msg) { + + Boolean wasWritten = false; + + msg = prependProxyVersionNumberToString(msg); + + wasWritten = logToSiphon(msg); + + if (isErrorEnabled && !wasWritten) { + NativeLogTool.logError(TAG, msg); + } + } + + public static void logError(String msg, Throwable ex) { + Boolean wasWritten = false; + + msg = prependProxyVersionNumberToString(msg); + + if (ex != null) { + wasWritten = logToSiphon(msg + " Exception String: " + ex.toString()); + } else { + wasWritten = logToSiphon(msg); + } + + if (isErrorEnabled && !wasWritten) { + NativeLogTool.logError(TAG, msg, ex); + } + } + + public static void logWarning(String msg) { + Boolean wasWritten = false; + + msg = prependProxyVersionNumberToString(msg); + + wasWritten = logToSiphon(msg); + + if (isWarningEnabled && !wasWritten) { + NativeLogTool.logWarning(TAG, msg); + } + } + + public static void logInfo(String msg) { + Boolean wasWritten = false; + + msg = prependProxyVersionNumberToString(msg); + + wasWritten = logToSiphon(msg); + + if (isInfoEnabled && !wasWritten) { + NativeLogTool.logInfo(TAG, msg); + } + } + + protected static Boolean logToSiphon(String msg) { + // Initialize the SiphonServer, will be ignored if already initialized + SiphonServer.init(); + + // Write to the SiphonServer + return SiphonServer.sendSiphonLogData(msg); + } + + protected static String getLine(Throwable ex) { + if (ex == null) { return null; } + String toPrint = ex.toString() + " :" + ex.getMessage(); + for (int i=0; i<ex.getStackTrace().length; i++) { + StackTraceElement elem = ex.getStackTrace()[i]; + toPrint += "\n " + elem.toString(); + } + + if (ex instanceof SmartDeviceLinkException) { + SmartDeviceLinkException SmartDeviceLinkEx = (SmartDeviceLinkException) ex; + if (SmartDeviceLinkEx.getInnerException() != null && SmartDeviceLinkEx != SmartDeviceLinkEx.getInnerException()) { + toPrint += "\n nested:\n"; + toPrint += getLine(SmartDeviceLinkEx.getInnerException()); + } + } + + return toPrint; + } + + + protected static Vector<IConsole> consoleListenerList = new Vector<IConsole>(); + + protected final static boolean isTransportEnabled = false; + protected final static boolean isRPCEnabled = false; + + public static void addConsole(IConsole console) { + synchronized(consoleListenerList) { + consoleListenerList.addElement(console); + } + } + + public static void removeConsole(IConsole console) { + synchronized(consoleListenerList) { + consoleListenerList.removeElement(console); + } + } + + public static void clearConsoles() { + synchronized(consoleListenerList) { + consoleListenerList.removeAllElements(); + } + } + + public static void logTransport(String msg) { + if (isTransportEnabled) { + Log.d(TAG, msg); + logInfoToConsole(msg); + } + } + + public static void logRPCSend(String rpcMsg) { + if (isRPCEnabled) { + Log.d(TAG, "Sending RPC message: " + rpcMsg); + logRPCSendToConsole(rpcMsg); + } + } + + public static void logRPCReceive(String rpcMsg) { + if (isRPCEnabled) { + Log.d(TAG, "Received RPC message: " + rpcMsg); + logRPCSendToConsole(rpcMsg); + } + } + + protected static void logInfoToConsole(String msg) { + Vector<IConsole> localList; + synchronized(consoleListenerList) { + localList = (Vector<IConsole>) consoleListenerList.clone(); + } + + for (int i = 0; i < localList.size(); i++) { + IConsole consoleListener = (IConsole) localList.elementAt(i); + try { + consoleListener.logInfo(msg); + } catch (Exception ex) { + Log.e(TAG, "Failure propagating logInfo: " + ex.toString(), ex); + } // end-catch + } + } + + protected static void logErrorToConsole(String msg) { + Vector<IConsole> localList; + synchronized(consoleListenerList) { + localList = (Vector<IConsole>) consoleListenerList.clone(); + } + for (int i = 0; i < localList.size(); i++) { + IConsole consoleListener = (IConsole) localList.elementAt(i); + try { + consoleListener.logError(msg); + } catch (Exception ex) { + Log.e(TAG, "Failure propagating logError: " + ex.toString(), ex); + } // end-catch + } + } + + protected static void logErrorToConsole(String msg, Throwable e) { + Vector<IConsole> localList; + synchronized(consoleListenerList) { + localList = (Vector<IConsole>) consoleListenerList.clone(); + } + + for (int i = 0; i < localList.size(); i++) { + IConsole consoleListener = (IConsole) localList.elementAt(i); + try { + consoleListener.logError(msg, e); + } catch (Exception ex) { + Log.e(TAG, "Failure propagating logError: " + ex.toString(), ex); + } // end-catch + } + } + + protected static void logRPCSendToConsole(String msg) { + Vector<IConsole> localList; + synchronized(consoleListenerList) { + localList = (Vector<IConsole>) consoleListenerList.clone(); + } + + for (int i = 0; i < localList.size(); i++) { + IConsole consoleListener = (IConsole) localList.elementAt(i); + try { + consoleListener.logRPCSend(msg); + } catch (Exception ex) { + Log.e(TAG, "Failure propagating logRPCSend: " + ex.toString(), ex); + } // end-catch + } + } + + protected static void logRPCReceiveToConsole(String msg) { + Vector<IConsole> localList; + synchronized(consoleListenerList) { + localList = (Vector<IConsole>) consoleListenerList.clone(); + } + + for (int i = 0; i < localList.size(); i++) { + IConsole consoleListener = (IConsole) localList.elementAt(i); + try { + consoleListener.logRPCReceive(msg); + } catch (Exception ex) { + Log.e(TAG, "Failure propagating logRPCReceive: " + ex.toString(), ex); + } // end-catch + } + } +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/IConsole.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/IConsole.java new file mode 100755 index 000000000..4537f1b29 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/IConsole.java @@ -0,0 +1,12 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.util; + +public interface IConsole { + void logInfo(String msg); + void logError(String msg); + void logError(String msg, Throwable ex); + void logRPCSend(String rpcMsg); + void logRPCReceive(String rpcMsg); +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/Mime.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/Mime.java new file mode 100755 index 000000000..d2c6241c6 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/Mime.java @@ -0,0 +1,185 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.util; + +public class Mime { + + private static String m_base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + public static Boolean isSafeASCII(String check) { + if (check.contains("&") || check.contains("<") || check.contains("]]") || check.contains("}") ) + return false; // these things aren't reliably CDATA encodable + + return true; + } + + public static String base64Encode(String toEncode) { + + byte[] bytesToEncode = new byte[toEncode.length()]; + for (int i=0; i< toEncode.length(); i++) + bytesToEncode[i] = (byte)toEncode.charAt(i); + + StringBuilder sb = new StringBuilder(); + + int idxin = 0; + int b64idx = 0; + + for (idxin=0;idxin < bytesToEncode.length;idxin++) { + switch (idxin % 3) { + case 0: + b64idx = (bytesToEncode[idxin] >> 2) & 0x3f; + break; + case 1: + b64idx = (bytesToEncode[idxin] >> 4) & 0x0f; + b64idx |= ((bytesToEncode[idxin-1] << 4)& 0x30); + break; + case 2: + b64idx = (bytesToEncode[idxin] >> 6) & 0x03; + b64idx |= ((bytesToEncode[idxin-1] << 2)& 0x3c); + sb.append(m_base64Chars.charAt(b64idx)); + b64idx = bytesToEncode[idxin] & 0x3f; + break; + } // end-switch + sb.append(m_base64Chars.charAt(b64idx)); + } // end-for + + switch (idxin % 3) { + case 0: + break; + case 1: + b64idx = (bytesToEncode[idxin-1] << 4) & 0x30; + sb.append(m_base64Chars.charAt(b64idx)); + sb.append("=="); + break; + case 2: + b64idx = ((bytesToEncode[idxin-1] << 2)& 0x3c); + sb.append(m_base64Chars.charAt(b64idx)); + sb.append('='); + break; + } // end-switch + + return sb.toString(); + } // end-method + + + private byte[] base64Decode(String base64String) { + byte[] outBytes = null; + byte[] base64ASCIIString = null; + final String ASCII_Encoding = "US-ASCII"; + + // Convert b64 string to raw bytes + try { + base64ASCIIString = base64String.getBytes(ASCII_Encoding); + } catch (Exception ex){ + // TODO + //publishStatus("Failure converting b64string to ASCII string: " + ex.toString()); + return null; + } + + if (!m_decodeInitComplete) { + m_decodeInitComplete = true; + initForDecode(); + } // end-if + + int numInChars = base64ASCIIString.length; + + if ((numInChars % 4) > 0) { + return null; + } // end-if + + int numOutBytes = base64ASCIIString.length / 4; + numOutBytes *= 3; + int eqpos = base64String.indexOf("="); + if (eqpos >= 0) { + numOutBytes--; + if (base64String.substring(eqpos).indexOf("==") >= 0) { + numOutBytes--; + } // end-if + } // end-if + outBytes = new byte[numOutBytes]; + + byte b64idxbits = 0x00; + int iidx = 0, oidx = 0; + byte writeByte = 0x00; + byte b64ASCIIChar = 0x00; + for (iidx=0, oidx=0;iidx < numInChars;iidx++) { + b64ASCIIChar = base64ASCIIString[iidx]; + if (b64ASCIIChar == 0x3d /*'='*/) { + return outBytes; + } // end-if + + if (!isb64char(b64ASCIIChar)) { + return null; + } // end-if + + switch (iidx % 4) { + case 0: + break; + case 1: + b64idxbits = b64decode[base64ASCIIString[iidx-1]]; + writeByte = (byte)((b64idxbits << 2) | ((b64decode[b64ASCIIChar] >> 4) & 0x03)); + outBytes[oidx++] = writeByte; + break; + case 2: + b64idxbits = b64decode[base64ASCIIString[iidx-1]]; + writeByte = (byte)(((b64idxbits << 4) & 0xf0) | ((b64decode[b64ASCIIChar] >> 2) & 0x0f)); + outBytes[oidx++] = writeByte; + break; + case 3: + b64idxbits = b64decode[base64ASCIIString[iidx-1]]; + writeByte = (byte)(((b64idxbits << 6) & 0xc0) | ((b64decode[b64ASCIIChar]) & 0x3f)); + outBytes[oidx++] = writeByte; + break; + } // end-switch + } // end-for + + return outBytes; + + } // end-method + + + private static byte[] b64decode = new byte[256]; + // A-Z is 0x41-0x5a + // a-z is 0x61-0x7a + // 0-9 is 0x30-0x39 + // + is 0x2b + // / is 0x2f + + private static boolean m_decodeInitComplete = false; + + private void initForDecode() { + int aidx = 0; + int lidx = 0; + // Set A-Z + for (aidx=0x41, lidx=0;aidx <= 0x5a;aidx++, lidx++) { + b64decode[aidx] = (byte)lidx; + } // end-for + // Set a-z + for (aidx=0x61;aidx <= 0x7a;aidx++, lidx++) { + b64decode[aidx] = (byte)lidx; + } // end-for + // Set 0-9 + for (aidx=0x30;aidx <= 0x39;aidx++, lidx++) { + b64decode[aidx] = (byte)lidx; + } // end-for + // Set '+' + b64decode[0x2b] = (byte)lidx++; + // Set '/' + b64decode[0x2f] = (byte)lidx++; + } // end-method + + private boolean isb64char(byte b) { + // A-Z is 0x41-0x5a + // a-z is 0x61-0x7a + // 0-9 is 0x30-0x39 + // + is 0x2b + // / is 0x2f + return ( (b >= 0x41 && b <= 0x5a) + || (b >= 0x61 && b <= 0x7a) + || (b >= 0x30 && b <= 0x39) + || (b == 0x2b) + || (b == 0x2f) + ); + } // end-method +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/NativeLogTool.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/NativeLogTool.java new file mode 100755 index 000000000..6e11f881a --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/NativeLogTool.java @@ -0,0 +1,103 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.util; + +import android.util.Log; + +import com.smartdevicelink.proxy.SmartDeviceLinkProxyBase; + +public class NativeLogTool { + + static private boolean logToSystemEnabled = true; + private static final int ChunkSize = 4000; + + private enum LogTarget { + Info + ,Warning + ,Error + } + + public static void setEnableState(boolean en) { + logToSystemEnabled = en; + } // end-method + + public static boolean isEnabled() { + return logToSystemEnabled; + } // end-method + + public static void logInfo(String message) { + logInfo(SmartDeviceLinkProxyBase.TAG, message); + } + + public static void logInfo(String tag, String message) { + if (logToSystemEnabled) { + log(LogTarget.Info, tag, message); + } + } + + public static void logWarning(String message) { + logWarning(SmartDeviceLinkProxyBase.TAG, message); + } + + public static void logWarning(String tag, String message) { + if (logToSystemEnabled) { + log(LogTarget.Warning, tag, message); + } + } + + public static void logError(String message) { + logError(SmartDeviceLinkProxyBase.TAG, message); + } + + public static void logError(String tag, String message) { + if (logToSystemEnabled) { + log(LogTarget.Error, tag, message); + } + } + + public static void logError(String message, Throwable t) { + logError(SmartDeviceLinkProxyBase.TAG, message, t); + } + + public static void logError(String tag, String message, Throwable t) { + // If the call to logError is passed a throwable, write directly to the system log + if (logToSystemEnabled) { + Log.e(tag, message, t); + } + } + + private static void log(LogTarget ltarg, String source, String logMsg) { + // Don't log empty messages + if (logMsg == null || logMsg.length() == 0) { + return; + } // end-if + + int bytesWritten = 0; + int substrSize = 0; + String tag = source; + String chunk = null; + try { + for (int idx=0;idx < logMsg.length();idx += substrSize) { + substrSize = Math.min(ChunkSize, logMsg.length() - idx); + chunk = logMsg.substring(idx, idx + substrSize); + switch (ltarg) { + case Info: + bytesWritten = Log.i(tag, chunk); + break; + case Warning: + bytesWritten = Log.w(tag, chunk); + break; + case Error: + bytesWritten = Log.e(tag, chunk); + break; + } // end-switch + if (bytesWritten < chunk.length()) { + Log.e(SmartDeviceLinkProxyBase.TAG, "Calling Log.e: msg length=" + chunk.length() + ", bytesWritten=" + bytesWritten); + } // end-if + } // end-while + } catch (Exception ex) { + Log.e(SmartDeviceLinkProxyBase.TAG, "Failure writing " + ltarg.name() + " fragments to android log:" + ex.toString()); + } // end-catch + } // end-method +} diff --git a/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/StringEnumer.java b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/StringEnumer.java new file mode 100755 index 000000000..e8c1814a3 --- /dev/null +++ b/SDL_Android/SmartDeviceLinkProxyAndroid/src/com/smartdevicelink/util/StringEnumer.java @@ -0,0 +1,50 @@ +// +// Copyright (c) 2013 Ford Motor Company +// +package com.smartdevicelink.util; + +import java.util.Vector; + +public abstract class StringEnumer { + + protected StringEnumer(int value, String name) { + this.value = value; + this.name = name; + } + + private int value; + private String name; + + public int getValue() { return value; } + public String getName() { return name; } + + public boolean equals(StringEnumer other) { + return name == other.getName(); + } + + public boolean eq(StringEnumer other) { + return equals(other); + } + + public String toString() { + return name; + } + + public static StringEnumer get(Vector<? extends StringEnumer> theList, int value) { + for (StringEnumer current : theList) { + if (current.getValue() == value) { + return current; + } + } + return null; + } + + public static StringEnumer get(Vector<? extends StringEnumer> theList, String name) { + for (StringEnumer current : theList) { + if (current.getName().equalsIgnoreCase(name)) { + return current; + } + } + return null; + } +} |