1 /* 2 * Copyright (C) 2008 Esmertec AG. 3 * Copyright (C) 2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.im.app; 19 20 import com.android.im.plugin.ImPlugin; 21 import com.android.im.plugin.ImPluginInfo; 22 import dalvik.system.PathClassLoader; 23 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.pm.PackageManager; 27 import android.content.pm.PackageManager.NameNotFoundException; 28 import android.content.res.Resources; 29 import android.graphics.drawable.Drawable; 30 import android.os.RemoteException; 31 import android.util.Log; 32 33 import java.lang.reflect.InvocationTargetException; 34 import java.lang.reflect.Method; 35 import java.util.Map; 36 37 /** 38 * The provider specific branding resources. 39 */ 40 public class BrandingResources { 41 private static final String TAG = ImApp.LOG_TAG; 42 43 private Map<Integer, Integer> mResMapping; 44 private Resources mPackageRes; 45 private int[] mSmileyIcons; 46 47 private BrandingResources mDefaultRes; 48 49 /** 50 * Creates a new BrandingResource of a specific plug-in. The resources will 51 * be retrieved from the plug-in package. 52 * 53 * @param context The current application context. 54 * @param pluginInfo The info about the plug-in. 55 * @param defaultRes The default branding resources. If the resource is not 56 * found in the plug-in, the default resource will be returned. 57 */ 58 public BrandingResources(Context context, ImPluginInfo pluginInfo, 59 BrandingResources defaultRes) { 60 mDefaultRes = defaultRes; 61 62 PackageManager pm = context.getPackageManager(); 63 try { 64 mPackageRes = pm.getResourcesForApplication(pluginInfo.mPackageName); 65 } catch (NameNotFoundException e) { 66 Log.e(TAG, "Can not load resources from package: " + pluginInfo.mPackageName); 67 } 68 // Load the plug-in directly from the apk instead of binding the service 69 // and calling through the IPC binder API. It's more effective in this way 70 // and we can avoid the async behaviors of binding service. 71 ClassLoader classLoader = context.getClassLoader(); 72 try { 73 Class cls = classLoader.loadClass(pluginInfo.mClassName); 74 Method m = cls.getMethod("onBind", Intent.class); 75 ImPlugin plugin = (ImPlugin)m.invoke(cls.newInstance(), new Object[]{null}); 76 mResMapping = plugin.getResourceMap(); 77 mSmileyIcons = plugin.getSmileyIconIds(); 78 } catch (ClassNotFoundException e) { 79 Log.e(TAG, "Failed load the plugin resource map", e); 80 } catch (IllegalAccessException e) { 81 Log.e(TAG, "Failed load the plugin resource map", e); 82 } catch (InstantiationException e) { 83 Log.e(TAG, "Failed load the plugin resource map", e); 84 } catch (SecurityException e) { 85 Log.e(TAG, "Failed load the plugin resource map", e); 86 } catch (NoSuchMethodException e) { 87 Log.e(TAG, "Failed load the plugin resource map", e); 88 } catch (IllegalArgumentException e) { 89 Log.e(TAG, "Failed load the plugin resource map", e); 90 } catch (InvocationTargetException e) { 91 Log.e(TAG, "Failed load the plugin resource map", e); 92 } 93 } 94 95 /** 96 * Creates a BrandingResource with application context and the resource ID map. 97 * The resource will be retrieved from the context directly instead from the plug-in package. 98 * 99 * @param context 100 * @param resMapping 101 */ 102 public BrandingResources(Context context, Map<Integer, Integer> resMapping, 103 BrandingResources defaultRes) { 104 this(context.getResources(), resMapping, null, defaultRes); 105 } 106 107 public BrandingResources(Resources packageRes, Map<Integer, Integer> resMapping, 108 int[] smileyIcons, BrandingResources defaultRes) { 109 mPackageRes = packageRes; 110 mResMapping = resMapping; 111 mSmileyIcons = smileyIcons; 112 mDefaultRes = defaultRes; 113 } 114 115 /** 116 * Gets a drawable object associated with a particular resource ID defined 117 * in {@link com.android.im.plugin.BrandingResourceIDs} 118 * 119 * @param id The ID defined in 120 * {@link com.android.im.plugin.BrandingResourceIDs} 121 * @return Drawable An object that can be used to draw this resource. 122 */ 123 public Drawable getDrawable(int id) { 124 int resId = getPackageResourceId(id); 125 if (resId != 0) { 126 return mPackageRes.getDrawable(resId); 127 } else if (mDefaultRes != null){ 128 return mDefaultRes.getDrawable(id); 129 } else { 130 return null; 131 } 132 } 133 134 /** 135 * Gets an array of the IDs of the supported smiley of the provider. Use 136 * {@link #getSmileyIcon(int)} to get the drawable object of the smiley. 137 * 138 * @return An array of the IDs of the supported smileys. 139 */ 140 public int[] getSmileyIcons() { 141 return mSmileyIcons; 142 } 143 144 /** 145 * Gets the drawable associated with particular smiley ID. 146 * 147 * @param smileyId The ID of the smiley returned in 148 * {@link #getSmileyIcons()} 149 * @return Drawable An object that can be used to draw this smiley. 150 */ 151 public Drawable getSmileyIcon(int smileyId){ 152 if (mPackageRes == null) { 153 return null; 154 } 155 return mPackageRes.getDrawable(smileyId); 156 } 157 158 /** 159 * Gets the string value associated with a particular resource ID defined in 160 * {@link com.android.im.plugin.BrandingResourceIDs} 161 * 162 * @param id The ID of the string resource defined in 163 * {@link com.android.im.plugin.BrandingResourceIDs} 164 * @param formatArgs The format arguments that will be used for 165 * substitution. 166 * @return The string data associated with the resource 167 */ 168 public String getString(int id, Object... formatArgs) { 169 int resId = getPackageResourceId(id); 170 if (resId != 0) { 171 return mPackageRes.getString(resId, formatArgs); 172 } else if (mDefaultRes != null){ 173 return mDefaultRes.getString(id, formatArgs); 174 } else { 175 return null; 176 } 177 } 178 179 /** 180 * Gets the string array associated with a particular resource ID defined in 181 * {@link com.android.im.plugin.BrandingResourceIDs} 182 * 183 * @param id The ID of the string resource defined in 184 * {@link com.android.im.plugin.BrandingResourceIDs} 185 * @return The string array associated with the resource. 186 */ 187 public String[] getStringArray(int id) { 188 int resId = getPackageResourceId(id); 189 if (resId != 0) { 190 return mPackageRes.getStringArray(resId); 191 } else if (mDefaultRes != null){ 192 return mDefaultRes.getStringArray(id); 193 } else { 194 return null; 195 } 196 } 197 198 private int getPackageResourceId(int id) { 199 if (mResMapping == null || mPackageRes == null) { 200 return 0; 201 } 202 Integer resId = mResMapping.get(id); 203 return resId == null ? 0 : resId; 204 } 205 206 } 207