Loading core/java/android/content/res/Resources.java +5 −0 Original line number Diff line number Diff line Loading @@ -1351,6 +1351,11 @@ public class Resources { private final AssetManager mAssets; private final int mTheme; // Needed by layoutlib. /*package*/ int getNativeTheme() { return mTheme; } } /** Loading tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * 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; } } tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java +75 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading @@ -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 Loading @@ -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 Loading @@ -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()); } } } tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +24 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -105,7 +106,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; Loading Loading @@ -307,6 +308,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; } Loading Loading @@ -449,7 +455,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 Loading Loading @@ -717,11 +726,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); Loading @@ -734,8 +745,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. Loading @@ -750,7 +767,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) Loading tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +3 −0 Original line number Diff line number Diff line Loading @@ -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", Loading Loading
core/java/android/content/res/Resources.java +5 −0 Original line number Diff line number Diff line Loading @@ -1351,6 +1351,11 @@ public class Resources { private final AssetManager mAssets; private final int mTheme; // Needed by layoutlib. /*package*/ int getNativeTheme() { return mTheme; } } /** Loading
tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * 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; } }
tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java +75 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading @@ -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 Loading @@ -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 Loading @@ -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()); } } }
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +24 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -105,7 +106,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; Loading Loading @@ -307,6 +308,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; } Loading Loading @@ -449,7 +455,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 Loading Loading @@ -717,11 +726,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); Loading @@ -734,8 +745,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. Loading @@ -750,7 +767,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) Loading
tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +3 −0 Original line number Diff line number Diff line Loading @@ -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", Loading