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().internalObtainStyledAttributes(
     60                 0, attrs);
     61         ta.setTheme(thisTheme);
     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         BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().internalObtainStyledAttributes(
     73                 resid, attrs);
     74         ta.setTheme(thisTheme);
     75         restoreResources(changed);
     76         return ta;
     77     }
     78 
     79     @LayoutlibDelegate
     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
     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
    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 
    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 
    132     private static void restoreResources(boolean changed) {
    133         if (changed) {
    134             RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles();
    135         }
    136     }
    137 
    138     @Nullable
    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         if (theme.isFramework()) {
    146             return (StyleResourceValue) context.getRenderResources()
    147                     .getFrameworkResource(ResourceType.STYLE, theme.getName());
    148         } else {
    149             return (StyleResourceValue) context.getRenderResources()
    150                     .getProjectResource(ResourceType.STYLE, theme.getName());
    151         }
    152     }
    153 }
    154