1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.content.res; 18 19 import com.android.ide.common.rendering.api.ResourceReference; 20 import com.android.ide.common.rendering.api.StyleResourceValue; 21 import com.android.layoutlib.bridge.android.BridgeContext; 22 import com.android.layoutlib.bridge.impl.DelegateManager; 23 import com.android.layoutlib.bridge.impl.RenderSessionImpl; 24 import com.android.resources.ResourceType; 25 import com.android.tools.layoutlib.annotations.LayoutlibDelegate; 26 27 import android.annotation.Nullable; 28 import android.content.res.Resources.NotFoundException; 29 import android.content.res.Resources.Theme; 30 import android.content.res.Resources.ThemeKey; 31 import android.util.AttributeSet; 32 import android.util.TypedValue; 33 34 /** 35 * Delegate used to provide new implementation of a select few methods of {@link Resources.Theme} 36 * 37 * Through the layoutlib_create tool, the original methods of Theme have been replaced 38 * by calls to methods of the same name in this delegate class. 39 * 40 */ 41 public class Resources_Theme_Delegate { 42 43 // ---- delegate manager ---- 44 45 private static final DelegateManager<Resources_Theme_Delegate> sManager = 46 new DelegateManager<Resources_Theme_Delegate>(Resources_Theme_Delegate.class); 47 getDelegateManager()48 public static DelegateManager<Resources_Theme_Delegate> getDelegateManager() { 49 return sManager; 50 } 51 52 // ---- delegate methods. ---- 53 54 @LayoutlibDelegate obtainStyledAttributes( Resources thisResources, Theme thisTheme, int[] attrs)55 /*package*/ static TypedArray obtainStyledAttributes( 56 Resources thisResources, Theme thisTheme, 57 int[] attrs) { 58 boolean changed = setupResources(thisTheme); 59 BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().internalObtainStyledAttributes( 60 0, attrs); 61 ta.setTheme(thisTheme); 62 restoreResources(changed); 63 return ta; 64 } 65 66 @LayoutlibDelegate obtainStyledAttributes( Resources thisResources, Theme thisTheme, int resid, int[] attrs)67 /*package*/ static TypedArray obtainStyledAttributes( 68 Resources thisResources, Theme thisTheme, 69 int resid, int[] attrs) 70 throws NotFoundException { 71 boolean changed = setupResources(thisTheme); 72 BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().internalObtainStyledAttributes( 73 resid, attrs); 74 ta.setTheme(thisTheme); 75 restoreResources(changed); 76 return ta; 77 } 78 79 @LayoutlibDelegate obtainStyledAttributes( Resources thisResources, Theme thisTheme, AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)80 /*package*/ static TypedArray obtainStyledAttributes( 81 Resources thisResources, Theme thisTheme, 82 AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { 83 boolean changed = setupResources(thisTheme); 84 BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().internalObtainStyledAttributes(set, 85 attrs, defStyleAttr, defStyleRes); 86 ta.setTheme(thisTheme); 87 restoreResources(changed); 88 return ta; 89 } 90 91 @LayoutlibDelegate resolveAttribute( Resources thisResources, Theme thisTheme, int resid, TypedValue outValue, boolean resolveRefs)92 /*package*/ static boolean resolveAttribute( 93 Resources thisResources, Theme thisTheme, 94 int resid, TypedValue outValue, 95 boolean resolveRefs) { 96 boolean changed = setupResources(thisTheme); 97 boolean found = RenderSessionImpl.getCurrentContext().resolveThemeAttribute(resid, 98 outValue, resolveRefs); 99 restoreResources(changed); 100 return found; 101 } 102 103 @LayoutlibDelegate resolveAttributes(Resources thisResources, Theme thisTheme, int[] values, int[] attrs)104 /*package*/ static TypedArray resolveAttributes(Resources thisResources, Theme thisTheme, 105 int[] values, int[] attrs) { 106 // FIXME 107 return null; 108 } 109 110 // ---- private helper methods ---- 111 setupResources(Theme thisTheme)112 private static boolean setupResources(Theme thisTheme) { 113 // Key is a space-separated list of theme ids applied that have been merged into the 114 // BridgeContext's theme to make thisTheme. 115 final ThemeKey key = thisTheme.getKey(); 116 final int[] resId = key.mResId; 117 final boolean[] force = key.mForce; 118 119 boolean changed = false; 120 for (int i = 0, N = key.mCount; i < N; i++) { 121 StyleResourceValue style = resolveStyle(resId[i]); 122 if (style != null) { 123 RenderSessionImpl.getCurrentContext().getRenderResources().applyStyle( 124 style, force[i]); 125 changed = true; 126 } 127 128 } 129 return changed; 130 } 131 restoreResources(boolean changed)132 private static void restoreResources(boolean changed) { 133 if (changed) { 134 RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles(); 135 } 136 } 137 138 @Nullable resolveStyle(int nativeResid)139 private static StyleResourceValue resolveStyle(int nativeResid) { 140 if (nativeResid == 0) { 141 return null; 142 } 143 BridgeContext context = RenderSessionImpl.getCurrentContext(); 144 ResourceReference theme = context.resolveId(nativeResid); 145 return (StyleResourceValue) context.getRenderResources().getResolvedResource(theme); 146 } 147 } 148