Home | History | Annotate | Download | only in res
      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 
     48     public static DelegateManager<Resources_Theme_Delegate> getDelegateManager() {
     49         return sManager;
     50     }
     51 
     52     // ---- delegate methods. ----
     53 
     54     @LayoutlibDelegate
     55     /*package*/ static TypedArray obtainStyledAttributes(
     56             Resources thisResources, Theme thisTheme,
     57             int[] attrs) {
     58         boolean changed = setupResources(thisTheme);
     59         BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
     60         ta.setTheme(thisTheme);
     61         restoreResources(changed);
     62         return ta;
     63     }
     64 
     65     @LayoutlibDelegate
     66     /*package*/ static TypedArray obtainStyledAttributes(
     67             Resources thisResources, Theme thisTheme,
     68             int resid, int[] attrs)
     69             throws NotFoundException {
     70         boolean changed = setupResources(thisTheme);
     71         BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid,
     72                 attrs);
     73         ta.setTheme(thisTheme);
     74         restoreResources(changed);
     75         return ta;
     76     }
     77 
     78     @LayoutlibDelegate
     79     /*package*/ static TypedArray obtainStyledAttributes(
     80             Resources thisResources, Theme thisTheme,
     81             AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
     82         boolean changed = setupResources(thisTheme);
     83         BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(set,
     84                 attrs, defStyleAttr, defStyleRes);
     85         ta.setTheme(thisTheme);
     86         restoreResources(changed);
     87         return ta;
     88     }
     89 
     90     @LayoutlibDelegate
     91     /*package*/ static boolean resolveAttribute(
     92             Resources thisResources, Theme thisTheme,
     93             int resid, TypedValue outValue,
     94             boolean resolveRefs) {
     95         boolean changed = setupResources(thisTheme);
     96         boolean found =  RenderSessionImpl.getCurrentContext().resolveThemeAttribute(resid,
     97                 outValue, resolveRefs);
     98         restoreResources(changed);
     99         return found;
    100     }
    101 
    102     @LayoutlibDelegate
    103     /*package*/ static TypedArray resolveAttributes(Resources thisResources, Theme thisTheme,
    104             int[] values, int[] attrs) {
    105         // FIXME
    106         return null;
    107     }
    108 
    109     // ---- private helper methods ----
    110 
    111     private static boolean setupResources(Theme thisTheme) {
    112         // Key is a space-separated list of theme ids applied that have been merged into the
    113         // BridgeContext's theme to make thisTheme.
    114         final ThemeKey key = thisTheme.getKey();
    115         final int[] resId = key.mResId;
    116         final boolean[] force = key.mForce;
    117 
    118         boolean changed = false;
    119         for (int i = 0, N = key.mCount; i < N; i++) {
    120             StyleResourceValue style = resolveStyle(resId[i]);
    121             if (style != null) {
    122                 RenderSessionImpl.getCurrentContext().getRenderResources().applyStyle(
    123                         style, force[i]);
    124                 changed = true;
    125             }
    126 
    127         }
    128         return changed;
    129     }
    130 
    131     private static void restoreResources(boolean changed) {
    132         if (changed) {
    133             RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles();
    134         }
    135     }
    136 
    137     @Nullable
    138     private static StyleResourceValue resolveStyle(int nativeResid) {
    139         if (nativeResid == 0) {
    140             return null;
    141         }
    142         BridgeContext context = RenderSessionImpl.getCurrentContext();
    143         ResourceReference theme = context.resolveId(nativeResid);
    144         if (theme.isFramework()) {
    145             return (StyleResourceValue) context.getRenderResources()
    146                     .getFrameworkResource(ResourceType.STYLE, theme.getName());
    147         } else {
    148             return (StyleResourceValue) context.getRenderResources()
    149                     .getProjectResource(ResourceType.STYLE, theme.getName());
    150         }
    151     }
    152 }
    153