FrontDoorPluginpublic class FrontDoorPlugin extends android.app.Service
Fields Summary |
---|
private static final String | TAG | private static final boolean | LOCAL_DEBUG | private static final String[] | BRANDING_RESOURCE_MAP_CACHE_PROJECTION | private static final int | BRANDING_RESOURCE_MAP_CACHE_PROVIDER_ID_COLUMN | private static final int | BRANDING_RESOURCE_MAP_CACHE_APP_RES_ID_COLUMN | private static final int | BRANDING_RESOURCE_MAP_CACHE_PLUGIN_RES_ID_COLUMN | private ArrayList | mProviderNames | private HashMap | mPackageNames | private HashMap | mBrandingResources | private final IImPlugin.Stub | mBinderThe implementation of IImFrontDoorPlugin defined through AIDL. |
Methods Summary |
---|
private java.util.Map | loadBrandingResource(java.lang.Class cls)Load branding resources from one plugin.
try {
Method m = cls.getMethod("getResourceMap");
// TODO: this would still cause a VM verifier exception to be thrown if.
// the landing page Android.mk and AndroidManifest.xml don't include use-library for
// "com.android.im.plugin". This is even with getCustomClassLoader() as the parent
// class loader.
return (Map)m.invoke(cls.newInstance(), new Object[]{});
} catch (IllegalAccessException e) {
Log.e(TAG, "Failed load the plugin resource map", e);
} catch (InstantiationException e) {
Log.e(TAG, "Failed load the plugin resource map", e);
} catch (SecurityException e) {
Log.e(TAG, "Failed load the plugin resource map", e);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Failed load the plugin resource map", e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Failed load the plugin resource map", e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Failed load the plugin resource map", e);
}
return null;
| private void | loadBrandingResources(java.util.HashMap providerNameToId, java.util.HashMap providerIdToName, java.util.HashMap classes)
mBrandingResources = new HashMap<String, Map<Integer, Integer>>();
// first try load from cache
loadBrandingResourcesFromCache(providerIdToName);
// check and load any un-cached resources
final ArrayList<ContentValues> valuesList = new ArrayList<ContentValues>();
for (String provider : mProviderNames) {
long providerId = providerNameToId.get(provider);
if (!mBrandingResources.containsKey(provider)) {
Map<Integer, Integer> resMap = loadBrandingResource(classes.get(provider));
if (resMap != null) {
mBrandingResources.put(provider, resMap);
for (int appResId : resMap.keySet()) {
int pluginResId = resMap.get(appResId);
ContentValues values = new ContentValues();
values.put(Im.BrandingResourceMapCache.PROVIDER_ID, providerId);
values.put(Im.BrandingResourceMapCache.APP_RES_ID, appResId);
values.put(Im.BrandingResourceMapCache.PLUGIN_RES_ID, pluginResId);
valuesList.add(values);
}
Log.d(TAG, "Plugin " + provider + " not in cache, loaded and saved");
}
}
}
// save the changes to cache
if (valuesList.size() > 0) {
new Thread(new Runnable() {
public void run() {
getContentResolver().bulkInsert(
Im.BrandingResourceMapCache.CONTENT_URI,
valuesList.toArray(new ContentValues[]{}));
}
}).start();
}
| private void | loadBrandingResourcesFromCache(java.util.HashMap providerIdToName)Try loading the branding resources from the database.
ContentResolver cr = getContentResolver();
Cursor c = cr.query(
Im.BrandingResourceMapCache.CONTENT_URI, /* URI */
BRANDING_RESOURCE_MAP_CACHE_PROJECTION, /* projection */
null, /* where */
null, /* where args */
null /* sort */);
if (c != null) {
try {
while (c.moveToNext()) {
long providerId = c.getLong(BRANDING_RESOURCE_MAP_CACHE_PROVIDER_ID_COLUMN);
String provider = providerIdToName.get(providerId);
if (TextUtils.isEmpty(provider)) {
Log.e(TAG, "Empty provider name in branding resource map cache table.");
continue;
}
int appResId = c.getInt(BRANDING_RESOURCE_MAP_CACHE_APP_RES_ID_COLUMN);
int pluginResId = c.getInt(BRANDING_RESOURCE_MAP_CACHE_PLUGIN_RES_ID_COLUMN);
Map<Integer, Integer> resMap = mBrandingResources.get(provider);
if (resMap == null) {
resMap = new HashMap<Integer, Integer>();
mBrandingResources.put(provider, resMap);
}
resMap.put(appResId, pluginResId);
}
} finally {
c.close();
}
} else {
Log.e(TAG, "Query of branding resource map cache table returns empty cursor");
}
| private java.lang.Class | loadClass(java.lang.String className, java.lang.String srcPath)
PathClassLoader loader = new PathClassLoader(srcPath, getClassLoader());
try {
return loader.loadClass(className);
} catch (ClassNotFoundException e) {
Log.e(TAG, "Could not find plugin class", e);
}
return null;
| private java.util.Map | loadProviderConfigFromPlugin(java.lang.Class cls)Load plugin config.
try {
Method m = cls.getMethod("onBind", Intent.class);
com.android.im.plugin.IImPlugin plugin =
(com.android.im.plugin.IImPlugin)m.invoke(cls.newInstance(), new Object[]{null});
return plugin.getProviderConfig();
} catch (IllegalAccessException e) {
Log.e(TAG, "Could not create plugin instance", e);
} catch (InstantiationException e) {
Log.e(TAG, "Could not create plugin instance", e);
} catch (SecurityException e) {
Log.e(TAG, "Could not load config from the plugin", e);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Could not load config from the plugin", e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Could not load config from the plugin", e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Could not load config from the plugin", e);
} catch (RemoteException e) {
Log.e(TAG, "Could not load config from the plugin", e);
}
return null;
| private void | loadThirdPartyPlugins(java.util.HashMap providerNameToId, java.util.HashMap providerIdToName, java.util.HashMap classes)
mProviderNames = new ArrayList<String>();
mPackageNames = new HashMap<String, String>();
PackageManager pm = getPackageManager();
List<ResolveInfo> plugins = pm.queryIntentServices(
new Intent(ImPluginConstants.PLUGIN_ACTION_NAME), PackageManager.GET_META_DATA);
int numPlugins = plugins.size();
if (Log.isLoggable(TAG, Log.DEBUG)) {
log("loadThirdPartyPlugins: # plugins found: " + numPlugins);
}
if (numPlugins == 0) {
Log.e(TAG, "[IM.FrontDoorPlugin] no plugins found! bail...");
return;
}
for (ResolveInfo info : plugins) {
if (Log.isLoggable(TAG, Log.DEBUG)) log("loadThirdPartyPlugins: found plugin " + info);
ServiceInfo serviceInfo = info.serviceInfo;
if (serviceInfo == null) {
Log.e(TAG, "[FrontDoorPlugin] loadThirdPartyPlugins: ignore bad plugin: " + info);
continue;
}
String providerName = null;
String providerFullName = null;
String signUpUrl = null;
Bundle metaData = serviceInfo.metaData;
if (metaData != null) {
providerName = metaData.getString(ImPluginConstants.METADATA_PROVIDER_NAME);
providerFullName =
metaData.getString(ImPluginConstants.METADATA_PROVIDER_FULL_NAME);
signUpUrl = metaData.getString(ImPluginConstants.METADATA_SIGN_UP_URL);
}
if (TextUtils.isEmpty(providerName) || TextUtils.isEmpty(providerFullName)) {
Log.e(TAG, "[FrontDoorPlugin] Ignore bad IM plugin: " + info +
". Lack of required meta data");
continue;
}
mProviderNames.add(providerName);
mPackageNames.put(providerName, serviceInfo.packageName);
String className = serviceInfo.name;
String srcPath = serviceInfo.applicationInfo.sourceDir;
Class pluginClass = loadClass(className, srcPath);
if (pluginClass == null) {
Log.e(TAG, "[FrontDoorPlugin] Can not load package for plugin " + providerName);
continue;
}
classes.put(providerName, pluginClass);
Map<String, String> config = loadProviderConfigFromPlugin(pluginClass);
if (config == null) {
Log.e(TAG, "[FrontDoorPlugin] Can not load config for plugin " + providerName);
continue;
}
config.put(ImConfigNames.PLUGIN_PATH, srcPath);
config.put(ImConfigNames.PLUGIN_CLASS, className);
long providerId = DatabaseUtils.updateProviderDb(getContentResolver(),
providerName, providerFullName, signUpUrl, config);
providerNameToId.put(providerName, providerId);
providerIdToName.put(providerId, providerName);
}
| private void | log(java.lang.String msg)
Log.d(TAG, "[ImFrontDoor] " + msg);
| public android.os.IBinder | onBind(android.content.Intent intent)
// temporary mappings
HashMap<String, Long> providerNameToId = new HashMap<String, Long>();
HashMap<Long, String> providerIdToName = new HashMap<Long, String>();
HashMap<String, Class> classes = new HashMap<String, Class>();
loadThirdPartyPlugins(providerNameToId, providerIdToName, classes);
loadBrandingResources(providerNameToId, providerIdToName, classes);
return mBinder;
|
|