1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 * This file contains the Resource Container APIs
26 package org.iotivity.service.resourcecontainer;
28 import java.util.List;
31 import java.util.Enumeration;
32 import android.util.Log;
33 import android.content.Context;
34 import java.util.Vector;
36 import dalvik.system.DexFile;
37 import android.content.pm.ApplicationInfo;
38 import android.content.pm.PackageManager;
39 import dalvik.system.PathClassLoader;
40 import java.net.URLClassLoader;
42 import java.util.Hashtable;
46 import java.lang.reflect.InvocationTargetException;
49 * This class provides APIs for managing the container and bundles in the
52 public class RcsResourceContainer implements RcsResourceContainerBundleAPI {
54 private static final String TAG = RcsResourceContainer.class.getSimpleName();
57 System.loadLibrary("gnustl_shared");
58 System.loadLibrary("oc_logger");
59 System.loadLibrary("connectivity_abstraction");
60 System.loadLibrary("ca-interface");
61 System.loadLibrary("octbstack");
62 System.loadLibrary("oc");
63 System.loadLibrary("rcs_client");
64 System.loadLibrary("rcs_server");
65 System.loadLibrary("rcs_common");
66 System.loadLibrary("rcs_container");
67 System.loadLibrary("resource_container_jni");
70 private Context appContext;
72 private native void nativeStartContainer(String configFile);
74 private native void nativeStopContainer();
76 private native void nativeAddBundle(String bundleId, String bundleUri,
77 String bundlePath, String activator, Map<String, String> params);
79 private native void nativeRemoveBundle(String bundleId);
81 private native List<RcsBundleInfo> nativeListBundles();
83 private native void nativeStartBundle(String bundleId);
85 private native void nativeStopBundle(String bundleId);
87 private native void nativeAddResourceConfig(String bundleId,
88 String resourceUri, Map<String, String> params);
90 private native void nativeRemoveResourceConfig(String bundleId,
93 private native List<String> nativeListBundleResources(String bundleId);
95 private native void nativeRegisterBundleResource(BundleResource resource,
96 String[] attributes, String bundleId, String uri,
97 String resourceType, String name);
99 private native void nativeUnregisterBundleResource(BundleResource resource,
102 private native int nativeGetNumberOfConfiguredResources(String bundleId);
104 private native String[] nativeGetConfiguredResourceParams(String bundleId,
107 public RcsResourceContainer(Context appContext){
108 this.appContext = appContext;
111 private Hashtable<String, BundleActivator> activators = new Hashtable<String, BundleActivator>();
114 * API for starting the Container
117 * This API start the container with the provided Configuration file.
120 * configuration File that contains the Bundle/Bundles
124 public List<RcsBundleInfo> startContainer(String configFile) {
125 if(configFile == null || configFile.isEmpty()){
126 throw new IllegalArgumentException(
127 "Configuration file is null or empty.");
129 nativeStartContainer(configFile);
130 Log.d(TAG, "startContainer in Java");
131 List<RcsBundleInfo> bundles = listBundles();
132 Log.d(TAG, "startContainer. There are " + bundles.size() + " bundles.");
133 for(RcsBundleInfo bundleInfo : bundles){
134 Log.d(TAG, "bundle-id: " + bundleInfo.getID() + ", " + bundleInfo.getPath());
135 if(bundleInfo.getPath().endsWith(".apk")){ // load classes from standalone application
136 startBundleFromStandaloneApp(bundleInfo);
137 }else if(bundleInfo.getPath().endsWith(".jar")){ // load classes from library
138 startBundleFromJar(bundleInfo);
144 private void startBundleFromStandaloneApp(RcsBundleInfo bundleInfo){
145 if(bundleInfo == null){
146 throw new IllegalArgumentException(
147 "bundleInfo parameter is null or empty.");
149 String packageName = bundleInfo.getPath().replace(".apk", "");
151 PackageManager packageManager = appContext.getPackageManager();
152 ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
153 DexFile df = new DexFile(appInfo.sourceDir);
154 ClassLoader cl = appContext.getClassLoader();
155 for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
156 String classN = iter.nextElement();
157 if (classN.contains(packageName)) {
158 Log.d(TAG,"Class: " + classN);
159 df.loadClass(classN, cl);
162 String className = bundleInfo.getActivatorName();
163 Log.d(TAG, "Loading activator: " + className);
164 Class activatorClass = df.loadClass(className, cl);
165 activateBundle(activatorClass, bundleInfo);
168 Log.e(TAG, e.getMessage(), e);
170 Log.d(TAG, "Have to register android bundle");
173 private void startBundleFromJar(RcsBundleInfo bundleInfo){
174 if(bundleInfo == null){
175 throw new IllegalArgumentException(
176 "bundleInfo parameter is null");
179 Log.e(TAG, "Loading from .jar file.");
181 PathClassLoader classLoader = new PathClassLoader(bundleInfo.getPath(),
182 RcsResourceContainer.class.getClassLoader());
184 String className = bundleInfo.getActivatorName().replace('/', '.');
185 Log.d(TAG, "Loading activator: " + className);
186 Class activatorClass = Class.forName(className, true, classLoader);
188 activateBundle(activatorClass, bundleInfo);
191 Log.e(TAG, e.getMessage(), e);
193 Log.d(TAG, "Have to register android bundle");
196 private void activateBundle(Class activatorClass, RcsBundleInfo bundleInfo) throws
197 NoSuchMethodException, InstantiationException, IllegalAccessException,
198 InvocationTargetException{
199 if(activatorClass == null){
200 throw new IllegalArgumentException(
201 "activatorClass is null.");
203 if(bundleInfo == null){
204 throw new IllegalArgumentException(
205 "bundleInfo is null.");
207 if(activatorClass!= null){
208 BundleActivator activator = (BundleActivator) activatorClass.
209 getConstructor(RcsResourceContainerBundleAPI.class, Context.class).
210 newInstance(this, appContext);
211 activator.activateBundle();
212 activators.put(bundleInfo.getID(), activator);
213 bundleInfo.setActivated(true);
215 Log.e(TAG, "Activator is null.");
220 * API for stopping the Container
222 public void stopContainer() {
223 // stop all android bundles
224 for(BundleActivator activator :activators.values()){
225 activator.deactivateBundle();
227 nativeStopContainer();
231 * API for getting the list of all bundles in the container
233 * @return list<RCSBundleInfo> -List of BundleInfo objects each associated
236 * {@link RcsBundleInfo}
238 public List<RcsBundleInfo> listBundles() {
239 return nativeListBundles();
243 * API for adding the bundle to the Container
252 * Activation prefix for .so bundles, or activator class name for
255 * key-value pairs in string form for other Bundle parameters
258 * It is dynamic configuration
260 public void addBundle(String bundleId, String bundleUri, String bundlePath,
261 String activator, Map<String, String> params) {
262 if(bundleId == null){
263 throw new IllegalArgumentException(
264 "bundleId parameter is null.");
266 if(bundleUri == null){
267 throw new IllegalArgumentException(
268 "bundleUri is null.");
270 if(bundlePath == null){
271 throw new IllegalArgumentException(
272 "bundlePath is null.");
274 if(activator == null){
275 throw new IllegalArgumentException(
276 "activator is null.");
278 nativeAddBundle(bundleId, bundleUri, bundlePath, activator, params);
282 * API for removing the bundle from the container
288 public void removeBundle(String bundleId) {
289 if(bundleId == null || bundleId.isEmpty()){
290 throw new IllegalArgumentException(
291 "bundleId parameter is null or empty.");
293 if(activators.contains(bundleId)){
294 // deactivate android bundle
295 activators.get(bundleId).deactivateBundle();
297 nativeRemoveBundle(bundleId);
301 * API for starting the bundle.
307 public void startBundle(String bundleId) {
308 Log.d(TAG, "startBundle");
309 if(bundleId == null || bundleId.isEmpty()){
310 throw new IllegalArgumentException(
311 "bundleId parameter is null or empty.");
313 List<RcsBundleInfo> bundles = listBundles();
315 for(RcsBundleInfo bundleInfo : bundles){
316 if(bundleInfo.getID().equals(bundleId) && bundleInfo.getPath().endsWith(".apk")){
317 Log.d(TAG, "Have to start android bundle");
318 Log.d(TAG, "bundle-id: " + bundleInfo.getID() + ", " + bundleInfo.getPath());
319 if(bundleInfo.getPath().endsWith(".apk")){
320 startBundleFromStandaloneApp(bundleInfo);
321 }else if(bundleInfo.getID().equals(bundleId) &&
322 bundleInfo.getPath().endsWith(".jar")){ // load classes from library
323 startBundleFromJar(bundleInfo);
326 nativeStartBundle(bundleId);
332 * API for Stopping the bundle
338 public void stopBundle(String bundleId){
339 if(bundleId == null || bundleId.isEmpty()){
340 throw new IllegalArgumentException(
341 "bundleId parameter is null or empty.");
343 nativeStopBundle(bundleId);
347 * API for adding the Resource configuration information to the bundle
352 * URI of the resource
354 * key-value pairs in string form for other Bundle parameters
357 public void addResourceConfig(String bundleId, String resourceUri,
358 Map<String, String> params) {
359 if(bundleId == null || bundleId.isEmpty()){
360 throw new IllegalArgumentException(
361 "bundleId parameter is null or empty.");
363 if(resourceUri == null || resourceUri.isEmpty()){
364 throw new IllegalArgumentException(
365 "resourceUri parameter is null or empty.");
367 nativeAddResourceConfig(bundleId, resourceUri, params);
371 * API for removing the Resource configuration information from the bundle
376 * URI of the resource
379 public void removeResourceConfig(String bundleId, String resourceUri) {
380 if(bundleId == null || bundleId.isEmpty()){
381 throw new IllegalArgumentException(
382 "bundleId parameter is null or empty.");
384 if(resourceUri == null || resourceUri.isEmpty()){
385 throw new IllegalArgumentException(
386 "resourceUri parameter is null or empty.");
388 nativeRemoveResourceConfig(bundleId, resourceUri);
392 * API for getting the list of Bundle Resources
397 * @return List<String> All the bundle resources
399 public List<String> listBundleResources(String bundleId) {
400 if(bundleId == null || bundleId.isEmpty()){
401 throw new IllegalArgumentException(
402 "bundleId parameter is null or empty.");
404 return nativeListBundleResources(bundleId);
408 * Registers a bundle resource
413 * resource to be registered
415 public void registerResource(String bundleId, BundleResource resource){
416 Log.d(TAG, "register Resource");
417 // bundleResources.add(resource);
419 if(bundleId == null || bundleId.isEmpty()){
420 throw new IllegalArgumentException(
421 "bundleId parameter is null or empty.");
423 if(resource == null){
424 throw new IllegalArgumentException(
425 "resource parameter is null.");
427 nativeRegisterBundleResource(resource, resource.getAttributeKeys(), bundleId,
428 resource.getURI(), resource.getResourceType(),
433 * Returns the bundle configuration for the resources
438 * @return List<ResourceConfig> All the resource configurations for the given bundle
440 public List<ResourceConfig> getConfiguredBundleResources(String bundleId) {
441 Log.d(TAG, "getConfiguredBundleResource " + bundleId);
442 Vector<ResourceConfig> configs = new Vector<ResourceConfig>();
443 if(bundleId == null || bundleId.isEmpty()){
444 throw new IllegalArgumentException(
445 "bundleId parameter is null or empty.");
447 int configuredResources = getNumberOfConfiguredResources(bundleId);
448 Log.d(TAG, "configured resources " + configuredResources);
450 for (int i = 0; i < configuredResources; i++) {
451 String[] resourceParams = getConfiguredResourceParams(bundleId, i);
452 ResourceConfig config = new ResourceConfig(resourceParams);
459 * Unregisters a bundle resource
462 * Resource to be unregistered
464 public void unregisterResource(BundleResource resource){
465 Log.d(TAG, "unregister Resource");
466 if(resource == null){
467 throw new IllegalArgumentException(
468 "resource is null.");
470 nativeUnregisterBundleResource(resource, resource.getURI());
474 * Returns the number of configured resources
478 * @return number of configured resources
480 public int getNumberOfConfiguredResources(String bundleId){
481 Log.d(TAG, "getNumberOfConfiguredResources");
482 if(bundleId == null || bundleId.isEmpty()){
483 throw new IllegalArgumentException(
484 "bundleId parameter is null or empty.");
486 return nativeGetNumberOfConfiguredResources(bundleId);
490 * Provides the configured resource parameter
495 Continuous numeric identifier within the bundle
496 * @return resource paramaters such as URI, resource type, name, etc. for the resource
498 public String[] getConfiguredResourceParams(String bundleId, int resId){
499 Log.d(TAG, "getConfiguredResourceParams");
500 if(bundleId == null || bundleId.isEmpty()){
501 throw new IllegalArgumentException(
502 "bundleId parameter is null or empty.");
505 throw new IllegalArgumentException(
506 "resId paramater has to be non-negative.");
508 return nativeGetConfiguredResourceParams(bundleId, resId);