summaryrefslogtreecommitdiff
path: root/SDL_Android/LivioSdlUtilities/src/com/livio/sdl/SdlResponseTracker.java
blob: e7e6fa3bf327f275f9c6ce1a43a64c2bcc339d87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package com.livio.sdl;

import android.util.SparseArray;

import com.livio.sdl.utils.Timeout;
import com.smartdevicelink.proxy.RPCRequest;

/**
 * Tracks outgoing requests to core and sets a timeout for when the response
 * should come back from core.  If a request isn't received by the time
 * the timeout expires, it should be assumed that SDL core disconnected.
 *
 * @author Mike Burke
 *
 */
public class SdlResponseTracker {

	/**
	 * Listener interface for SdlResponseTracker.  Contains callback method
	 * for when any request times out.
	 *
	 * @author Mike Burke
	 *
	 */
	public interface Listener{
		public void onRequestTimedOut();
	}
	
	/**
	 * Default timeout to receive a response for a typical request.
	 */
	public static final int DEFAULT_TIMEOUT = 5000; // 5 seconds
	
	private SparseArray<RPCRequest> requests = new SparseArray<RPCRequest>();
	private SparseArray<Timeout> timeouts = new SparseArray<Timeout>();
	
	private Listener listener;
	
	public SdlResponseTracker(Listener l) {
		this.listener = l;
	}
	
	/**
	 * Adds a request to the tracker with a default timeout.
	 * 
	 * @param request The request to track
	 */
	public void add(RPCRequest request){
		add(request, DEFAULT_TIMEOUT);
	}
	
	/**
	 * Adds a request to the tracker with a specified timeout.
	 * 
	 * @param request The request to track
	 * @param duration The timeout duration (in ms)
	 */
	public void add(RPCRequest request, int duration){
		int corrId = request.getCorrelationID();
		requests.put(corrId, request);
		
		Timeout timeout = new Timeout(duration, new Timeout.Listener() {
			@Override public void onTimeoutCancelled() {}
			
			@Override
			public void onTimeoutCompleted() {
				notifyRequestTimedOut();
			}
		});
		timeout.start();
		timeouts.put(corrId, timeout);
	}
	
	/**
	 * Removes the specified correlation id from the tracker.  Also automatically
	 * cancels the associated timer for the specified correlation id.
	 * 
	 * @param corrId The correlation id to stop tracking
	 * @return The request that was removed
	 */
	public RPCRequest remove(int corrId){
		timeouts.get(corrId).cancel();
		timeouts.remove(corrId);
		
		RPCRequest result = requests.get(corrId);
		requests.remove(corrId);
		return result;
	}
	
	/**
	 * Clears all requests being tracked and cancels their associated timeouts.
	 */
	public void clear(){
		if(requests != null){
			// loop through requests and remove each one
			for(int numItems = requests.size()-1; numItems >= 0; numItems--){
				RPCRequest request = requests.valueAt(numItems);
				remove(request.getCorrelationID());
			}
		}
	}
	
	private void notifyRequestTimedOut(){
		if(listener != null){
			listener.onRequestTimedOut();
		}
	}

}