Unit tests for android extension of resource contianer
[platform/upstream/iotivity.git] / service / resource-container / android / resource-container / src / main / java / org / iotivity / service / resourcecontainer / RcsResourceContainer.java
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21
22 /**
23  * @file
24  * This file contains the Resource Container APIs
25  */
26 package org.iotivity.service.resourcecontainer;
27
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Enumeration;
31 import android.util.Log;
32 import android.content.Context;
33 import java.util.Vector;
34
35 import dalvik.system.DexFile;
36 import android.content.pm.ApplicationInfo;
37 import android.content.pm.PackageManager;
38
39 import java.util.Hashtable;
40
41 // TODO null check for parameters
42 /**
43  * This class provides APIs for managing the container and bundles in the
44  * container.
45  */
46 public class RcsResourceContainer implements RcsResourceContainerBundleAPI {
47
48     private static final String TAG = RcsResourceContainer.class.getSimpleName();
49     static {
50         System.loadLibrary("gnustl_shared");
51         System.loadLibrary("oc_logger");
52         System.loadLibrary("connectivity_abstraction");
53         System.loadLibrary("ca-interface");
54         System.loadLibrary("octbstack");
55         System.loadLibrary("oc");
56         System.loadLibrary("rcs_client");
57         System.loadLibrary("rcs_server");
58         System.loadLibrary("rcs_common");
59         System.loadLibrary("rcs_container");
60         System.loadLibrary("resource_container_jni");
61     }
62     
63     private Context appContext;
64
65     private native void nativeStartContainer(String configFile);
66
67     private native void nativeStopContainer();
68
69     private native void nativeAddBundle(String bundleId, String bundleUri,
70             String bundlePath, String activator, Map<String, String> params);
71
72     private native void nativeRemoveBundle(String bundleId);
73
74     private native List<RcsBundleInfo> nativeListBundles();
75
76     private native void nativeStartBundle(String bundleId);
77
78     private native void nativeStopBundle(String bundleId);
79
80     private native void nativeAddResourceConfig(String bundleId,
81             String resourceUri, Map<String, String> params);
82
83     private native void nativeRemoveResourceConfig(String bundleId,
84             String resourceUri);
85
86     private native List<String> nativeListBundleResources(String bundleId);
87     
88     private native void nativeRegisterBundleResource(BundleResource resource,
89         String[] attributes, String bundleId, String uri,
90         String resourceType, String name);
91     
92     private native void nativeUnregisterBundleResource(BundleResource resource,
93         String uri);
94     
95     private native int nativeGetNumberOfConfiguredResources(String bundleId);
96         
97     private native String[] nativeGetConfiguredResourceParams(String bundleId,
98         int resId);  
99     
100     public RcsResourceContainer(Context appContext){
101         this.appContext = appContext;
102     }
103     
104     private Hashtable<String, BundleActivator> activators = new Hashtable<String, BundleActivator>();
105
106     /**
107      * API for starting the Container
108      *
109      * <p>
110      * This API start the container with the provided Configuration file.
111      *
112      * @param configFile
113      *            configuration File that contains the Bundle/Bundles
114      *            information.
115      *
116      */
117     public void startContainer(String configFile) {        
118         nativeStartContainer(configFile);
119         Log.d(TAG, "startContainer");
120         List<RcsBundleInfo> bundles = listBundles();
121         for(RcsBundleInfo bundleInfo : bundles){
122             Log.d(TAG, "bundle-id: " + bundleInfo.getID() + ", " + bundleInfo.getPath());
123             if(bundleInfo.getPath().endsWith(".apk")){
124                 String packageName = bundleInfo.getPath().replace(".apk", "");
125                 try{
126                     PackageManager packageManager = appContext.getPackageManager();
127                     ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
128                     DexFile df = new DexFile(appInfo.sourceDir);
129                     ClassLoader cl = appContext.getClassLoader();
130                     for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
131                         String classN = iter.nextElement();
132                         if (classN.contains(packageName)) {
133                             Log.d(TAG,"Class: " + classN);
134                             df.loadClass(classN, cl);
135                         }
136                     }
137                     
138                     String className = bundleInfo.getActivatorName();
139                     Log.d(TAG, "Loading activator: " + className);
140                     Class activatorClass = df.loadClass(className, cl);
141                     if(activatorClass!= null){
142                         BundleActivator activator = (BundleActivator) activatorClass.
143                                 getConstructor(RcsResourceContainerBundleAPI.class, Context.class).
144                                 newInstance(this, appContext);
145                         activator.activateBundle();
146                         activators.put(bundleInfo.getID(), activator);
147                     }else{
148                         Log.e(TAG, "Activator is null.");
149                     }
150                 }
151                 catch(Exception e){
152                     Log.e(TAG, e.getMessage(), e);
153                 }
154                 Log.d(TAG, "Have to register android bundle");
155             }
156         }
157     }
158
159     /**
160      * API for stopping the Container
161      */
162     public void stopContainer() {
163         // stop all android bundles
164         for(BundleActivator activator :activators.values()){
165             activator.deactivateBundle();
166         }
167         nativeStopContainer();
168     }
169
170     /**
171      * API for getting the list of all bundles in the container
172      *
173      * @return list<RCSBundleInfo> -List of BundleInfo objects each associated
174      *         with a bundle
175      *
176      *         {@link RcsBundleInfo}
177      */
178     public List<RcsBundleInfo> listBundles() {
179         return nativeListBundles();
180     }
181
182     /**
183      * API for adding the bundle to the Container
184      *
185      * @param bundleId
186      *            Id of the Bundle
187      * @param bundleUri
188      *            Uri of the bundle
189      * @param bundlePath
190      *            Path of the bundle
191      * @param activator
192      *            Activation prefix for .so bundles, or activator class name for
193      *            .jar bundles
194      * @param params
195      *            key-value pairs in string form for other Bundle parameters
196      *
197      *            <p>
198      *            It is dynamic configuration
199      */
200     public void addBundle(String bundleId, String bundleUri, String bundlePath,
201             String activator, Map<String, String> params) {
202         nativeAddBundle(bundleId, bundleUri, bundlePath, activator, params);
203     }
204
205     /**
206      * API for removing the bundle from the container
207      *
208      * @param bundleId
209      *            Id of the Bundle
210      *
211      */
212     public void removeBundle(String bundleId) {
213         if(activators.contains(bundleId)){
214             // deactivate android bundle
215             activators.get(bundleId).deactivateBundle();
216         }
217         nativeRemoveBundle(bundleId);
218     }
219
220     /**
221      * API for starting the bundle.
222      *
223      * @param bundleId
224      *            Id of the Bundle
225      *
226      */
227     public void startBundle(String bundleId) {
228         Log.d(TAG, "startBundle");
229         List<RcsBundleInfo> bundles = listBundles();
230        
231         for(RcsBundleInfo bundleInfo : bundles){          
232             if(bundleInfo.getID().equals(bundleId) && bundleInfo.getLibraryPath().endsWith(".apk")){
233                 Log.d(TAG, "Have to start android bundle");
234                 Log.d(TAG, "bundle-id: " + bundleInfo.getID() + ", " + bundleInfo.getPath());
235                 if(bundleInfo.getPath().endsWith(".apk")){
236                     String packageName = bundleInfo.getPath().replace(".apk", "");
237                     try{
238                         PackageManager packageManager = appContext.getPackageManager();
239                         ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
240                         DexFile df = new DexFile(appInfo.sourceDir);
241                         ClassLoader cl = appContext.getClassLoader();
242                         for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
243                             String classN = iter.nextElement();
244                             if (classN.contains(packageName)) {
245                                 Log.d(TAG,"Class: " + classN);
246                                 df.loadClass(classN, cl);
247                             }
248                         }
249                         
250                         String className = bundleInfo.getActivatorName();
251                         Log.d(TAG, "Loading activator: " + className);
252                         Class activatorClass = df.loadClass(className, cl);
253                         if(activatorClass!= null){
254                             BundleActivator activator = (BundleActivator) activatorClass.
255                                     getConstructor(RcsResourceContainerBundleAPI.class, 
256                                             Context.class).
257                                     newInstance(this, appContext);
258                             activator.activateBundle();
259                         }else{
260                             Log.e(TAG, "Activator is null.");
261                         }
262                     }
263                     catch(Exception e){
264                         Log.e(TAG, e.getMessage(), e);
265                     }
266                     Log.d(TAG, "Have to register android bundle");
267                 }
268             }else{
269                 nativeStartBundle(bundleId);
270             }
271         }
272       
273     }
274
275     /**
276      * API for Stopping the bundle
277      *
278      * @param bundleId
279      *            Id of the Bundle
280      *
281      */
282     public void stopBundle(String bundleId) {
283         nativeStopBundle(bundleId);
284     }
285
286     /**
287      * API for adding the Resource configuration information to the bundle
288      *
289      * @param bundleId
290      *            Id of the Bundle
291      * @param resourceUri
292      *            URI of the resource
293      * @param params
294      *            key-value pairs in string form for other Bundle parameters
295      *
296      */
297     public void addResourceConfig(String bundleId, String resourceUri,
298             Map<String, String> params) {
299         nativeAddResourceConfig(bundleId, resourceUri, params);
300     }
301
302     /**
303      * API for removing the Resource configuration information from the bundle
304      *
305      * @param bundleId
306      *            Id of the Bundle
307      * @param resourceUri
308      *            URI of the resource
309      *
310      */
311     public void removeResourceConfig(String bundleId, String resourceUri) {
312         nativeRemoveResourceConfig(bundleId, resourceUri);
313     }
314
315     /**
316      * API for getting the list of Bundle Resources
317      *
318      * @param bundleId
319      *            Id of the Bundle
320      *
321      * @return List<String> All the bundle resources
322      */
323     public List<String> listBundleResources(String bundleId) {
324         return nativeListBundleResources(bundleId);
325     }
326
327     public void registerResource(String bundleId, BundleResource resource){
328         Log.d(TAG, "register Resource");
329         // bundleResources.add(resource);
330         nativeRegisterBundleResource(resource, resource.getAttributeKeys(), bundleId,
331                         resource.getURI(), resource.getResourceType(),
332                         resource.getName());
333     }
334     
335     public List<ResourceConfig> getConfiguredBundleResources(String bundleId) {
336         Log.d(TAG, "getConfiguredBundleResource " + bundleId);
337         int configuredResources = getNumberOfConfiguredResources(bundleId);
338         Log.d(TAG, "configured resources " + configuredResources);
339
340         Vector<ResourceConfig> configs = new Vector<ResourceConfig>();
341
342         for (int i = 0; i < configuredResources; i++) {
343                 String[] resourceParams = getConfiguredResourceParams(bundleId, i);
344                 ResourceConfig config = new ResourceConfig(resourceParams);
345                 configs.add(config);
346
347         }
348         return configs;
349     }
350
351     
352     public void unregisterResource(BundleResource resource){
353         Log.d(TAG, "unregister Resource");
354         nativeUnregisterBundleResource(resource, resource.getURI());
355     }
356
357     public int getNumberOfConfiguredResources(String bundleId){
358         Log.d(TAG, "getNumberOfConfiguredResources");
359         return nativeGetNumberOfConfiguredResources(bundleId);
360     }
361
362     public String[] getConfiguredResourceParams(String bundleId, int resId){
363         Log.d(TAG, "getConfiguredResourceParams");
364         return nativeGetConfiguredResourceParams(bundleId, resId);
365     }
366 }