Resources_Theme_Delegate.java revision 130d2353edda445b8e36a6b5e4b176fd748035b0
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
17package android.content.res;
18
19import com.android.annotations.Nullable;
20import com.android.ide.common.rendering.api.ResourceReference;
21import com.android.ide.common.rendering.api.StyleResourceValue;
22import com.android.layoutlib.bridge.android.BridgeContext;
23import com.android.layoutlib.bridge.impl.DelegateManager;
24import com.android.layoutlib.bridge.impl.RenderSessionImpl;
25import com.android.resources.ResourceType;
26import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
27
28import android.content.res.Resources.NotFoundException;
29import android.content.res.Resources.Theme;
30import android.util.AttributeSet;
31import android.util.TypedValue;
32
33/**
34 * Delegate used to provide new implementation of a select few methods of {@link Resources.Theme}
35 *
36 * Through the layoutlib_create tool, the original  methods of Theme have been replaced
37 * by calls to methods of the same name in this delegate class.
38 *
39 */
40public class Resources_Theme_Delegate {
41
42    // Whether to use the Theme.mThemeResId as primary theme.
43    boolean force;
44
45    // ---- delegate manager ----
46
47    private static final DelegateManager<Resources_Theme_Delegate> sManager =
48            new DelegateManager<Resources_Theme_Delegate>(Resources_Theme_Delegate.class);
49
50    public static DelegateManager<Resources_Theme_Delegate> getDelegateManager() {
51        return sManager;
52    }
53
54    // ---- delegate methods. ----
55
56    @LayoutlibDelegate
57    /*package*/ static TypedArray obtainStyledAttributes(
58            Resources thisResources, Theme thisTheme,
59            int[] attrs) {
60        boolean changed = setupResources(thisTheme);
61        TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
62        restoreResources(changed);
63        return ta;
64    }
65
66    @LayoutlibDelegate
67    /*package*/ static TypedArray obtainStyledAttributes(
68            Resources thisResources, Theme thisTheme,
69            int resid, int[] attrs)
70            throws NotFoundException {
71        boolean changed = setupResources(thisTheme);
72        TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid, attrs);
73        restoreResources(changed);
74        return ta;
75    }
76
77    @LayoutlibDelegate
78    /*package*/ static TypedArray obtainStyledAttributes(
79            Resources thisResources, Theme thisTheme,
80            AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
81        boolean changed = setupResources(thisTheme);
82        TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(set, attrs,
83                defStyleAttr, defStyleRes);
84        restoreResources(changed);
85        return ta;
86    }
87
88    @LayoutlibDelegate
89    /*package*/ static boolean resolveAttribute(
90            Resources thisResources, Theme thisTheme,
91            int resid, TypedValue outValue,
92            boolean resolveRefs) {
93        boolean changed = setupResources(thisTheme);
94        boolean found =  RenderSessionImpl.getCurrentContext().resolveThemeAttribute(
95                resid, outValue, resolveRefs);
96        restoreResources(changed);
97        return found;
98    }
99
100    @LayoutlibDelegate
101    /*package*/ static TypedArray resolveAttributes(Resources thisResources, Theme thisTheme,
102            int[] values, int[] attrs) {
103        // FIXME
104        return null;
105    }
106
107    // ---- private helper methods ----
108
109    private static boolean setupResources(Theme thisTheme) {
110        Resources_Theme_Delegate themeDelegate = sManager.getDelegate(thisTheme.getNativeTheme());
111        StyleResourceValue style = resolveStyle(thisTheme.getAppliedStyleResId());
112        if (style != null) {
113            RenderSessionImpl.getCurrentContext().getRenderResources()
114                    .applyStyle(style, themeDelegate.force);
115            return true;
116        }
117        return false;
118    }
119
120    private static void restoreResources(boolean changed) {
121        if (changed) {
122            RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles();
123        }
124    }
125
126    @Nullable
127    private static StyleResourceValue resolveStyle(int nativeResid) {
128        if (nativeResid == 0) {
129            return null;
130        }
131        BridgeContext context = RenderSessionImpl.getCurrentContext();
132        ResourceReference theme = context.resolveId(nativeResid);
133        if (theme.isFramework()) {
134            return (StyleResourceValue) context.getRenderResources()
135                    .getFrameworkResource(ResourceType.STYLE, theme.getName());
136        } else {
137            return (StyleResourceValue) context.getRenderResources()
138                    .getProjectResource(ResourceType.STYLE, theme.getName());
139        }
140    }
141}
142