diff options
Diffstat (limited to 'core/java/android/content/res/Resources.java')
-rw-r--r-- | core/java/android/content/res/Resources.java | 165 |
1 files changed, 156 insertions, 9 deletions
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 731903c..f6a966b 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -21,6 +21,9 @@ import android.annotation.ColorInt; import android.annotation.StyleRes; import android.annotation.StyleableRes; import com.android.internal.util.GrowingArrayUtils; +import android.app.ComposedIconInfo; +import android.app.IconPackHelper; +import android.app.IconPackHelper.IconCustomizer; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; @@ -45,6 +48,7 @@ import android.annotation.RawRes; import android.annotation.StringRes; import android.annotation.XmlRes; import android.content.pm.ActivityInfo; +import android.content.pm.PackageItemInfo; import android.graphics.Movie; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -59,6 +63,7 @@ import android.util.Log; import android.util.LongSparseArray; import android.util.Pools.SynchronizedPool; import android.util.Slog; +import android.util.SparseArray; import android.util.TypedValue; import android.view.ViewDebug; import android.view.ViewHierarchyEncoder; @@ -108,6 +113,20 @@ public class Resources { private static final int ID_OTHER = 0x01000004; + // Package IDs for themes. Aapt will compile the res table with this id. + /** @hide */ + public static final int THEME_FRAMEWORK_PKG_ID = 0x60; + /** @hide */ + public static final int THEME_APP_PKG_ID = 0x61; + /** @hide */ + public static final int THEME_ICON_PKG_ID = 0x62; + /** + * The common resource pkg id needs to be less than the THEME_FRAMEWORK_PKG_ID + * otherwise aapt will complain and fail + * @hide + */ + public static final int THEME_COMMON_PKG_ID = THEME_FRAMEWORK_PKG_ID - 1; + private static final Object sSync = new Object(); // Information about preloaded resources. Note that they are not @@ -158,6 +177,9 @@ public class Resources { private CompatibilityInfo mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; + private SparseArray<PackageItemInfo> mIcons; + private ComposedIconInfo mComposedIconInfo; + static { sPreloadedDrawables = new LongSparseArray[2]; sPreloadedDrawables[0] = new LongSparseArray<>(); @@ -268,7 +290,7 @@ public class Resources { mCompatibilityInfo = compatInfo; } updateConfiguration(config, metrics); - assets.ensureStringBlocks(); + assets.recreateStringBlocks(); } /** @@ -793,6 +815,19 @@ public class Resources { */ @Nullable public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme) throws NotFoundException { + return getDrawable(id, theme, true); + } + + /** @hide */ + @Nullable + public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme, boolean supportComposedIcons) + throws NotFoundException { + //Check if an icon is themed + PackageItemInfo info = mIcons != null ? mIcons.get(id) : null; + if (info != null && info.themedIcon != 0) { + id = info.themedIcon; + } + TypedValue value; synchronized (mAccessLock) { value = mTmpValue; @@ -801,9 +836,24 @@ public class Resources { } else { mTmpValue = null; } - getValue(id, value, true); + getValue(id, value, true, supportComposedIcons); + } + Drawable res = null; + try { + res = loadDrawable(value, id, theme); + } catch (NotFoundException e) { + // The below statement will be true if we were trying to load a composed icon. + // Since we received a NotFoundException, try to load the original if this + // condition is true, otherwise throw the original exception. + if (supportComposedIcons && mComposedIconInfo != null && info != null && + info.themedIcon == 0) { + Log.e(TAG, "Failed to retrieve composed icon.", e); + getValue(id, value, true, false); + res = loadDrawable(value, id, theme); + } else { + throw e; + } } - final Drawable res = loadDrawable(value, id, theme); synchronized (mAccessLock) { if (mTmpValue == null) { mTmpValue = value; @@ -860,6 +910,19 @@ public class Resources { */ @Nullable public Drawable getDrawableForDensity(@DrawableRes int id, int density, @Nullable Theme theme) { + return getDrawableForDensity(id, density, theme, true); + } + + /** @hide */ + @Nullable + public Drawable getDrawableForDensity(@DrawableRes int id, int density, @Nullable Theme theme, + boolean supportComposedIcons) { + //Check if an icon was themed + PackageItemInfo info = mIcons != null ? mIcons.get(id) : null; + if (info != null && info.themedIcon != 0) { + id = info.themedIcon; + } + TypedValue value; synchronized (mAccessLock) { value = mTmpValue; @@ -868,7 +931,7 @@ public class Resources { } else { mTmpValue = null; } - getValueForDensity(id, density, value, true); + getValueForDensity(id, density, value, true, supportComposedIcons); /* * Pretend the requested density is actually the display density. If @@ -1344,8 +1407,24 @@ public class Resources { */ public void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException { + getValue(id, outValue, resolveRefs, true); + } + + /** @hide */ + public void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs, + boolean supportComposedIcons) throws NotFoundException { + //Check if an icon was themed + PackageItemInfo info = mIcons != null ? mIcons.get(id) : null; + if (info != null && info.themedIcon != 0) { + id = info.themedIcon; + } boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs); if (found) { + if (supportComposedIcons && IconPackHelper.shouldComposeIcon(mComposedIconInfo) + && info != null && info.themedIcon == 0) { + Drawable dr = loadDrawable(outValue, id, null); + IconCustomizer.getValue(this, id, outValue, dr); + } return; } throw new NotFoundException("Resource ID #0x" @@ -1367,8 +1446,45 @@ public class Resources { */ public void getValueForDensity(@AnyRes int id, int density, TypedValue outValue, boolean resolveRefs) throws NotFoundException { + getValueForDensity(id, density, outValue, resolveRefs, true); + } + + /** @hide */ + public void getValueForDensity(@AnyRes int id, int density, TypedValue outValue, + boolean resolveRefs, boolean supportComposedIcons) throws NotFoundException { + //Check if an icon was themed + PackageItemInfo info = mIcons != null ? mIcons.get(id) : null; + if (info != null && info.themedIcon != 0) { + id = info.themedIcon; + } + boolean found = mAssets.getResourceValue(id, density, outValue, resolveRefs); if (found) { + if (supportComposedIcons && IconPackHelper.shouldComposeIcon(mComposedIconInfo) && + info != null && info.themedIcon == 0) { + int tmpDensity = outValue.density; + /* + * Pretend the requested density is actually the display density. If + * the drawable returned is not the requested density, then force it + * to be scaled later by dividing its density by the ratio of + * requested density to actual device density. Drawables that have + * undefined density or no density don't need to be handled here. + */ + if (outValue.density > 0 && outValue.density != TypedValue.DENSITY_NONE) { + if (outValue.density == density) { + outValue.density = mMetrics.densityDpi; + } else { + outValue.density = (outValue.density * mMetrics.densityDpi) / density; + } + } + Drawable dr = loadDrawable(outValue, id, null); + + // Return to original density. If we do not do this then + // the caller will get the wrong density for the given id and perform + // more of its own scaling in loadDrawable + outValue.density = tmpDensity; + IconCustomizer.getValue(this, id, outValue, dr); + } return; } throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)); @@ -2083,7 +2199,15 @@ public class Resources { mTmpConfig.setLayoutDirection(mTmpConfig.locale); } configChanges = mConfiguration.updateFrom(mTmpConfig); - configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); + + /* This is ugly, but modifying the activityInfoConfigToNative + * adapter would be messier */ + if ((configChanges & ActivityInfo.CONFIG_THEME_RESOURCE) != 0) { + configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); + configChanges |= ActivityInfo.CONFIG_THEME_RESOURCE; + } else { + configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); + } } return configChanges; } @@ -2526,9 +2650,10 @@ public class Resources { // attributes. final ConstantState cs; if (isColorDrawable) { - cs = sPreloadedColorDrawables.get(key); + cs = mAssets.hasThemedAssets() ? null : sPreloadedColorDrawables.get(key); } else { - cs = sPreloadedDrawables[mConfiguration.getLayoutDirection()].get(key); + cs = mAssets.hasThemedAssets() ? null : + sPreloadedDrawables[mConfiguration.getLayoutDirection()].get(key); } Drawable dr; @@ -2666,7 +2791,7 @@ public class Resources { if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && value.type <= TypedValue.TYPE_LAST_COLOR_INT) { final android.content.res.ConstantState<ColorStateList> factory = - sPreloadedColorStateLists.get(key); + mAssets.hasThemedAssets() ? null : sPreloadedColorStateLists.get(key); if (factory != null) { return factory.newInstance(); } @@ -2690,7 +2815,7 @@ public class Resources { } final android.content.res.ConstantState<ColorStateList> factory = - sPreloadedColorStateLists.get(key); + mAssets.hasThemedAssets() ? null : sPreloadedColorStateLists.get(key); if (factory != null) { csl = factory.newInstance(this, theme); } @@ -2845,6 +2970,28 @@ public class Resources { return theme.obtainStyledAttributes(set, attrs, 0, 0); } + /** @hide */ + public void setIconResources(SparseArray<PackageItemInfo> icons) { + mIcons = icons; + } + + /** @hide */ + public void setComposedIconInfo(ComposedIconInfo iconInfo) { + mComposedIconInfo = iconInfo; + } + + /** @hide */ + public ComposedIconInfo getComposedIconInfo() { + return mComposedIconInfo; + } + + /** @hide */ + public final void updateStringCache() { + synchronized (mAccessLock) { + mAssets.recreateStringBlocks(); + } + } + private Resources() { mAssets = AssetManager.getSystem(); // NOTE: Intentionally leaving this uninitialized (all values set |