Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / service / protocol-plugin / plugin-manager / src / Android / src / org / iotivity / service / ppm / FelixManager.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 /// @file FelixManager.java
22
23 package org.iotivity.service.ppm;
24
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31 import java.util.ArrayList;
32 import java.util.Dictionary;
33 import java.util.HashMap;
34 import java.util.Map;
35
36 import org.apache.felix.framework.Felix;
37 import org.osgi.framework.BundleContext;
38 import org.osgi.framework.BundleException;
39 import org.osgi.framework.Constants;
40
41 import android.content.Context;
42 import android.content.res.AssetManager;
43 import android.os.FileObserver;
44 import android.util.Log;
45
46 public class FelixManager {
47     private static Felix                   m_felix                    = null;
48     private static ArrayList<FileObserver> m_observer;
49     private static FelixManager            m_felixmgr;
50     private static Context                 m_context;
51     private static final int               TRUE                       = 1;
52     private static final int               FALSE                      = 0;
53
54     static final String                    ANDROID_FRAMEWORK_PACKAGES = ("android,"
55                                                                   + "android.app,"
56                                                                   + "android.content,"
57                                                                   + "android.content.pm,"
58                                                                   + "android.content.res,"
59                                                                   + "android.database,"
60                                                                   + "android.database.sqlite,"
61                                                                   + "android.graphics,"
62                                                                   + "android.graphics.drawable,"
63                                                                   + "android.graphics.glutils,"
64                                                                   + "android.hardware,"
65                                                                   + "android.location,"
66                                                                   + "android.media,"
67                                                                   + "android.net,"
68                                                                   + "android.net.wifi,"
69                                                                   + "android.net.http,"
70                                                                   + "android.opengl,"
71                                                                   + "android.os,"
72                                                                   + "android.provider,"
73                                                                   + "android.sax,"
74                                                                   + "android.speech.recognition,"
75                                                                   + "android.telephony,"
76                                                                   + "android.telephony.gsm,"
77                                                                   + "android.text,"
78                                                                   + "android.text.format,"
79                                                                   + "android.text.method,"
80                                                                   + "android.text.style,"
81                                                                   + "android.text.util,"
82                                                                   + "android.util,"
83                                                                   + "android.view,"
84                                                                   + "android.view.animation,"
85                                                                   + "android.webkit,"
86                                                                   + "android.widget,"
87                                                                   + "javax.xml.parsers,"
88                                                                   + "org.xml.sax,"
89                                                                   + "org.w3c.dom,"
90                                                                   + "com.example.felixmanager,"
91                                                                   + "org.iotivity.base");
92
93     // FelixManager singleton
94     public static FelixManager getInstance(Context ctx) {
95         if (m_felixmgr == null) {
96             m_felixmgr = new FelixManager(ctx);
97             copyFiles("files");
98         }
99
100         return m_felixmgr;
101     }
102
103     public static void LogEx(String info) {
104         Log.d("felix", info);
105     }
106
107     private FelixManager(Context ctx) {
108         m_context = ctx;
109         m_observer = new ArrayList<FileObserver>();
110
111         Map configMap = new HashMap();
112         String mCacheDir = ctx.getDir("org.osgi.framework.storage",
113                 Context.MODE_WORLD_WRITEABLE).toString();
114         configMap.put("org.osgi.framework.storage", mCacheDir);
115         configMap.put("felix.embedded.execution", "true");
116         configMap.put("org.osgi.service.http.port", "9990");
117         configMap.put("org.osgi.framework.startlevel.beginning", "5");
118         configMap.put("felix.bootdelegation.implicit", "false");
119         configMap.put("felix.service.urlhandlers", "false");
120         configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA,
121                 ANDROID_FRAMEWORK_PACKAGES);
122         try {
123             m_felix = new Felix(configMap);
124             m_felix.init();
125             m_felix.start();
126
127             for (org.osgi.framework.Bundle b : m_felix.getBundleContext()
128                     .getBundles()) {
129                 LogEx("Bundle: " + b.getSymbolicName());
130             }
131         } catch (Throwable ex) {
132             Log.d("Felix", "could not create framework: " + ex.getMessage(), ex);
133         }
134     }
135
136     public static int registerPlugin(String path) {
137
138         int flag = FALSE;
139
140         flag = installPlugin(path);
141         if (flag == TRUE)
142             flag = loadPluginInfoToManager(path);
143
144         return flag;
145     }
146
147     public static int registerAllPlugin(String path) {
148
149         int flag = FALSE;
150
151         flag = findPluginRecursive(path);
152         if (flag == TRUE)
153             flag = loadPluginInfoToManager(path);
154
155         return flag;
156     }
157
158     public static int unregisterPlugin(String id) {
159         int flag = TRUE;
160         try {
161             BundleContext bContext = m_felix.getBundleContext();
162             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
163             for (org.osgi.framework.Bundle b : bundles) {
164                 if (b.getSymbolicName().equals(id)) {
165                     Log.d("Felix", "bundle: " + b.getBundleId()
166                             + "   symbolicName : " + b.getSymbolicName());
167                     b.uninstall();
168                     Log.d("Felix", "uninstall end");
169                 }
170             }
171         } catch (BundleException e) {
172             e.printStackTrace();
173             flag = FALSE;
174         }
175
176         return flag;
177     }
178
179     public static int unregisterAllPlugin() {
180         int flag = TRUE;
181         try {
182             BundleContext bContext = m_felix.getBundleContext();
183             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
184             for (org.osgi.framework.Bundle b : bundles) {
185                 if (!b.getSymbolicName().equals("org.apache.felix.framework")) {
186                     Log.d("Felix", "bundle: " + b.getBundleId()
187                             + "   symbolicName : " + b.getSymbolicName());
188                     b.uninstall();
189                     Log.d("Felix", "uninstall end");
190                 }
191             }
192         } catch (BundleException e) {
193             e.printStackTrace();
194             flag = FALSE;
195         }
196
197         return flag;
198     }
199
200     public static org.osgi.framework.Bundle[] getAllPlugins() {
201         try {
202             BundleContext bContext = m_felix.getBundleContext();
203             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
204             return bundles;
205         } catch (Exception e) {
206             e.printStackTrace();
207         }
208
209         return null;
210     }
211
212     public static org.osgi.framework.Bundle[] findPulgins(String key,
213             String value) {
214         BundleContext bContext = m_felix.getBundleContext();
215         org.osgi.framework.Bundle[] bundles = bContext.getBundles();
216
217         return bundles;
218     }
219
220     public static org.osgi.framework.Bundle getPlugin(int ID) {
221         BundleContext bContext = m_felix.getBundleContext();
222         org.osgi.framework.Bundle[] bundles = bContext.getBundles();
223         for (int i = 0; i < bundles.length; i++) {
224             if (bundles[i].getBundleId() == ID) {
225                 return bundles[i];
226             }
227         }
228         return null;
229     }
230
231     public static int start(String id) {
232         int flag = TRUE;
233         Log.d("Felix", "String id : " + id);
234         try {
235             BundleContext bContext = m_felix.getBundleContext();
236             bContext.registerService(Context.class.getName(), m_context, null);
237
238             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
239             for (org.osgi.framework.Bundle b : bundles) {
240                 Log.d("Felix", "symbolicName : " + b.getSymbolicName());
241                 if (b.getSymbolicName().equals(id)) {
242                     Log.d("Felix", "bundle: " + b.getBundleId()
243                             + "   symbolicName : " + b.getSymbolicName());
244                     b.start();
245                     Log.d("Felix", "start end");
246                 }
247             }
248         } catch (BundleException e) {
249             e.printStackTrace();
250             flag = FALSE;
251         }
252         return flag;
253     }
254
255     public static int stop(String id) {
256         int flag = TRUE;
257         try {
258             BundleContext bContext = m_felix.getBundleContext();
259             org.osgi.framework.Bundle[] bundles = bContext.getBundles();
260             for (org.osgi.framework.Bundle b : bundles) {
261                 if (b.getSymbolicName().equals(id)) {
262                     Log.d("Felix", "bundle: " + b.getBundleId()
263                             + "   symbolicName : " + b.getSymbolicName());
264                     b.stop();
265                     b.uninstall();
266                     Log.d("Felix", "stop end");
267                 }
268             }
269         } catch (BundleException e) {
270             e.printStackTrace();
271             flag = FALSE;
272         }
273         return flag;
274     }
275
276     public static boolean isStarted(String name) {
277         String state = getState(name);
278         if (state.equals("ACTIVE") || state.equals("STARTING"))
279             return true;
280         return false;
281     }
282
283     public static String getValue(String name, String key) {
284         Log.d("FELIX", "getValue");
285         BundleContext bContext = m_felix.getBundleContext();
286         org.osgi.framework.Bundle[] bundles = bContext.getBundles();
287         for (org.osgi.framework.Bundle b : bundles) {
288             Dictionary<String, String> dic = b.getHeaders();
289             String bundlename = b.getSymbolicName();
290             Log.d("FELIX", "Bundlename: " + bundlename);
291
292             if (bundlename.equals(name)) {
293                 if (dic.get("Bundle-" + key) == null) {
294                     Log.d("FELIX", name + " null");
295                     return "";
296                 }
297                 Log.d("FELIX", name + " " + dic.get("Bundle-" + key));
298                 return dic.get("Bundle-" + key);
299             }
300         }
301         return "";
302     }
303
304     public static String getState(String name) {
305         Log.d("FELIX", "getState");
306         BundleContext bContext = m_felix.getBundleContext();
307         org.osgi.framework.Bundle[] bundles = bContext.getBundles();
308         for (org.osgi.framework.Bundle b : bundles) {
309             Dictionary<String, String> dic = b.getHeaders();
310             String bundlename = b.getSymbolicName();
311
312             if (bundlename.equals(name)) {
313                 Log.d("FELIX", state_to_string(b.getState()));
314                 return state_to_string(b.getState());
315             }
316         }
317         Log.d("FELIX", "null");
318         return "";
319     }
320
321     public static String printPluginList() {
322         String str = "";
323         str += "id   |     state     |    symbolname | ";
324         BundleContext bContext = m_felix.getBundleContext();
325         org.osgi.framework.Bundle[] bundles = bContext.getBundles();
326         for (org.osgi.framework.Bundle b : bundles) {
327             str += "\n" + b.getBundleId() + "  "
328                     + state_to_string(b.getState()) + " " + b.getSymbolicName();
329         }
330         return str;
331     }
332
333     public static void stop_felix() {
334         try {
335             m_felix.stop();
336             m_felix.waitForStop(0);
337         } catch (Exception e) {
338             e.printStackTrace();
339         }
340     }
341
342     public static ArrayList<String> getFileList(String path, boolean recursive) {
343         File file = new File(path);
344         File[] files = file.listFiles();
345         ArrayList<String> array = new ArrayList<String>();
346         for (int i = 0; i < files.length; i++) {
347             if (files[i].isDirectory()) {
348                 if (recursive == true) {
349                     ArrayList<String> directory_list = getFileList(files[i]
350                             + "/", true);
351                     array.addAll(directory_list);
352                 }
353                 Log.v("Directory : ", files[i].getName());
354             } else {
355                 if (files[i].getName().endsWith("jar")) {
356                     Log.v("File :", files[i].getName());
357                     if (path.charAt(path.length() - 1) != '/') {
358                         path += "/";
359                     }
360                     array.add(path + files[i].getName());
361                 }
362             }
363         }
364         return array;
365     }
366
367     private static String state_to_string(int state) {
368         String str = state + " [unknown state]";
369
370         if (state == org.osgi.framework.Bundle.ACTIVE) {
371             return "ACTIVE";
372         } else if (state == org.osgi.framework.Bundle.INSTALLED) {
373             return "INSTALLED";
374         } else if (state == org.osgi.framework.Bundle.RESOLVED) {
375             return "RESOLVED";
376         } else if (state == org.osgi.framework.Bundle.STARTING) {
377             return "STARTING";
378         } else if (state == org.osgi.framework.Bundle.STOPPING) {
379             return "STOPPING";
380         } else if (state == org.osgi.framework.Bundle.UNINSTALLED) {
381             return "UNINSTALLED";
382         }
383         return str;
384     }
385
386     public static int installPlugin(String path) {
387
388         int flag = TRUE;
389         if (path == "") {
390             System.out.println("PluginManager path is Null\n");
391         }
392
393         ArrayList<String> filearray;
394         BundleContext bContext = m_felix.getBundleContext();
395         String location = "";
396         FileInputStream fin;
397         if (path.charAt(0) != '/') {
398             path = "/" + path;
399         } else if (path.charAt(path.length() - 1) != '/') {
400             path = path + "/";
401         }
402
403         filearray = getFileList(path, false);
404
405         for (int i = 0; i < filearray.size(); i++) {
406             try {
407                 location = "file:" + filearray.get(i);
408                 fin = new FileInputStream(new File(filearray.get(i)));
409                 bContext.installBundle(location, fin);
410             } catch (BundleException e) {
411                 e.printStackTrace();
412                 flag = FALSE;
413             } catch (FileNotFoundException e) {
414                 e.printStackTrace();
415                 flag = FALSE;
416             }
417         }
418
419         return flag;
420     }
421
422     private static String getEventString(int event) {
423         switch (event) {
424             case FileObserver.ACCESS:
425                 return "ACCESS";
426             case FileObserver.MODIFY:
427                 return "MODIFY";
428             case FileObserver.ATTRIB:
429                 return "ATTRIB";
430             case FileObserver.CLOSE_WRITE:
431                 return "CLOSE_WRITE";
432             case FileObserver.CLOSE_NOWRITE:
433                 return "CLOSE_NOWRITE";
434             case FileObserver.OPEN:
435                 return "OPEN";
436             case FileObserver.MOVED_FROM:
437                 return "MOVED_FROM";
438             case FileObserver.MOVED_TO:
439                 return "MOVED_TO";
440             case FileObserver.CREATE:
441                 return "CREATE";
442             case FileObserver.DELETE:
443                 return "DELETE";
444             case FileObserver.DELETE_SELF:
445                 return "DELETE_SELF";
446             case FileObserver.MOVE_SELF:
447                 return "MOVE_SELF";
448             default:
449                 return "UNKNOWN";
450         }
451     }
452
453     public static int ObservePluginPath(String path) {
454         int flag = TRUE;
455         Log.d("FELIX", "ObservePluginPath" + path);
456
457         FileObserver observer = new FileObserver(path) {
458             @Override
459             public void onEvent(int event, String path) {
460                 Log.d("FELIX", "Observing start : " + path);
461                 Log.d("FELIX", "Observing event : " + getEventString(event));
462             }
463         };
464         observer.startWatching();
465         m_observer.add(observer);
466
467         return flag;
468     }
469
470     public static int findPluginRecursive(String path) {
471         int flag = TRUE;
472         if (path == "") {
473             System.out.println("PluginManager path is Null\n");
474             Log.d("FELIX", "PluginManager path is Null\n");
475             flag = FALSE;
476             return flag;
477         }
478
479         ArrayList<String> filearray;
480         BundleContext bContext = m_felix.getBundleContext();
481         String location = "";
482         FileInputStream fin;
483
484         if (path.charAt(0) != '/') {
485             path = "/" + path;
486         } else if (path.charAt(path.length() - 1) != '/') {
487             path = path + "/";
488         }
489
490         filearray = getFileList(path, true);
491
492         for (int i = 0; i < filearray.size(); i++) {
493             try {
494                 location = "file:" + filearray.get(i);
495                 fin = new FileInputStream(new File(filearray.get(i)));
496                 bContext.installBundle(location, fin);
497             } catch (BundleException e) {
498                 e.printStackTrace();
499                 flag = FALSE;
500             } catch (FileNotFoundException e) {
501                 e.printStackTrace();
502                 flag = FALSE;
503             }
504         }
505
506         return flag;
507     }
508
509     public static int loadPluginInfoToManager(String path) {
510         int flag = FALSE;
511
512         flag = ObservePluginPath(path);
513         FelixManager.printPluginList();
514
515         return flag;
516     }
517
518     public static String getPackageName() {
519         String packagename;
520
521         packagename = m_context.getPackageName();
522
523         return packagename;
524     }
525
526     private static void copyFiles(String path) {
527         AssetManager assetManager = m_context.getAssets();
528         String assets[] = null;
529
530         try {
531             assets = assetManager.list(path);
532
533             if (assets.length == 0) {
534                 copyFile(path);
535             } else {
536                 String fullPath = "/data/data/"
537                         + m_context.getPackageName() + "/" + path;
538                 Log.d("FELIX", fullPath);
539                 File dir = new File(fullPath);
540
541                 if (!dir.exists())
542                     dir.mkdir();
543                 for (int i = 0; i < assets.length; ++i) {
544                     copyFiles(path + "/" + assets[i]);
545                 }
546             }
547         } catch (IOException ex) {
548             Log.e("tag", "I/O Exception", ex);
549         }
550     }
551
552     private static void copyFile(String filename) {
553         AssetManager assetManager = m_context.getAssets();
554         InputStream in = null;
555         OutputStream out = null;
556
557         try {
558             in = assetManager.open(filename);
559             out = m_context.openFileOutput(filename.split("/")[1], Context.MODE_PRIVATE);
560
561             byte[] buffer = new byte[1024];
562             
563             int read;
564
565             while ((read = in.read(buffer)) != -1) {
566                 out.write(buffer, 0, read);
567             }
568
569             in.close();
570             in = null;
571             out.flush();
572             out.close();
573             out = null;
574         } catch (Exception e) {
575             Log.e("tag", e.getMessage());
576         }
577     }
578 }