1 /*
2  * Copyright (C) 2016 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.googlecode.android_scripting.facade;
18 
19 import java.lang.reflect.Method;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.SortedMap;
27 import java.util.TreeMap;
28 
29 import com.google.common.collect.Maps;
30 import com.googlecode.android_scripting.Log;
31 import com.googlecode.android_scripting.facade.bluetooth.BluetoothA2dpFacade;
32 import com.googlecode.android_scripting.facade.bluetooth.BluetoothA2dpSinkFacade;
33 import com.googlecode.android_scripting.facade.bluetooth.BluetoothAvrcpFacade;
34 import com.googlecode.android_scripting.facade.bluetooth.BluetoothConnectionFacade;
35 import com.googlecode.android_scripting.facade.bluetooth.BluetoothFacade;
36 import com.googlecode.android_scripting.facade.bluetooth.BluetoothHidFacade;
37 import com.googlecode.android_scripting.facade.bluetooth.BluetoothHspFacade;
38 import com.googlecode.android_scripting.facade.bluetooth.BluetoothHfpClientFacade;
39 import com.googlecode.android_scripting.facade.bluetooth.BluetoothA2dpFacade;
40 import com.googlecode.android_scripting.facade.bluetooth.BluetoothLeAdvertiseFacade;
41 import com.googlecode.android_scripting.facade.bluetooth.BluetoothLeScanFacade;
42 import com.googlecode.android_scripting.facade.bluetooth.BluetoothMapFacade;
43 import com.googlecode.android_scripting.facade.bluetooth.BluetoothRfcommFacade;
44 import com.googlecode.android_scripting.facade.bluetooth.GattClientFacade;
45 import com.googlecode.android_scripting.facade.bluetooth.GattServerFacade;
46 import com.googlecode.android_scripting.facade.media.AudioManagerFacade;
47 import com.googlecode.android_scripting.facade.media.MediaPlayerFacade;
48 import com.googlecode.android_scripting.facade.media.MediaRecorderFacade;
49 import com.googlecode.android_scripting.facade.media.MediaScannerFacade;
50 import com.googlecode.android_scripting.facade.media.MediaSessionFacade;
51 import com.googlecode.android_scripting.facade.telephony.CarrierConfigFacade;
52 import com.googlecode.android_scripting.facade.telephony.ImsManagerFacade;
53 import com.googlecode.android_scripting.facade.telephony.SmsFacade;
54 import com.googlecode.android_scripting.facade.telephony.SubscriptionManagerFacade;
55 import com.googlecode.android_scripting.facade.telephony.TelecomCallFacade;
56 import com.googlecode.android_scripting.facade.telephony.TelecomManagerFacade;
57 import com.googlecode.android_scripting.facade.telephony.TelephonyManagerFacade;
58 import com.googlecode.android_scripting.facade.ui.UiFacade;
59 import com.googlecode.android_scripting.facade.wifi.HttpFacade;
60 import com.googlecode.android_scripting.facade.wifi.WifiManagerFacade;
61 import com.googlecode.android_scripting.facade.wifi.WifiNanManagerFacade;
62 import com.googlecode.android_scripting.facade.wifi.WifiP2pManagerFacade;
63 import com.googlecode.android_scripting.facade.wifi.WifiRttManagerFacade;
64 import com.googlecode.android_scripting.facade.wifi.WifiScannerFacade;
65 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
66 import com.googlecode.android_scripting.rpc.MethodDescriptor;
67 import com.googlecode.android_scripting.rpc.RpcDeprecated;
68 import com.googlecode.android_scripting.rpc.RpcMinSdk;
69 import com.googlecode.android_scripting.rpc.RpcStartEvent;
70 import com.googlecode.android_scripting.rpc.RpcStopEvent;
71 import com.googlecode.android_scripting.webcam.WebCamFacade;
72 
73 /**
74  * Encapsulates the list of supported facades and their construction.
75  */
76 public class FacadeConfiguration {
77     private final static Set<Class<? extends RpcReceiver>> sFacadeClassList;
78     private final static SortedMap<String, MethodDescriptor> sRpcs =
79             new TreeMap<String, MethodDescriptor>();
80 
81     private static int sSdkLevel;
82 
83     static {
84         sSdkLevel = android.os.Build.VERSION.SDK_INT;
85 
86         sFacadeClassList = new HashSet<Class<? extends RpcReceiver>>();
87         sFacadeClassList.add(ActivityResultFacade.class);
88         sFacadeClassList.add(AndroidFacade.class);
89         sFacadeClassList.add(ApplicationManagerFacade.class);
90         sFacadeClassList.add(AudioManagerFacade.class);
91         sFacadeClassList.add(BatteryManagerFacade.class);
92         sFacadeClassList.add(CameraFacade.class);
93         sFacadeClassList.add(CommonIntentsFacade.class);
94         sFacadeClassList.add(ContactsFacade.class);
95         sFacadeClassList.add(EventFacade.class);
96         sFacadeClassList.add(ImsManagerFacade.class);
97         sFacadeClassList.add(LocationFacade.class);
98         sFacadeClassList.add(TelephonyManagerFacade.class);
99         sFacadeClassList.add(PreferencesFacade.class);
100         sFacadeClassList.add(MediaPlayerFacade.class);
101         sFacadeClassList.add(MediaRecorderFacade.class);
102         sFacadeClassList.add(MediaScannerFacade.class);
103         sFacadeClassList.add(MediaSessionFacade.class);
104         sFacadeClassList.add(SensorManagerFacade.class);
105         sFacadeClassList.add(SettingsFacade.class);
106         sFacadeClassList.add(SmsFacade.class);
107         sFacadeClassList.add(SpeechRecognitionFacade.class);
108         sFacadeClassList.add(ToneGeneratorFacade.class);
109         sFacadeClassList.add(WakeLockFacade.class);
110         sFacadeClassList.add(HttpFacade.class);
111         sFacadeClassList.add(WifiManagerFacade.class);
112         sFacadeClassList.add(UiFacade.class);
113         sFacadeClassList.add(TextToSpeechFacade.class);
114         sFacadeClassList.add(BluetoothFacade.class);
115         sFacadeClassList.add(BluetoothA2dpFacade.class);
116         sFacadeClassList.add(BluetoothAvrcpFacade.class);
117         sFacadeClassList.add(BluetoothConnectionFacade.class);
118         sFacadeClassList.add(BluetoothHspFacade.class);
119         sFacadeClassList.add(BluetoothHidFacade.class);
120         sFacadeClassList.add(BluetoothMapFacade.class);
121         sFacadeClassList.add(BluetoothRfcommFacade.class);
122         sFacadeClassList.add(WebCamFacade.class);
123         sFacadeClassList.add(WifiP2pManagerFacade.class);
124         sFacadeClassList.add(BluetoothLeScanFacade.class);
125         sFacadeClassList.add(BluetoothLeAdvertiseFacade.class);
126         sFacadeClassList.add(GattClientFacade.class);
127         sFacadeClassList.add(GattServerFacade.class);
128         sFacadeClassList.add(ConnectivityManagerFacade.class);
129         sFacadeClassList.add(DisplayFacade.class);
130         sFacadeClassList.add(TelecomManagerFacade.class);
131         sFacadeClassList.add(WifiRttManagerFacade.class);
132         sFacadeClassList.add(WifiScannerFacade.class);
133         sFacadeClassList.add(SubscriptionManagerFacade.class);
134         sFacadeClassList.add(TelecomCallFacade.class);
135         sFacadeClassList.add(CarrierConfigFacade.class);
136 
137         /*Compatibility reset to >= Marshmallow */
138         if( sSdkLevel >= 23 ) {
139             //add new facades here
140             sFacadeClassList.add(WifiNanManagerFacade.class);
141             sFacadeClassList.add(BluetoothHfpClientFacade.class);
142         }
143 
144         for (Class<? extends RpcReceiver> recieverClass : sFacadeClassList) {
145             for (MethodDescriptor rpcMethod : MethodDescriptor.collectFrom(recieverClass)) {
rpcMethod.getName()146                 sRpcs.put(rpcMethod.getName(), rpcMethod);
147             }
148         }
149     }
150 
FacadeConfiguration()151     private FacadeConfiguration() {
152         // Utility class.
153     }
154 
getSdkLevel()155     public static int getSdkLevel() {
156         return sSdkLevel;
157     }
158 
159     /** Returns a list of {@link MethodDescriptor} objects for all facades. */
collectMethodDescriptors()160     public static List<MethodDescriptor> collectMethodDescriptors() {
161         return new ArrayList<MethodDescriptor>(sRpcs.values());
162     }
163 
164     /**
165      * Returns a list of not deprecated {@link MethodDescriptor} objects for facades supported by
166      * the current SDK version.
167      */
collectSupportedMethodDescriptors()168     public static List<MethodDescriptor> collectSupportedMethodDescriptors() {
169         List<MethodDescriptor> list = new ArrayList<MethodDescriptor>();
170         for (MethodDescriptor descriptor : sRpcs.values()) {
171             Method method = descriptor.getMethod();
172             if (method.isAnnotationPresent(RpcDeprecated.class)) {
173                 continue;
174             } else if (method.isAnnotationPresent(RpcMinSdk.class)) {
175                 int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value();
176                 if (sSdkLevel < requiredSdkLevel) {
177                     continue;
178                 }
179             }
180             list.add(descriptor);
181         }
182         return list;
183     }
184 
collectStartEventMethodDescriptors()185     public static Map<String, MethodDescriptor> collectStartEventMethodDescriptors() {
186         Map<String, MethodDescriptor> map = Maps.newHashMap();
187         for (MethodDescriptor descriptor : sRpcs.values()) {
188             Method method = descriptor.getMethod();
189             if (method.isAnnotationPresent(RpcStartEvent.class)) {
190                 String eventName = method.getAnnotation(RpcStartEvent.class).value();
191                 if (map.containsKey(eventName)) {
192                     Log.d("Duplicate eventName " + eventName);
193                     throw new RuntimeException("Duplicate start event method descriptor found.");
194                 }
195                 map.put(eventName, descriptor);
196             }
197         }
198         return map;
199     }
200 
collectStopEventMethodDescriptors()201     public static Map<String, MethodDescriptor> collectStopEventMethodDescriptors() {
202         Map<String, MethodDescriptor> map = Maps.newHashMap();
203         for (MethodDescriptor descriptor : sRpcs.values()) {
204             Method method = descriptor.getMethod();
205             if (method.isAnnotationPresent(RpcStopEvent.class)) {
206                 String eventName = method.getAnnotation(RpcStopEvent.class).value();
207                 if (map.containsKey(eventName)) {
208                     throw new RuntimeException("Duplicate stop event method descriptor found.");
209                 }
210                 map.put(eventName, descriptor);
211             }
212         }
213         return map;
214     }
215 
216     /** Returns a method by name. */
getMethodDescriptor(String name)217     public static MethodDescriptor getMethodDescriptor(String name) {
218         return sRpcs.get(name);
219     }
220 
getFacadeClasses()221     public static Collection<Class<? extends RpcReceiver>> getFacadeClasses() {
222         return sFacadeClassList;
223     }
224 }
225