diff options
author | Deepanshu Gupta <deepanshu@google.com> | 2014-05-13 16:32:02 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-05-13 16:32:02 +0000 |
commit | 9053261a5413f401168d25fa4a9749723b232949 (patch) | |
tree | 638872007433cb85636a63967ee0ab7b2a33212d /tools/layoutlib | |
parent | 5594616c4f4513dc97b08d6cabb6fd7127dde131 (diff) | |
parent | 052e0c589e5cf714ca71bc8d7b3ce8b3f6c4cb96 (diff) | |
download | frameworks_base-9053261a5413f401168d25fa4a9749723b232949.zip frameworks_base-9053261a5413f401168d25fa4a9749723b232949.tar.gz frameworks_base-9053261a5413f401168d25fa4a9749723b232949.tar.bz2 |
am 052e0c58: am 770e40f8: Fix theme/style resolution in Layoutlib [DO NOT MERGE]
* commit '052e0c589e5cf714ca71bc8d7b3ce8b3f6c4cb96':
Fix theme/style resolution in Layoutlib [DO NOT MERGE]
Diffstat (limited to 'tools/layoutlib')
4 files changed, 150 insertions, 14 deletions
diff --git a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java new file mode 100644 index 0000000..f3d6ba3 --- /dev/null +++ b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.res; + +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; + +/** + * Delegate used to provide implementation of a select few native methods of {@link AssetManager} + * <p/> + * Through the layoutlib_create tool, the original native methods of AssetManager have been replaced + * by calls to methods of the same name in this delegate class. + * + */ +public class AssetManager_Delegate { + + @LayoutlibDelegate + /*package*/ static int newTheme(AssetManager manager) { + return Resources_Theme_Delegate.getDelegateManager() + .addNewDelegate(new Resources_Theme_Delegate()); + } + + @LayoutlibDelegate + /*package*/ static void deleteTheme(AssetManager manager, int theme) { + Resources_Theme_Delegate.getDelegateManager().removeJavaReferenceFor(theme); + } + + @LayoutlibDelegate + /*package*/ static void applyThemeStyle(int theme, int styleRes, boolean force) { + Resources_Theme_Delegate delegate = Resources_Theme_Delegate.getDelegateManager() + .getDelegate(theme); + delegate.mThemeResId = styleRes; + delegate.force = force; + } +} diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java index c9d615c..b89d15f 100644 --- a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java +++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java @@ -16,7 +16,13 @@ package android.content.res; +import com.android.annotations.Nullable; +import com.android.ide.common.rendering.api.ResourceReference; +import com.android.ide.common.rendering.api.StyleResourceValue; +import com.android.layoutlib.bridge.android.BridgeContext; +import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.layoutlib.bridge.impl.RenderSessionImpl; +import com.android.resources.ResourceType; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.content.res.Resources.NotFoundException; @@ -25,7 +31,7 @@ import android.util.AttributeSet; import android.util.TypedValue; /** - * Delegate used to provide new implementation of a select few methods of {@link Resources$Theme} + * Delegate used to provide new implementation of a select few methods of {@link Resources.Theme} * * Through the layoutlib_create tool, the original methods of Theme have been replaced * by calls to methods of the same name in this delegate class. @@ -33,11 +39,30 @@ import android.util.TypedValue; */ public class Resources_Theme_Delegate { + // Resource identifier for the theme. + int mThemeResId; + // Whether to use the Theme.mThemeResId as primary theme. + boolean force; + + // ---- delegate manager ---- + + private static final DelegateManager<Resources_Theme_Delegate> sManager = + new DelegateManager<Resources_Theme_Delegate>(Resources_Theme_Delegate.class); + + public static DelegateManager<Resources_Theme_Delegate> getDelegateManager() { + return sManager; + } + + // ---- delegate methods. ---- + @LayoutlibDelegate /*package*/ static TypedArray obtainStyledAttributes( Resources thisResources, Theme thisTheme, int[] attrs) { - return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs); + boolean changed = setupResources(thisTheme); + TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs); + restoreResources(changed); + return ta; } @LayoutlibDelegate @@ -45,15 +70,21 @@ public class Resources_Theme_Delegate { Resources thisResources, Theme thisTheme, int resid, int[] attrs) throws NotFoundException { - return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid, attrs); + boolean changed = setupResources(thisTheme); + TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid, attrs); + restoreResources(changed); + return ta; } @LayoutlibDelegate /*package*/ static TypedArray obtainStyledAttributes( Resources thisResources, Theme thisTheme, AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { - return RenderSessionImpl.getCurrentContext().obtainStyledAttributes( - set, attrs, defStyleAttr, defStyleRes); + boolean changed = setupResources(thisTheme); + TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(set, attrs, + defStyleAttr, defStyleRes); + restoreResources(changed); + return ta; } @LayoutlibDelegate @@ -61,7 +92,45 @@ public class Resources_Theme_Delegate { Resources thisResources, Theme thisTheme, int resid, TypedValue outValue, boolean resolveRefs) { - return RenderSessionImpl.getCurrentContext().resolveThemeAttribute( + boolean changed = setupResources(thisTheme); + boolean found = RenderSessionImpl.getCurrentContext().resolveThemeAttribute( resid, outValue, resolveRefs); + restoreResources(changed); + return found; + } + + // ---- private helper methods ---- + + private static boolean setupResources(Theme thisTheme) { + Resources_Theme_Delegate themeDelegate = sManager.getDelegate(thisTheme.getNativeTheme()); + StyleResourceValue style = resolveStyle(themeDelegate.mThemeResId); + if (style != null) { + RenderSessionImpl.getCurrentContext().getRenderResources() + .applyStyle(style, themeDelegate.force); + return true; + } + return false; + } + + private static void restoreResources(boolean changed) { + if (changed) { + RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles(); + } + } + + @Nullable + private static StyleResourceValue resolveStyle(int nativeResid) { + if (nativeResid == 0) { + return null; + } + BridgeContext context = RenderSessionImpl.getCurrentContext(); + ResourceReference theme = context.resolveId(nativeResid); + if (theme.isFramework()) { + return (StyleResourceValue) context.getRenderResources() + .getFrameworkResource(ResourceType.STYLE, theme.getName()); + } else { + return (StyleResourceValue) context.getRenderResources() + .getProjectResource(ResourceType.STYLE, theme.getName()); + } } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index e2fced6..a1c5be4 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -16,6 +16,7 @@ package com.android.layoutlib.bridge.android; +import com.android.annotations.Nullable; import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.LayoutLog; @@ -109,7 +110,7 @@ public final class BridgeContext extends Context { // maps for dynamically generated id representing style objects (StyleResourceValue) private Map<Integer, StyleResourceValue> mDynamicIdToStyleMap; private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap; - private int mDynamicIdGenerator = 0x01030000; // Base id for framework R.style + private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace // cache for TypedArray generated from IStyleResourceValue object private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache; @@ -311,6 +312,11 @@ public final class BridgeContext extends Context { } } + // The base value for R.style is 0x01030000 and the custom style is 0x02030000. + // So, if the second byte is 03, it's probably a style. + if ((id >> 16 & 0xFF) == 0x03) { + return getStyleByDynamicId(id); + } return null; } @@ -451,7 +457,10 @@ public final class BridgeContext extends Context { @Override public final TypedArray obtainStyledAttributes(int[] attrs) { - return createStyleBasedTypedArray(mRenderResources.getCurrentTheme(), attrs); + // No style is specified here, so create the typed array based on the default theme + // and the styles already applied to it. A null value of style indicates that the default + // theme should be used. + return createStyleBasedTypedArray(null, attrs); } @Override @@ -719,11 +728,13 @@ public final class BridgeContext extends Context { /** * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the - * values found in the given style. + * values found in the given style. If no style is specified, the default theme, along with the + * styles applied to it are used. + * * @see #obtainStyledAttributes(int, int[]) */ - private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs) - throws Resources.NotFoundException { + private BridgeTypedArray createStyleBasedTypedArray(@Nullable StyleResourceValue style, + int[] attrs) throws Resources.NotFoundException { List<Pair<String, Boolean>> attributes = searchAttrs(attrs); @@ -736,8 +747,14 @@ public final class BridgeContext extends Context { if (attribute != null) { // look for the value in the given style - ResourceValue resValue = mRenderResources.findItemInStyle(style, - attribute.getFirst(), attribute.getSecond()); + ResourceValue resValue; + if (style != null) { + resValue = mRenderResources.findItemInStyle(style, attribute.getFirst(), + attribute.getSecond()); + } else { + resValue = mRenderResources.findItemInTheme(attribute.getFirst(), + attribute.getSecond()); + } if (resValue != null) { // resolve it to make sure there are no references left. @@ -752,7 +769,6 @@ public final class BridgeContext extends Context { return ta; } - /** * The input int[] attrs is a list of attributes. The returns a list of information about * each attributes. The information is (name, isFramework) diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java index 4c65cbb..ca6e968 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java @@ -125,6 +125,9 @@ public final class CreateInfo implements ICreateInfo { "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;", "android.content.res.Resources$Theme#obtainStyledAttributes", "android.content.res.Resources$Theme#resolveAttribute", + "android.content.res.AssetManager#newTheme", + "android.content.res.AssetManager#deleteTheme", + "android.content.res.AssetManager#applyThemeStyle", "android.content.res.TypedArray#getValueAt", "android.graphics.BitmapFactory#finishDecode", "android.os.Handler#sendMessageAtTime", |