Home | History | Annotate | Download | only in server
      1 /*
      2 **
      3 ** Copyright 2007, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 package com.android.server;
     19 
     20 import android.content.Context;
     21 import android.content.pm.ActivityInfo;
     22 import android.content.pm.PackageManager;
     23 import android.content.res.Configuration;
     24 import android.content.res.Resources;
     25 import android.content.res.TypedArray;
     26 import android.util.SparseArray;
     27 
     28 import java.util.HashMap;
     29 import java.util.WeakHashMap;
     30 
     31 /**
     32  * TODO: This should be better integrated into the system so it doesn't need
     33  * special calls from the activity manager to clear it.
     34  */
     35 public final class AttributeCache {
     36     private static AttributeCache sInstance = null;
     37 
     38     private final Context mContext;
     39     private final WeakHashMap<String, Package> mPackages =
     40             new WeakHashMap<String, Package>();
     41     private final Configuration mConfiguration = new Configuration();
     42 
     43     public final static class Package {
     44         public final Context context;
     45         private final SparseArray<HashMap<int[], Entry>> mMap
     46                 = new SparseArray<HashMap<int[], Entry>>();
     47 
     48         public Package(Context c) {
     49             context = c;
     50         }
     51     }
     52 
     53     public final static class Entry {
     54         public final Context context;
     55         public final TypedArray array;
     56 
     57         public Entry(Context c, TypedArray ta) {
     58             context = c;
     59             array = ta;
     60         }
     61     }
     62 
     63     public static void init(Context context) {
     64         if (sInstance == null) {
     65             sInstance = new AttributeCache(context);
     66         }
     67     }
     68 
     69     public static AttributeCache instance() {
     70         return sInstance;
     71     }
     72 
     73     public AttributeCache(Context context) {
     74         mContext = context;
     75     }
     76 
     77     public void removePackage(String packageName) {
     78         synchronized (this) {
     79             mPackages.remove(packageName);
     80         }
     81     }
     82 
     83     public void updateConfiguration(Configuration config) {
     84         synchronized (this) {
     85             int changes = mConfiguration.updateFrom(config);
     86             if ((changes & ~(ActivityInfo.CONFIG_FONT_SCALE |
     87                     ActivityInfo.CONFIG_KEYBOARD_HIDDEN |
     88                     ActivityInfo.CONFIG_ORIENTATION)) != 0) {
     89                 // The configurations being masked out are ones that commonly
     90                 // change so we don't want flushing the cache... all others
     91                 // will flush the cache.
     92                 mPackages.clear();
     93             }
     94         }
     95     }
     96 
     97     public Entry get(String packageName, int resId, int[] styleable) {
     98         synchronized (this) {
     99             Package pkg = mPackages.get(packageName);
    100             HashMap<int[], Entry> map = null;
    101             Entry ent = null;
    102             if (pkg != null) {
    103                 map = pkg.mMap.get(resId);
    104                 if (map != null) {
    105                     ent = map.get(styleable);
    106                     if (ent != null) {
    107                         return ent;
    108                     }
    109                 }
    110             } else {
    111                 Context context;
    112                 try {
    113                     context = mContext.createPackageContext(packageName, 0);
    114                     if (context == null) {
    115                         return null;
    116                     }
    117                 } catch (PackageManager.NameNotFoundException e) {
    118                     return null;
    119                 }
    120                 pkg = new Package(context);
    121                 mPackages.put(packageName, pkg);
    122             }
    123 
    124             if (map == null) {
    125                 map = new HashMap<int[], Entry>();
    126                 pkg.mMap.put(resId, map);
    127             }
    128 
    129             try {
    130                 ent = new Entry(pkg.context,
    131                         pkg.context.obtainStyledAttributes(resId, styleable));
    132                 map.put(styleable, ent);
    133             } catch (Resources.NotFoundException e) {
    134                 return null;
    135             }
    136 
    137             return ent;
    138         }
    139     }
    140 }
    141 
    142