summaryrefslogtreecommitdiff
path: root/sdl_android/src/main/java/com/smartdevicelink/proxy/SystemCapabilityManager.java
blob: b5dac4768eda65cea7c252f6aca5072f3d3f34bd (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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package com.smartdevicelink.proxy;

import com.smartdevicelink.exception.SdlException;
import com.smartdevicelink.proxy.interfaces.ISdl;
import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener;
import com.smartdevicelink.proxy.rpc.GetSystemCapability;
import com.smartdevicelink.proxy.rpc.GetSystemCapabilityResponse;
import com.smartdevicelink.proxy.rpc.HMICapabilities;
import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse;
import com.smartdevicelink.proxy.rpc.enums.Result;
import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener;
import com.smartdevicelink.util.CorrelationIdGenerator;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class SystemCapabilityManager {
	HashMap<SystemCapabilityType, Object> cachedSystemCapabilities = new HashMap<>();
	ISdl callback;

	public SystemCapabilityManager(ISdl callback){
		this.callback = callback;
	}

	public void parseRAIResponse(RegisterAppInterfaceResponse response){
		if(response!=null && response.getSuccess()) {
			cachedSystemCapabilities.put(SystemCapabilityType.HMI, response.getHmiCapabilities());
			cachedSystemCapabilities.put(SystemCapabilityType.DISPLAY, response.getDisplayCapabilities());
			cachedSystemCapabilities.put(SystemCapabilityType.AUDIO_PASSTHROUGH, response.getAudioPassThruCapabilities());
			cachedSystemCapabilities.put(SystemCapabilityType.BUTTON, response.getButtonCapabilities());
			cachedSystemCapabilities.put(SystemCapabilityType.HMI_ZONE, response.getHmiZoneCapabilities());
			cachedSystemCapabilities.put(SystemCapabilityType.PRESET_BANK, response.getPresetBankCapabilities());
			cachedSystemCapabilities.put(SystemCapabilityType.SOFTBUTTON, response.getSoftButtonCapabilities());
			cachedSystemCapabilities.put(SystemCapabilityType.SPEECH, response.getSpeechCapabilities());
			cachedSystemCapabilities.put(SystemCapabilityType.VOICE_RECOGNITION, response.getVrCapabilities());
		}
	}

	/**
	 * Sets a capability in the cached map. This should only be done when an RPC is received and contains updates to the capability
	 * that is being cached in the SystemCapabilityManager.
	 * @param systemCapabilityType
	 * @param capability
	 */
	public void setCapability(SystemCapabilityType systemCapabilityType, Object capability){
		cachedSystemCapabilities.put(systemCapabilityType,capability);
	}

	/**
	 * Ability to see if the connected module supports the given capability. Useful to check before
	 * attempting to query for capabilities that require asynchronous calls to initialize.
	 * @param type the SystemCapabilityType that is to be checked
	 * @return if that capability is supported with the current, connected module
	 */
	public boolean isCapabilitySupported(SystemCapabilityType type){
		if(cachedSystemCapabilities.containsKey(type)){
			return true;
		}else if(cachedSystemCapabilities.containsKey(SystemCapabilityType.HMI)){
			HMICapabilities hmiCapabilities = ((HMICapabilities)cachedSystemCapabilities.get(SystemCapabilityType.HMI));
			switch (type) {
				case NAVIGATION:
					return hmiCapabilities.isNavigationAvailable();
				case PHONE_CALL:
					return hmiCapabilities.isPhoneCallAvailable();
				case VIDEO_STREAMING:
					return hmiCapabilities.isVideoStreamingAvailable();
				case REMOTE_CONTROL:
					return hmiCapabilities.isRemoteControlAvailable();
				default:
					return false;
			}
		}else{
			return false;
		}
	}
	/**
	 * @param systemCapabilityType Type of capability desired
	 * @param scListener callback to execute upon retrieving capability
	 */
	public void getCapability(final SystemCapabilityType systemCapabilityType, final OnSystemCapabilityListener scListener){
		Object capability = cachedSystemCapabilities.get(systemCapabilityType);
		if(capability != null){
			scListener.onCapabilityRetrieved(capability);
		}else if(scListener == null){
			return;
		}

		retrieveCapability(systemCapabilityType, scListener);
	}

	/**
	 * @param systemCapabilityType Type of capability desired
	 * @return Desired capability if it is cached in the manager, otherwise returns a null object
	 * and works in the background to retrieve the capability for the next call
	 */
	public Object getCapability(final SystemCapabilityType systemCapabilityType){
		Object capability = cachedSystemCapabilities.get(systemCapabilityType);
		if(capability != null){
			return capability;
		}

		retrieveCapability(systemCapabilityType, null);
		return null;
	}

	/**
	 * @param systemCapabilityType Type of capability desired
	 * passes GetSystemCapabilityType request to  `callback` to be sent by proxy
	 */
	private void retrieveCapability(final SystemCapabilityType systemCapabilityType, final OnSystemCapabilityListener scListener){
		final GetSystemCapability request = new GetSystemCapability();
		request.setSystemCapabilityType(systemCapabilityType);
		request.setOnRPCResponseListener(new OnRPCResponseListener() {
			@Override
			public void onResponse(int correlationId, RPCResponse response) {
				if(response.getSuccess()){
					Object retrievedCapability = ((GetSystemCapabilityResponse) response).getSystemCapability().getCapabilityForType(systemCapabilityType);
					cachedSystemCapabilities.put(systemCapabilityType, retrievedCapability);
					if(scListener!=null){scListener.onCapabilityRetrieved(retrievedCapability);	}
				}else{
					if(scListener!=null){scListener.onError(response.getInfo());}
				}
			}

			@Override
			public void onError(int correlationId, Result resultCode, String info) {
				if(scListener!=null){scListener.onError(info);}
			}
		});
		request.setCorrelationID(CorrelationIdGenerator.generateId());

		if(callback!=null){
			callback.sendRPCRequest(request);
		}
	}

	/**
	 * Converts a capability object into a list.
	 * @param object the capability that needs to be converted
	 * @param classType The class type of that should be contained in the list
	 * @return a List of capabilities if object is instance of List, otherwise it will return null.
	 */
	@SuppressWarnings({"unchecked"})
	public static <T> List<T> convertToList(Object object, Class<T> classType){
		if(classType!=null && object!=null && object instanceof List ){
			List list = (List)object;
			if(!list.isEmpty()){
				if(classType.isInstance(list.get(0))){
					return (List<T>)object;
				}else{
					//The list is not of the correct list type
					return null;
				}
			}else {
				//We return a new list of type T instead of null because while we don't know if
				//the original list was of type T we want to ensure that we don't throw a cast class exception
				//but still
				return new ArrayList<T>();
			}
		}else{
			return null;
		}
	}
}