FileDocCategorySizeDatePackage
FrontDoorPlugin.javaAPI DocAndroid 1.5 API14611Wed May 06 22:42:46 BST 2009com.android.im.app

FrontDoorPlugin

public 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
mBinder
The implementation of IImFrontDoorPlugin defined through AIDL.
Constructors Summary
Methods Summary
private java.util.MaploadBrandingResource(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 voidloadBrandingResources(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 voidloadBrandingResourcesFromCache(java.util.HashMap providerIdToName)
Try loading the branding resources from the database.

param
providerIdToName a map between provider ID and name.

        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.ClassloadClass(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.MaploadProviderConfigFromPlugin(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 voidloadThirdPartyPlugins(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 voidlog(java.lang.String msg)

        Log.d(TAG, "[ImFrontDoor] " + msg);
    
public android.os.IBinderonBind(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;