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.os.UserHandle;
     27 import android.util.SparseArray;
     28 
     29 import java.util.HashMap;
     30 import java.util.WeakHashMap;
     31 
     32 /**
     33  * TODO: This should be better integrated into the system so it doesn't need
     34  * special calls from the activity manager to clear it.
     35  */
     36 public final class AttributeCache {
     37     private static AttributeCache sInstance = null;
     38 
     39     private final Context mContext;
     40     private final WeakHashMap<String, Package> mPackages =
     41             new WeakHashMap<String, Package>();
     42     private final Configuration mConfiguration = new Configuration();
     43 
     44     public final static class Package {
     45         public final Context context;
     46         private final SparseArray<HashMap<int[], Entry>> mMap
     47                 = new SparseArray<HashMap<int[], Entry>>();
     48 
     49         public Package(Context c) {
     50             context = c;
     51         }
     52     }
     53 
     54     public final static class Entry {
     55         public final Context context;
     56         public final TypedArray array;
     57 
     58         public Entry(Context c, TypedArray ta) {
     59             context = c;
     60             array = ta;
     61         }
     62     }
     63 
     64     public static void init(Context context) {
     65         if (sInstance == null) {
     66             sInstance = new AttributeCache(context);
     67         }
     68     }
     69 
     70     public static AttributeCache instance() {
     71         return sInstance;
     72     }
     73 
     74     public AttributeCache(Context context) {
     75         mContext = context;
     76     }
     77 
     78     public void removePackage(String packageName) {
     79         synchronized (this) {
     80             mPackages.remove(packageName);
     81         }
     82     }
     83 
     84     public void updateConfiguration(Configuration config) {
     85         synchronized (this) {
     86             int changes = mConfiguration.updateFrom(config);
     87             if ((changes & ~(ActivityInfo.CONFIG_FONT_SCALE |
     88                     ActivityInfo.CONFIG_KEYBOARD_HIDDEN |
     89                     ActivityInfo.CONFIG_ORIENTATION)) != 0) {
     90                 // The configurations being masked out are ones that commonly
     91                 // change so we don't want flushing the cache... all others
     92                 // will flush the cache.
     93                 mPackages.clear();
     94             }
     95         }
     96     }
     97 
     98     public Entry get(String packageName, int resId, int[] styleable, int userId) {
     99         synchronized (this) {
    100             Package pkg = mPackages.get(packageName);
    101             HashMap<int[], Entry> map = null;
    102             Entry ent = null;
    103             if (pkg != null) {
    104                 map = pkg.mMap.get(resId);
    105                 if (map != null) {
    106                     ent = map.get(styleable);
    107                     if (ent != null) {
    108                         return ent;
    109                     }
    110                 }
    111             } else {
    112                 Context context;
    113                 try {
    114                     context = mContext.createPackageContextAsUser(packageName, 0,
    115                             new UserHandle(userId));
    116                     if (context == null) {
    117                         return null;
    118                     }
    119                 } catch (PackageManager.NameNotFoundException e) {
    120                     return null;
    121                 }
    122                 pkg = new Package(context);
    123                 mPackages.put(packageName, pkg);
    124             }
    125 
    126             if (map == null) {
    127                 map = new HashMap<int[], Entry>();
    128                 pkg.mMap.put(resId, map);
    129             }
    130 
    131             try {
    132                 ent = new Entry(pkg.context,
    133                         pkg.context.obtainStyledAttributes(resId, styleable));
    134                 map.put(styleable, ent);
    135             } catch (Resources.NotFoundException e) {
    136                 return null;
    137             }
    138 
    139             return ent;
    140         }
    141     }
    142 }
    143 
    144