package org.bbs.apklauncher;
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.view.LayoutInflater;
/**
* when bundle resource is ready, return this, otherwise, return normally.
* @author bysong
*
*/
public class TargetContext extends
//ContextWrapper
FileContext
//ContextThemeWrapper
{
private static final String TAG = TargetContext.class.getSimpleName();
private String mPackageName;
private Resources mResource;
private ClassLoader mClassLoader;
private ClassLoader mMergedClassLoader;
private PackageManager mPackageManager;
private Context mAppContext;
private Theme mTargetTheme;
private int mTargetThemeId;
private Activity mHostActivity;
private LayoutInflater mInflater;
private String mCookie;
public TargetContext(Context base) {
super(base);
// this(base, 0);
}
public void setCookie(String cookie){
mCookie = cookie;
}
public String getCookie() {
return mCookie;
}
public String getTargetPackageName(){
return mPackageName;
}
// TODO move xxxReade functions to attach(xx1 x, xx2 x2, ...)
public static void bundleReadyX(TargetContext LazyContext, Bundle bundle, Resources res, String packageName) {
// trivas build error
// LazyContext.mClassLoader = bundle.adapt(BundleWiring.class).getClassLoader();
// LazyContext.mResource = res;
// mPackageName = packageName;
notSupported();
}
public void packageManagerReady(PackageManager pm) {
mPackageManager = pm;
}
public void applicationContextReady(Context appContext){
mAppContext = appContext;
}
public void packageNameReady(String packageName) {
mPackageName = packageName;
}
public void themeReady(int theme) {
mTargetThemeId = theme;
}
public void resReady(Resources res) {
mResource = res;
}
public void classLoaderReady(ClassLoader classloader) {
mClassLoader = classloader;
}
//------------------------------------------------------------------
@Override
public Theme getTheme() {
Theme theme = null;
if (null != mTargetTheme) {
theme = mTargetTheme;
}
if (mResource != null) {
if (mTargetThemeId > 0) {
if (mTargetTheme == null) {
mTargetTheme = mResource.newTheme();
}
mTargetTheme.applyStyle(mTargetThemeId, true);
theme = mTargetTheme;
}
}
if (theme == null) {
theme = super.getTheme();
}
// Log.d(TAG, "getTheme(). theme: " + theme);
return theme;
}
@Override
public String getPackageName() {
String pName = doGetPackageName();
// Log.d(TAG, "getPackageName(). packageName: " + pName);
return pName;
}
private String doGetPackageName() {
// new Exception("stack info").printStackTrace();
if (!TextUtils.isEmpty(mPackageName)) {
return mPackageName;
}
return super.getPackageName();
}
@Override
public Resources getResources() {
Resources res = null;
if (null == mResource) {
res = super.getResources();
} else {
res = mResource;
}
// Log.d(TAG, "getResources(). res: " + res);
return res;
}
@Override
public AssetManager getAssets() {
if (null != mResource) {
if (mResource instanceof ResourcesMerger) {
Resources r = ((ResourcesMerger)mResource).mFirst;
return getAsset(r);
}
}
return super.getAssets();
}
private AssetManager getAsset(Resources r) {
return (AssetManager) ReflectUtil.getFiledValue(Resources.class, r, "mAssets");
}
@Override
public ClassLoader getClassLoader() {
ClassLoader cl = super.getClassLoader();
if (mClassLoader != null) {
if (mMergedClassLoader == null) {
mMergedClassLoader = new MergedClassLoader(cl, mClassLoader);
}
cl = mMergedClassLoader;
}
return cl;
}
@Override
public PackageManager getPackageManager() {
PackageManager pm = doGetPackageManager();
// Log.d(TAG, "pm: " + pm);
return pm;
}
private PackageManager doGetPackageManager() {
// new Exception("stack info").printStackTrace();
if (mPackageManager != null) {
return mPackageManager;
}
return super.getPackageManager();
}
@Override
public Context getApplicationContext() {
if (mAppContext != null) {
return mAppContext;
}
return super.getApplicationContext();
}
@Override
public ComponentName startService(Intent service) {
if (ApkLauncherConfig.ENALBE_SERVICE) {
ApkLauncher.getInstance().onProcessIntent(service, mClassLoader, getBaseContext());
return super.startService(service);
} else {
Log.w(TAG, "startService not implemented.");
return null;
}
}
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
if (ApkLauncherConfig.ENALBE_SERVICE) {
ApkLauncher.getInstance().onProcessIntent(service, mClassLoader, getBaseContext());
return super.bindService(service, conn, flags);
} else {
Log.w(TAG, "bindService not implemented.");
return false;
}
}
@Override
public boolean stopService(Intent service) {
if (ApkLauncherConfig.ENALBE_SERVICE) {
ApkLauncher.getInstance().onProcessIntent(service, mClassLoader, getBaseContext());
return super.stopService(service);
} else {
Log.w(TAG, "stopService not implemented.");
return false;
}
}
@Override
public void unbindService(ServiceConnection conn) {
if (ApkLauncherConfig.ENALBE_SERVICE) {
super.unbindService(conn);
} else {
Log.w(TAG, "unbindService not implemented.");
}
}
@Override
public Object getSystemService(String name) {
// adjust layout inflater
// if (LAYOUT_INFLATER_SERVICE.equals(name)) {
// if (mInflater == null) {
// mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
// }
// return mInflater;
// }
return getBaseContext().getSystemService(name);
}
static void notSupported() {
throw new RuntimeException("not supported.");
}
static class MergedAssetManager
// extends AssetManager
{
}
static class MergedClassLoader extends ClassLoader {
private ClassLoader mMajor;
private ClassLoader mMinor;
MergedClassLoader(ClassLoader major, ClassLoader minor) {
mMajor = major;
mMinor = minor;
}
@Override
protected Class<?> loadClass(String className, boolean resolve)
throws ClassNotFoundException {
try {
return mMajor.loadClass(className);
} catch (Exception e) {
return mMinor.loadClass(className);
}
}
}
}