package org.bbs.apklauncher.osgi.bundlemanager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.knopflerfish.framework.Debug;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Constants;
import org.osgi.framework.launch.Framework;
import android.content.Context;
import android.util.Log;
public class FrameworkHelper {
private static final String TAG = FrameworkHelper.class.getSimpleName();
public static final String HEADER_CONTRIBUTE_ANDROID_COMPONENT = "X-contribute-android-component";
public static final String HEADER_REQUIRED_RESOURCE_BUNDLE = "X-Required-Resource-Bundle";
private static final String OSGI_BUNDLE_DIR = "osgi_bundle";
private static final String OSGI_BUNDLE_CACHE_DIR = "osgi_bundlecache";
private static final String ANDROID_PACKAGE_FOR_BOOT_DELEGATION =
// android framework package
"android.*,"
+ "javax.crypto.*,"
+ "junit.framework.*,"
+ "junit.runner.*,"
+ "org.apache.http.*,"
+ "org.json.*,"
+ "org.w3c.dom.*,"
+ "org.xml.sax.*,"
+ "org.xmlpull.*,"
// + "org.bbs.apklauncher.emb.auto_gen.*,"
// + "org.bbs.apklauncher.emb.*,"
+ "non.exist.package.*"
;
// private static final String ASSERT_PRELOAD_BUNDLE_DIR = "felix/preloadbundle";
// private static final String ASSERT_AUTO_EXTRACT_DIR = "autoExtract";
private static FrameworkHelper sInstance;
private Framework mFramework;
private String mCacheDir;
private String mBundleDir;
private FrameworkHelper(Context context) {
mCacheDir = context.getDir(OSGI_BUNDLE_CACHE_DIR,
Context.MODE_WORLD_WRITEABLE).toString();
mBundleDir = context.getDir(OSGI_BUNDLE_DIR,
Context.MODE_WORLD_WRITEABLE).toString();
;
// extractPreloadBundle(context);
// extractAssets(context);
HashMap<String, String> configMap = new HashMap<String, String>();
configMap.put(Constants.FRAMEWORK_STORAGE, mCacheDir);
configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA,
ANDROID_PACKAGES_FOR_EXPORT_EXTRA);
configMap.put(Constants.FRAMEWORK_BOOTDELEGATION, ANDROID_PACKAGE_FOR_BOOT_DELEGATION);
// configMap.put(Constants.frame, value)
// configMap.put(FelixConstants.LOG_LEVEL_PROP, 4 + "");
// mFramework = new FrameworkFactory().newFramework(configMap);
configMap.put(Debug.CLASSLOADER_PROP, "true");
configMap.put(Debug.RESOLVER_PROP, "true");
mFramework = new org.knopflerfish.framework.FrameworkFactoryImpl().newFramework(configMap);
Log.d(TAG, "init & start osgi.");
try {
mFramework.init();
BundleContext bContext = mFramework.getBundleContext();
OsgiUtil.dumpProperties(bContext);
Bundle[] bundles = bContext.getBundles();
// for re-deploy bundle.
for (Bundle b : bundles) {
if (0 != b.getBundleId()) {
b.uninstall();
}
}
mFramework.start();
} catch (BundleException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d(TAG,
"OSGi framework running, state: "
+ OsgiUtil.bundleState2Str(mFramework.getState()));
registerListener(mFramework);
Bundle[] bundles = mFramework.getBundleContext().getBundles();
for (Bundle b : bundles) {
Log.d(TAG,
"b: " + b.getBundleId() + " "
+ OsgiUtil.bundleState2Str(b.getState()));
}
// mFramework.getBundleContext().getb
}
public Framework getFramework() {
return mFramework;
}
void registerListener(Framework f) {
f.getBundleContext().addBundleListener(new BundleListener() {
@Override
public void bundleChanged(BundleEvent e) {
Log.d(TAG, "bundleChanged. event:" + e);
}
});
}
// private void extractAssets(Context context) {
// try {
// AssetManager assetsM = context.getResources().getAssets();
// String[] files = assetsM.list(ASSERT_AUTO_EXTRACT_DIR);
// for (String aFile : files) {
// String assertFile = ASSERT_AUTO_EXTRACT_DIR + "/" + aFile;
// Log.d(TAG, "prepare bundle: " + aFile);
// InputStream in = assetsM.open(assertFile);
// String bFile = "/sdcard/autoextract/" + aFile;
// File f = new File(bFile);
// f.getParentFile().mkdirs();
// OutputStream out =
// // context.openFileOutput(mBundleDir + "/" + aFile, 0);
//
// new FileOutputStream(bFile);
//
// int byteCount = 8096;
// byte[] buffer = new byte[byteCount];
// int count = 0;
// while ((count = in.read(buffer, 0, byteCount)) != -1) {
// out.write(buffer, 0, count);
// }
//
// in.close();
// out.close();
// }
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
//
// private void extractPreloadBundle(Context context) {
// try {
// AssetManager assetsM = context.getResources().getAssets();
// String[] files = assetsM.list(ASSERT_PRELOAD_BUNDLE_DIR);
// for (String aFile : files) {
// String assertFile = ASSERT_PRELOAD_BUNDLE_DIR + "/" + aFile;
// Log.d(TAG, "prepare bundle: " + aFile);
// InputStream in = assetsM.open(assertFile);
// String bFile = mBundleDir + "/" + aFile;
// if (aFile.endsWith("apk")) {
// bFile = bFile + ".jar";
// }
// OutputStream out =
// // context.openFileOutput(mBundleDir + "/" + aFile, 0);
//
// new FileOutputStream(bFile);
//
// int byteCount = 8096;
// byte[] buffer = new byte[byteCount];
// int count = 0;
// while ((count = in.read(buffer, 0, byteCount)) != -1) {
// out.write(buffer, 0, count);
// }
//
// in.close();
// out.close();
// }
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
public static FrameworkHelper getInstance(Context context) {
if (null == sInstance) {
sInstance = new FrameworkHelper(context);
}
return sInstance;
}
static String[] sExportedPackages_Android = new String[]{
// android
"android",
"android.app",
//"android.app.Application,"
"android.content",
//"android.content.Context,"
//"android.content.ContextWrapper,"
"android.content.res",
"android.content.pm",
"android.database",
"android.database.sqlite",
"android.graphics",
"android.graphics.drawable",
"android.graphics.glutils",
"android.hardware",
"android.location",
"android.media",
"android.net",
"android.opengl",
"android.os",
"android.os.bundle",
"android.provider",
"android.sax",
"android.speech.recognition",
"android.telephony",
"android.telephony.gsm",
"android.text",
"android.text.method",
"android.text.style",
"android.text.util",
"android.util",
"android.view",
"android.view.animation",
"android.webkit",
"android.widget",
// JAVAx
"javax.crypto",
"javax.crypto.interfaces",
"javax.crypto.spec",
"javax.microedition.khronos.opengles",
"javax.net",
"javax.net.ssl",
"javax.security.auth",
"javax.security.auth.callback",
"javax.security.auth.login",
"javax.security.auth.x500",
"javax.security.cert",
"javax.sound.midi",
"javax.sound.midi.spi",
"javax.sound.sampled",
"javax.sound.sampled.spi",
"javax.sql",
"javax.xml.parsers",
// JUNIT
"junit.extensions",
"junit.framework",
// APACHE
"org.apache.commons.codec",
"org.apache.commons.codec.binary",
"org.apache.commons.codec.language",
"org.apache.commons.codec.net",
"org.apache.commons.httpclient",
"org.apache.commons.httpclient.auth",
"org.apache.commons.httpclient.cookie",
"org.apache.commons.httpclient.methods",
"org.apache.commons.httpclient.methods.multipart",
"org.apache.commons.httpclient.params",
"org.apache.commons.httpclient.protocol",
"org.apache.commons.httpclient.util",
// OTHERS
"org.bluez",
"org.json",
"org.w3c.dom",
"org.xml.sax",
"org.xml.sax.ext",
"org.xml.sax.helpers",
"org.xmlpull.v1",
"org.xmlpull.v1.sax2"
};
static String[] sExportedPackages_Android_v4 = new String[]{
"android.support.annotation",
"android.support.v4.accessibilityserivce",
"android.support.v4.app",
"android.support.v4.content",
"android.support.v4.database",
"android.support.v4.graphics",
"android.support.v4.hardware.display",
"android.support.v4.internal.view",
"android.support.v4.media",
"android.support.v4.net",
"android.support.v4.os",
"android.support.v4.print",
"android.support.v4.provider",
"android.support.v4.speech.tts",
"android.support.v4.text",
"android.support.v4.util",
"android.support.v4.view",
"android.support.v4.view.accessibility",
"android.support.v4.widget",
};
static String[] sExportedPackages_app = new String[]{
"org.bbs.apklauncher.emb",
"org.bbs.apklauncher.emb.auto_gen",
};
private static /*final*/ String ANDROID_PACKAGES_FOR_EXPORT_EXTRA = "";
static {
List<String> exportedPackages = new ArrayList<String>();
exportedPackages = toList(sExportedPackages_app);
exportedPackages.addAll(toList(sExportedPackages_Android));
exportedPackages.addAll(toList(sExportedPackages_Android_v4));
for (String pkg: exportedPackages){
ANDROID_PACKAGES_FOR_EXPORT_EXTRA += pkg + ",";
}
ANDROID_PACKAGES_FOR_EXPORT_EXTRA = ANDROID_PACKAGES_FOR_EXPORT_EXTRA.substring(0, ANDROID_PACKAGES_FOR_EXPORT_EXTRA.length() - 1);
}
static List<String> toList(String[] array){
List<String> l = new ArrayList<>();
for (String s : array){
l.add(s);
}
return l;
}
}