summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBretty <brettywhite@users.noreply.github.com>2018-03-09 11:02:06 -0500
committerJoey Grover <joeygrover@gmail.com>2018-03-09 11:02:06 -0500
commit115942eb69d8d1490f7106bbe0f715e9bb3bc6c4 (patch)
treee2b6787a5b2b20d915125220f83c081997c36bf9
parentf1d8dbac21709f2b9332eefa1cc0f0bbab35cbf4 (diff)
downloadsdl_android-115942eb69d8d1490f7106bbe0f715e9bb3bc6c4.tar.gz
Feature/issue 606 send multiple RPCS (#685)
* initial commit multple RPC work * added javadocs * working sending async * removed uneccessary call * send multiple async * updated method name for clarity * remove code per bilal’s review * new javadoc for method * start of tests * adding some tests * adding one more assert / fix comments * remove duplicate method / fixes * addressed final issues * fixed error override in tests * removed unused lock object * add onError callback
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java116
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java120
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnMultipleRequestListener.java52
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnRPCResponseListener.java4
4 files changed, 289 insertions, 3 deletions
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java
index fdc52f9b7..b50f6f48d 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java
@@ -8,7 +8,10 @@ import android.util.Log;
import com.smartdevicelink.exception.SdlException;
import com.smartdevicelink.exception.SdlExceptionCause;
+import com.smartdevicelink.proxy.RPCRequest;
+import com.smartdevicelink.proxy.RPCResponse;
import com.smartdevicelink.proxy.SdlProxyALM;
+import com.smartdevicelink.proxy.SdlProxyBase;
import com.smartdevicelink.proxy.SdlProxyBuilder;
import com.smartdevicelink.proxy.SdlProxyConfigurationResources;
import com.smartdevicelink.proxy.callbacks.OnServiceEnded;
@@ -66,6 +69,7 @@ import com.smartdevicelink.proxy.rpc.SetDisplayLayoutResponse;
import com.smartdevicelink.proxy.rpc.SetGlobalPropertiesResponse;
import com.smartdevicelink.proxy.rpc.SetInteriorVehicleDataResponse;
import com.smartdevicelink.proxy.rpc.SetMediaClockTimerResponse;
+import com.smartdevicelink.proxy.rpc.Show;
import com.smartdevicelink.proxy.rpc.ShowConstantTbtResponse;
import com.smartdevicelink.proxy.rpc.ShowResponse;
import com.smartdevicelink.proxy.rpc.SliderResponse;
@@ -79,7 +83,9 @@ import com.smartdevicelink.proxy.rpc.UnsubscribeButtonResponse;
import com.smartdevicelink.proxy.rpc.UnsubscribeVehicleDataResponse;
import com.smartdevicelink.proxy.rpc.UnsubscribeWayPointsResponse;
import com.smartdevicelink.proxy.rpc.UpdateTurnListResponse;
+import com.smartdevicelink.proxy.rpc.enums.Result;
import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason;
+import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener;
import com.smartdevicelink.streaming.video.SdlRemoteDisplay;
import com.smartdevicelink.streaming.video.VideoStreamingParameters;
import com.smartdevicelink.test.streaming.video.SdlRemoteDisplayTest;
@@ -87,6 +93,8 @@ import com.smartdevicelink.test.streaming.video.SdlRemoteDisplayTest;
import junit.framework.Assert;
import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
public class SdlProxyBaseTests extends AndroidTestCase{
@@ -162,6 +170,114 @@ public class SdlProxyBaseTests extends AndroidTestCase{
}
}
+ public void testMultipleRPCSendSynchronous() {
+
+ List<RPCRequest> rpcs = new ArrayList<>();
+
+ // rpc 1
+ Show show = new Show();
+ show.setMainField1("hey y'all");
+ show.setMainField2("");
+ show.setMainField3("");
+ show.setMainField4("");
+ rpcs.add(show);
+
+ // rpc 2
+ Show show2 = new Show();
+ show2.setMainField1("");
+ show2.setMainField2("It is Wednesday My Dudes");
+ show2.setMainField3("");
+ show2.setMainField4("");
+ rpcs.add(show2);
+
+ OnMultipleRequestListener mrl = new OnMultipleRequestListener() {
+ @Override
+ public void onUpdate(int remainingRequests) {
+
+ }
+
+ @Override
+ public void onFinished() {
+
+ }
+
+ @Override
+ public void onError(int correlationId, Result resultCode, String info) {
+ assert false;
+ }
+
+ @Override
+ public void onResponse(int correlationId, RPCResponse response) {
+
+ }
+ };
+ try{
+ // public void sendRequests(List<RPCRequest> rpcs, final OnMultipleRequestListener listener) throws SdlException {
+ Method m = SdlProxyBase.class.getDeclaredMethod("sendRequests", SdlProxyBase.class);
+ assertNotNull(m);
+ m.setAccessible(true);
+ m.invoke(rpcs,mrl);
+ assert true;
+
+ }catch (Exception e){
+ assert false;
+ }
+ }
+
+ public void testMultipleRPCSendAsynchronous() {
+
+ List<RPCRequest> rpcs = new ArrayList<>();
+
+ // rpc 1
+ Show show = new Show();
+ show.setMainField1("hey y'all");
+ show.setMainField2("");
+ show.setMainField3("");
+ show.setMainField4("");
+ rpcs.add(show);
+
+ // rpc 2
+ Show show2 = new Show();
+ show2.setMainField1("");
+ show2.setMainField2("It is Wednesday My Dudes");
+ show2.setMainField3("");
+ show2.setMainField4("");
+ rpcs.add(show2);
+
+ OnMultipleRequestListener mrl = new OnMultipleRequestListener() {
+ @Override
+ public void onUpdate(int remainingRequests) {
+
+ }
+
+ @Override
+ public void onFinished() {
+
+ }
+
+ @Override
+ public void onError(int correlationId, Result resultCode, String info) {
+ assert false;
+ }
+
+ @Override
+ public void onResponse(int correlationId, RPCResponse response) {
+
+ }
+ };
+ try{
+ // public void sendSequentialRequests(List<RPCRequest> rpcs, final OnMultipleRequestListener listener) throws SdlException {
+ Method m = SdlProxyBase.class.getDeclaredMethod("sendSequentialRequests", SdlProxyBase.class);
+ assertNotNull(m);
+ m.setAccessible(true);
+ m.invoke(rpcs,mrl);
+ assert true;
+
+ }catch (Exception e){
+ assert false;
+ }
+ }
+
public class ProxyListenerTest implements IProxyListenerALM {
@Override
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
index 67b3d15da..fffeb4525 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
@@ -93,6 +93,7 @@ import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
import com.smartdevicelink.proxy.rpc.enums.TextAlignment;
import com.smartdevicelink.proxy.rpc.enums.TouchType;
import com.smartdevicelink.proxy.rpc.enums.UpdateMode;
+import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener;
import com.smartdevicelink.proxy.rpc.listeners.OnPutFileUpdateListener;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener;
@@ -108,6 +109,7 @@ import com.smartdevicelink.trace.enums.InterfaceActivityDirection;
import com.smartdevicelink.transport.BaseTransportConfig;
import com.smartdevicelink.transport.SiphonServer;
import com.smartdevicelink.transport.enums.TransportType;
+import com.smartdevicelink.util.CorrelationIdGenerator;
import com.smartdevicelink.util.DebugTool;
@@ -130,7 +132,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530,
POLICIES_CORRELATION_ID = 65535;
- // Sdlhronization Objects
+ // Sdl Synchronization Objects
private static final Object CONNECTION_REFERENCE_LOCK = new Object(),
INCOMING_MESSAGE_QUEUE_THREAD_LOCK = new Object(),
OUTGOING_MESSAGE_QUEUE_THREAD_LOCK = new Object(),
@@ -3425,12 +3427,124 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
SdlTrace.logProxyEvent("Proxy received RPC Message: " + functionName, SDL_LIB_TRACE_KEY);
}
+
+ /**
+ * Takes a list of RPCRequests and sends it to SDL in a synchronous fashion. Responses are captured through callback on OnMultipleRequestListener.
+ * For sending requests asynchronously, use sendRequests <br>
+ *
+ * <strong>NOTE: This will override any listeners on individual RPCs</strong>
+ *
+ * @param rpcs is the list of RPCRequests being sent
+ * @param listener listener for updates and completions
+ * @throws SdlException if an unrecoverable error is encountered
+ */
+ @SuppressWarnings("unused")
+ public void sendSequentialRequests(final List<RPCRequest> rpcs, final OnMultipleRequestListener listener) throws SdlException {
+ if (_proxyDisposed) {
+ throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED);
+ }
+
+ SdlTrace.logProxyEvent("Application called sendSequentialRequests", SDL_LIB_TRACE_KEY);
+
+ synchronized(CONNECTION_REFERENCE_LOCK) {
+ if (!getIsConnected()) {
+ SdlTrace.logProxyEvent("Application attempted to call sendSequentialRequests without a connected transport.", SDL_LIB_TRACE_KEY);
+ throw new SdlException("There is no valid connection to SDL. sendSequentialRequests cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE);
+ }
+ }
+
+ if (rpcs == null){
+ //Log error here
+ throw new SdlException("You must send some RPCs", SdlExceptionCause.INVALID_ARGUMENT);
+ }
+
+ int requestCount = rpcs.size();
+
+ // Break out of recursion, we have finished the requests
+ if (requestCount == 0) {
+ listener.onFinished();
+ return;
+ }
+
+ RPCRequest rpc = rpcs.remove(0);
+ rpc.setCorrelationID(CorrelationIdGenerator.generateId());
+
+ rpc.setOnRPCResponseListener(new OnRPCResponseListener() {
+ @Override
+ public void onResponse(int correlationId, RPCResponse response) {
+ if (response.getSuccess()) {
+ // success
+ listener.onUpdate(rpcs.size());
+ try {
+ // recurse after successful response of RPC
+ sendSequentialRequests(rpcs, listener);
+ } catch (SdlException e) {
+ e.printStackTrace();
+ listener.onError(correlationId, Result.GENERIC_ERROR, e.toString());
+ }
+ }
+ }
+
+ @Override
+ public void onError(int correlationId, Result resultCode, String info){
+ listener.onError(correlationId, resultCode, info);
+ }
+ });
+
+ sendRPCRequestPrivate(rpc);
+ }
+
+ /**
+ * Takes a list of RPCRequests and sends it to SDL. Responses are captured through callback on OnMultipleRequestListener.
+ * For sending requests synchronously, use sendSequentialRequests <br>
+ *
+ * <strong>NOTE: This will override any listeners on individual RPCs</strong>
+ *
+ * @param rpcs is the list of RPCRequests being sent
+ * @param listener listener for updates and completions
+ * @throws SdlException if an unrecoverable error is encountered
+ */
+ @SuppressWarnings("unused")
+ public void sendRequests(List<RPCRequest> rpcs, final OnMultipleRequestListener listener) throws SdlException {
+
+ if (_proxyDisposed) {
+ throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED);
+ }
+
+ SdlTrace.logProxyEvent("Application called sendRequests", SDL_LIB_TRACE_KEY);
+
+ synchronized(CONNECTION_REFERENCE_LOCK) {
+ if (!getIsConnected()) {
+ SdlTrace.logProxyEvent("Application attempted to call sendRequests without a connected transport.", SDL_LIB_TRACE_KEY);
+ throw new SdlException("There is no valid connection to SDL. sendRequests cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE);
+ }
+ }
+
+ if (rpcs == null){
+ //Log error here
+ throw new SdlException("You must send some RPCs, the array is null", SdlExceptionCause.INVALID_ARGUMENT);
+ }
+
+ int arraySize = rpcs.size();
+
+ if (arraySize == 0) {
+ throw new SdlException("You must send some RPCs, the array is empty", SdlExceptionCause.INVALID_ARGUMENT);
+ }
+
+ for (int i = 0; i < arraySize; i++) {
+ RPCRequest rpc = rpcs.get(i);
+ rpc.setCorrelationID(CorrelationIdGenerator.generateId());
+ listener.addCorrelationId(rpc.getCorrelationID());
+ rpc.setOnRPCResponseListener(listener.getSingleRpcResponseListener());
+ sendRPCRequestPrivate(rpc);
+ }
+ }
/**
* Takes an RPCRequest and sends it to SDL. Responses are captured through callback on IProxyListener.
*
* @param request is the RPCRequest being sent
- * @throws SdlException if an unrecoverable error is encountered if an unrecoverable error is encountered
+ * @throws SdlException if an unrecoverable error is encountered
*/
public void sendRPCRequest(RPCRequest request) throws SdlException {
if (_proxyDisposed) {
@@ -3474,7 +3588,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
SdlTrace.logProxyEvent("Application attempted to send a RegisterAppInterface or UnregisterAppInterface while using ALM.", SDL_LIB_TRACE_KEY);
throw new SdlException("The RPCRequest, " + request.getFunctionName() +
- ", is unallowed using the Advanced Lifecycle Management Model.", SdlExceptionCause.INCORRECT_LIFECYCLE_MODEL);
+ ", is un-allowed using the Advanced Lifecycle Management Model.", SdlExceptionCause.INCORRECT_LIFECYCLE_MODEL);
}
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnMultipleRequestListener.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnMultipleRequestListener.java
new file mode 100644
index 000000000..107de1bf9
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnMultipleRequestListener.java
@@ -0,0 +1,52 @@
+package com.smartdevicelink.proxy.rpc.listeners;
+
+import android.util.Log;
+
+import com.smartdevicelink.proxy.RPCResponse;
+import com.smartdevicelink.proxy.rpc.enums.Result;
+
+import org.json.JSONException;
+
+import java.util.Vector;
+
+/**
+ * This is the listener for sending Multiple RPCs.
+ */
+public abstract class OnMultipleRequestListener extends OnRPCResponseListener {
+
+ final Vector<Integer> correlationIds;
+ OnRPCResponseListener rpcResponseListener;
+ private static String TAG = "OnMultipleRequestListener";
+
+ public OnMultipleRequestListener(){
+ setListenerType(UPDATE_LISTENER_TYPE_MULTIPLE_REQUESTS);
+ correlationIds = new Vector<>();
+
+ rpcResponseListener = new OnRPCResponseListener() {
+ @Override
+ public void onResponse(int correlationId, RPCResponse response) {
+ correlationIds.remove(Integer.valueOf(correlationId));
+ if(correlationIds.size()>0){
+ onUpdate(correlationIds.size());
+ }else{
+ onFinished();
+ }
+ }
+ };
+ }
+
+ public void addCorrelationId(int correlationid){
+ correlationIds.add(correlationid);
+ }
+ /**
+ * onUpdate is called during multiple stream request
+ * @param remainingRequests of the original request
+ */
+ public abstract void onUpdate(int remainingRequests);
+ public abstract void onFinished();
+ public abstract void onError(int correlationId, Result resultCode, String info);
+
+ public OnRPCResponseListener getSingleRpcResponseListener(){
+ return rpcResponseListener;
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnRPCResponseListener.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnRPCResponseListener.java
index 4bc5ccd79..c21244926 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnRPCResponseListener.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/listeners/OnRPCResponseListener.java
@@ -12,6 +12,10 @@ public abstract class OnRPCResponseListener {
* Listener type specific to putfile
*/
public final static int UPDATE_LISTENER_TYPE_PUT_FILE = 1;
+ /**
+ * Listener type specific to sendRequests and sendSequentialRequests
+ */
+ public final static int UPDATE_LISTENER_TYPE_MULTIPLE_REQUESTS = 2;
/**
* Stores what type of listener this instance is. This prevents of from having to use reflection