BridgeContext.java revision 74f170f9468d3cf6d7d0ef453320141a3e63571b
1/*
2 * Copyright (C) 2008 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 com.android.layoutlib.bridge;
18
19import com.android.layoutlib.api.ILayoutLog;
20import com.android.layoutlib.api.IProjectCallback;
21import com.android.layoutlib.api.IResourceValue;
22import com.android.layoutlib.api.IStyleResourceValue;
23
24import android.content.BroadcastReceiver;
25import android.content.ComponentName;
26import android.content.ContentResolver;
27import android.content.Context;
28import android.content.Intent;
29import android.content.IntentFilter;
30import android.content.IntentSender;
31import android.content.ServiceConnection;
32import android.content.SharedPreferences;
33import android.content.pm.ApplicationInfo;
34import android.content.pm.PackageManager;
35import android.content.res.AssetManager;
36import android.content.res.Configuration;
37import android.content.res.Resources;
38import android.content.res.TypedArray;
39import android.content.res.Resources.Theme;
40import android.database.DatabaseErrorHandler;
41import android.database.sqlite.SQLiteDatabase;
42import android.database.sqlite.SQLiteDatabase.CursorFactory;
43import android.graphics.Bitmap;
44import android.graphics.drawable.Drawable;
45import android.net.Uri;
46import android.os.Bundle;
47import android.os.Handler;
48import android.os.Looper;
49import android.util.AttributeSet;
50import android.util.DisplayMetrics;
51import android.view.BridgeInflater;
52import android.view.View;
53
54import java.io.File;
55import java.io.FileInputStream;
56import java.io.FileNotFoundException;
57import java.io.FileOutputStream;
58import java.io.IOException;
59import java.io.InputStream;
60import java.util.HashMap;
61import java.util.Map;
62import java.util.TreeMap;
63import java.util.Map.Entry;
64
65/**
66 * Custom implementation of Context to handle non compiled resources.
67 */
68public final class BridgeContext extends Context {
69
70    private final Resources mResources;
71    private final Theme mTheme;
72    private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
73    private final IStyleResourceValue mThemeValues;
74    private final Object mProjectKey;
75    private final Map<String, Map<String, IResourceValue>> mProjectResources;
76    private final Map<String, Map<String, IResourceValue>> mFrameworkResources;
77    private final Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap;
78
79    // maps for dynamically generated id representing style objects (IStyleResourceValue)
80    private Map<Integer, IStyleResourceValue> mDynamicIdToStyleMap;
81    private Map<IStyleResourceValue, Integer> mStyleToDynamicIdMap;
82    private int mDynamicIdGenerator = 0x01030000; // Base id for framework R.style
83
84    // cache for TypedArray generated from IStyleResourceValue object
85    private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache;
86    private BridgeInflater mInflater;
87
88    private final IProjectCallback mProjectCallback;
89    private final ILayoutLog mLogger;
90    private BridgeContentResolver mContentResolver;
91
92    /**
93     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
94     * @param metrics the {@link DisplayMetrics}.
95     * @param themeName The name of the theme to use.
96     * @param projectResources the resources of the project. The map contains (String, map) pairs
97     * where the string is the type of the resource reference used in the layout file, and the
98     * map contains (String, {@link IResourceValue}) pairs where the key is the resource name,
99     * and the value is the resource value.
100     * @param frameworkResources the framework resources. The map contains (String, map) pairs
101     * where the string is the type of the resource reference used in the layout file, and the map
102     * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
103     * value is the resource value.
104     * @param styleInheritanceMap
105     * @param customViewLoader
106     */
107    public BridgeContext(Object projectKey, DisplayMetrics metrics,
108            IStyleResourceValue currentTheme,
109            Map<String, Map<String, IResourceValue>> projectResources,
110            Map<String, Map<String, IResourceValue>> frameworkResources,
111            Map<IStyleResourceValue, IStyleResourceValue> styleInheritanceMap,
112            IProjectCallback customViewLoader, ILayoutLog logger) {
113        mProjectKey = projectKey;
114        mProjectCallback = customViewLoader;
115        mLogger = logger;
116        Configuration config = new Configuration();
117
118        AssetManager assetManager = BridgeAssetManager.initSystem();
119        mResources = BridgeResources.initSystem(
120                this,
121                assetManager,
122                metrics,
123                config,
124                customViewLoader);
125
126        mTheme = mResources.newTheme();
127
128        mThemeValues = currentTheme;
129        mProjectResources = projectResources;
130        mFrameworkResources = frameworkResources;
131        mStyleInheritanceMap = styleInheritanceMap;
132    }
133
134    public void setBridgeInflater(BridgeInflater inflater) {
135        mInflater = inflater;
136    }
137
138    public void addViewKey(View view, Object viewKey) {
139        mViewKeyMap.put(view, viewKey);
140    }
141
142    public Object getViewKey(View view) {
143        return mViewKeyMap.get(view);
144    }
145
146    public Object getProjectKey() {
147        return mProjectKey;
148    }
149
150    public IProjectCallback getProjectCallback() {
151        return mProjectCallback;
152    }
153
154    public ILayoutLog getLogger() {
155        return mLogger;
156    }
157
158    // ------------ Context methods
159
160    @Override
161    public Resources getResources() {
162        return mResources;
163    }
164
165    @Override
166    public Theme getTheme() {
167        return mTheme;
168    }
169
170    @Override
171    public ClassLoader getClassLoader() {
172        return this.getClass().getClassLoader();
173    }
174
175    @Override
176    public Object getSystemService(String service) {
177        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
178            return mInflater;
179        }
180
181        // AutoCompleteTextView and MultiAutoCompleteTextView want a window
182        // service. We don't have any but it's not worth an exception.
183        if (WINDOW_SERVICE.equals(service)) {
184            return null;
185        }
186
187        throw new UnsupportedOperationException("Unsupported Service: " + service);
188    }
189
190
191    @Override
192    public final TypedArray obtainStyledAttributes(int[] attrs) {
193        return createStyleBasedTypedArray(mThemeValues, attrs);
194    }
195
196    @Override
197    public final TypedArray obtainStyledAttributes(int resid, int[] attrs)
198            throws Resources.NotFoundException {
199        // get the IStyleResourceValue based on the resId;
200        IStyleResourceValue style = getStyleByDynamicId(resid);
201
202        if (style == null) {
203            throw new Resources.NotFoundException();
204        }
205
206        if (mTypedArrayCache == null) {
207            mTypedArrayCache = new HashMap<int[], Map<Integer,TypedArray>>();
208
209            Map<Integer, TypedArray> map = new HashMap<Integer, TypedArray>();
210            mTypedArrayCache.put(attrs, map);
211
212            BridgeTypedArray ta = createStyleBasedTypedArray(style, attrs);
213            map.put(resid, ta);
214
215            return ta;
216        }
217
218        // get the 2nd map
219        Map<Integer, TypedArray> map = mTypedArrayCache.get(attrs);
220        if (map == null) {
221            map = new HashMap<Integer, TypedArray>();
222            mTypedArrayCache.put(attrs, map);
223        }
224
225        // get the array from the 2nd map
226        TypedArray ta = map.get(resid);
227
228        if (ta == null) {
229            ta = createStyleBasedTypedArray(style, attrs);
230            map.put(resid, ta);
231        }
232
233        return ta;
234    }
235
236    @Override
237    public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
238        return obtainStyledAttributes(set, attrs, 0, 0);
239    }
240
241    @Override
242    public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
243            int defStyleAttr, int defStyleRes) {
244
245        // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
246        BridgeXmlBlockParser parser = null;
247        if (set instanceof BridgeXmlBlockParser) {
248            parser = (BridgeXmlBlockParser)set;
249        } else {
250            // reall this should not be happening since its instantiated in Bridge
251            mLogger.error("Parser is not a BridgeXmlBlockParser!");
252            return null;
253        }
254
255        boolean[] frameworkAttributes = new boolean[1];
256        TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes);
257
258        BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length,
259                parser.isPlatformFile());
260
261        // resolve the defStyleAttr value into a IStyleResourceValue
262        IStyleResourceValue defStyleValues = null;
263
264        // look for a custom style.
265        String customStyle = parser.getAttributeValue(null /* namespace*/, "style");
266        if (customStyle != null) {
267            IResourceValue item = findResValue(customStyle);
268
269            if (item instanceof IStyleResourceValue) {
270                defStyleValues = (IStyleResourceValue)item;
271            }
272        }
273
274        if (defStyleValues == null && defStyleAttr != 0) {
275            // get the name from the int.
276            String defStyleName = searchAttr(defStyleAttr);
277
278            // look for the style in the current theme, and its parent:
279            if (mThemeValues != null) {
280                IResourceValue item = findItemInStyle(mThemeValues, defStyleName);
281
282                if (item != null) {
283                    // item is a reference to a style entry. Search for it.
284                    item = findResValue(item.getValue());
285
286                    if (item instanceof IStyleResourceValue) {
287                        defStyleValues = (IStyleResourceValue)item;
288                    }
289                } else {
290                    // TODO: log the error properly
291                    System.out.println("Failed to find defStyle: " + defStyleName);
292                }
293            }
294        }
295
296        if (defStyleRes != 0) {
297            // FIXME: See what we need to do with this.
298            throw new UnsupportedOperationException();
299        }
300
301        String namespace = BridgeConstants.NS_RESOURCES;
302        if (frameworkAttributes[0] == false) {
303            // need to use the application namespace
304            namespace = mProjectCallback.getNamespace();
305        }
306
307        if (styleNameMap != null) {
308            for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
309                int index = styleAttribute.getKey().intValue();
310
311                String name = styleAttribute.getValue();
312                String value = parser.getAttributeValue(namespace, name);
313
314                // if there's no direct value for this attribute in the XML, we look for default
315                // values in the widget defStyle, and then in the theme.
316                if (value == null) {
317                    IResourceValue resValue = null;
318
319                    // look for the value in the defStyle first (and its parent if needed)
320                    if (defStyleValues != null) {
321                        resValue = findItemInStyle(defStyleValues, name);
322                    }
323
324                    // if the item is not present in the defStyle, we look in the main theme (and
325                    // its parent themes)
326                    if (resValue == null && mThemeValues != null) {
327                        resValue = findItemInStyle(mThemeValues, name);
328                    }
329
330                    // if we found a value, we make sure this doesn't reference another value.
331                    // So we resolve it.
332                    if (resValue != null) {
333                        resValue = resolveResValue(resValue);
334                    }
335
336                    ta.bridgeSetValue(index, name, resValue);
337                } else {
338                    // there is a value in the XML, but we need to resolve it in case it's
339                    // referencing another resource or a theme value.
340                    ta.bridgeSetValue(index, name, resolveValue(null, name, value));
341                }
342            }
343        }
344
345        ta.sealArray();
346
347        return ta;
348    }
349
350    @Override
351    public Looper getMainLooper() {
352        return Looper.myLooper();
353    }
354
355
356    // ------------- private new methods
357
358    /**
359     * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
360     * values found in the given style.
361     * @see #obtainStyledAttributes(int, int[])
362     */
363    private BridgeTypedArray createStyleBasedTypedArray(IStyleResourceValue style, int[] attrs)
364            throws Resources.NotFoundException {
365        TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, null);
366
367        BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length,
368                false /* platformResourceFlag */);
369
370        // loop through all the values in the style map, and init the TypedArray with
371        // the style we got from the dynamic id
372        for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
373            int index = styleAttribute.getKey().intValue();
374
375            String name = styleAttribute.getValue();
376
377            // get the value from the style, or its parent styles.
378            IResourceValue resValue = findItemInStyle(style, name);
379
380            // resolve it to make sure there are no references left.
381            ta.bridgeSetValue(index, name, resolveResValue(resValue));
382        }
383
384        ta.sealArray();
385
386        return ta;
387    }
388
389
390    /**
391     * Resolves the value of a resource, if the value references a theme or resource value.
392     * <p/>
393     * This method ensures that it returns a {@link IResourceValue} object that does not
394     * reference another resource.
395     * If the resource cannot be resolved, it returns <code>null</code>.
396     * <p/>
397     * If a value that does not need to be resolved is given, the method will return a new
398     * instance of IResourceValue that contains the input value.
399     *
400     * @param type the type of the resource
401     * @param name the name of the attribute containing this value.
402     * @param value the resource value, or reference to resolve
403     * @return the resolved resource value or <code>null</code> if it failed to resolve it.
404     */
405    private IResourceValue resolveValue(String type, String name, String value) {
406        if (value == null) {
407            return null;
408        }
409
410        // get the IResourceValue referenced by this value
411        IResourceValue resValue = findResValue(value);
412
413        // if resValue is null, but value is not null, this means it was not a reference.
414        // we return the name/value wrapper in a IResourceValue
415        if (resValue == null) {
416            return new ResourceValue(type, name, value);
417        }
418
419        // we resolved a first reference, but we need to make sure this isn't a reference also.
420        return resolveResValue(resValue);
421    }
422
423    /**
424     * Returns the {@link IResourceValue} referenced by the value of <var>value</var>.
425     * <p/>
426     * This method ensures that it returns a {@link IResourceValue} object that does not
427     * reference another resource.
428     * If the resource cannot be resolved, it returns <code>null</code>.
429     * <p/>
430     * If a value that does not need to be resolved is given, the method will return the input
431     * value.
432     *
433     * @param value the value containing the reference to resolve.
434     * @return a {@link IResourceValue} object or <code>null</code>
435     */
436    IResourceValue resolveResValue(IResourceValue value) {
437        if (value == null) {
438            return null;
439        }
440
441        // if the resource value is a style, we simply return it.
442        if (value instanceof IStyleResourceValue) {
443            return value;
444        }
445
446        // else attempt to find another IResourceValue referenced by this one.
447        IResourceValue resolvedValue = findResValue(value.getValue());
448
449        // if the value did not reference anything, then we simply return the input value
450        if (resolvedValue == null) {
451            return value;
452        }
453
454        // otherwise, we attempt to resolve this new value as well
455        return resolveResValue(resolvedValue);
456    }
457
458    /**
459     * Searches for, and returns a {@link IResourceValue} by its reference.
460     * <p/>
461     * The reference format can be:
462     * <pre>@resType/resName</pre>
463     * <pre>@android:resType/resName</pre>
464     * <pre>@resType/android:resName</pre>
465     * <pre>?resType/resName</pre>
466     * <pre>?android:resType/resName</pre>
467     * <pre>?resType/android:resName</pre>
468     * Any other string format will return <code>null</code>.
469     * <p/>
470     * The actual format of a reference is <pre>@[namespace:]resType/resName</pre> but this method
471     * only support the android namespace.
472     *
473     * @param reference the resource reference to search for.
474     * @return a {@link IResourceValue} or <code>null</code>.
475     */
476    IResourceValue findResValue(String reference) {
477        if (reference == null) {
478            return null;
479        }
480        if (reference.startsWith(BridgeConstants.PREFIX_THEME_REF)) {
481            // no theme? no need to go further!
482            if (mThemeValues == null) {
483                return null;
484            }
485
486            boolean frameworkOnly = false;
487
488            // eleminate the prefix from the string
489            if (reference.startsWith(BridgeConstants.PREFIX_ANDROID_THEME_REF)) {
490                frameworkOnly = true;
491                reference = reference.substring(BridgeConstants.PREFIX_ANDROID_THEME_REF.length());
492            } else {
493                reference = reference.substring(BridgeConstants.PREFIX_THEME_REF.length());
494            }
495
496            // at this point, value can contain type/name (drawable/foo for instance).
497            // split it to make sure.
498            String[] segments = reference.split("\\/");
499
500            // we look for the referenced item name.
501            String referenceName = null;
502
503            if (segments.length == 2) {
504                // there was a resType in the reference. If it's attr, we ignore it
505                // else, we assert for now.
506                if (BridgeConstants.RES_ATTR.equals(segments[0])) {
507                    referenceName = segments[1];
508                } else {
509                    // At this time, no support for ?type/name where type is not "attr"
510                    return null;
511                }
512            } else {
513                // it's just an item name.
514                referenceName = segments[0];
515            }
516
517            // now we look for android: in the referenceName in order to support format
518            // such as: ?attr/android:name
519            if (referenceName.startsWith(BridgeConstants.PREFIX_ANDROID)) {
520                frameworkOnly = true;
521                referenceName = referenceName.substring(BridgeConstants.PREFIX_ANDROID.length());
522            }
523
524            // Now look for the item in the theme, starting with the current one.
525            if (frameworkOnly) {
526                // FIXME for now we do the same as if it didn't specify android:
527                return findItemInStyle(mThemeValues, referenceName);
528            }
529
530            return findItemInStyle(mThemeValues, referenceName);
531        } else if (reference.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) {
532            boolean frameworkOnly = false;
533
534            // check for the specific null reference value.
535            if (BridgeConstants.REFERENCE_NULL.equals(reference)) {
536                return null;
537            }
538
539            // Eliminate the prefix from the string.
540            if (reference.startsWith(BridgeConstants.PREFIX_ANDROID_RESOURCE_REF)) {
541                frameworkOnly = true;
542                reference = reference.substring(
543                        BridgeConstants.PREFIX_ANDROID_RESOURCE_REF.length());
544            } else {
545                reference = reference.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
546            }
547
548            // at this point, value contains type/[android:]name (drawable/foo for instance)
549            String[] segments = reference.split("\\/");
550
551            // now we look for android: in the resource name in order to support format
552            // such as: @drawable/android:name
553            if (segments[1].startsWith(BridgeConstants.PREFIX_ANDROID)) {
554                frameworkOnly = true;
555                segments[1] = segments[1].substring(BridgeConstants.PREFIX_ANDROID.length());
556            }
557
558            return findResValue(segments[0], segments[1], frameworkOnly);
559        }
560
561        // Looks like the value didn't reference anything. Return null.
562        return null;
563    }
564
565    /**
566     * Searches for, and returns a {@link IResourceValue} by its name, and type.
567     * @param resType the type of the resource
568     * @param resName  the name of the resource
569     * @param frameworkOnly if <code>true</code>, the method does not search in the
570     * project resources
571     */
572    private IResourceValue findResValue(String resType, String resName, boolean frameworkOnly) {
573        // map of IResouceValue for the given type
574        Map<String, IResourceValue> typeMap;
575
576        // if allowed, search in the project resources first.
577        if (frameworkOnly == false) {
578            typeMap = mProjectResources.get(resType);
579            if (typeMap != null) {
580                IResourceValue item = typeMap.get(resName);
581                if (item != null) {
582                    return item;
583                }
584            }
585        }
586
587        // now search in the framework resources.
588        typeMap = mFrameworkResources.get(resType);
589        if (typeMap != null) {
590            IResourceValue item = typeMap.get(resName);
591            if (item != null) {
592                return item;
593            }
594        }
595
596        // didn't find the resource anywhere.
597        return null;
598    }
599
600    /**
601     * Returns a framework resource by type and name. The returned resource is resolved.
602     * @param resourceType the type of the resource
603     * @param resourceName the name of the resource
604     */
605    public IResourceValue getFrameworkResource(String resourceType, String resourceName) {
606        return getResource(resourceType, resourceName, mFrameworkResources);
607    }
608
609    /**
610     * Returns a project resource by type and name. The returned resource is resolved.
611     * @param resourceType the type of the resource
612     * @param resourceName the name of the resource
613     */
614    public IResourceValue getProjectResource(String resourceType, String resourceName) {
615        return getResource(resourceType, resourceName, mProjectResources);
616    }
617
618    IResourceValue getResource(String resourceType, String resourceName,
619            Map<String, Map<String, IResourceValue>> resourceRepository) {
620        Map<String, IResourceValue> typeMap = resourceRepository.get(resourceType);
621        if (typeMap != null) {
622            IResourceValue item = typeMap.get(resourceName);
623            if (item != null) {
624                item = resolveResValue(item);
625                return item;
626            }
627        }
628
629        // didn't find the resource anywhere.
630        return null;
631
632    }
633
634    /**
635     * Returns the {@link IResourceValue} matching a given name in a given style. If the
636     * item is not directly available in the style, the method looks in its parent style.
637     * @param style the style to search in
638     * @param itemName the name of the item to search for.
639     * @return the {@link IResourceValue} object or <code>null</code>
640     */
641    IResourceValue findItemInStyle(IStyleResourceValue style, String itemName) {
642        IResourceValue item = style.findItem(itemName);
643
644        // if we didn't find it, we look in the parent style (if applicable)
645        if (item == null && mStyleInheritanceMap != null) {
646            IStyleResourceValue parentStyle = mStyleInheritanceMap.get(style);
647            if (parentStyle != null) {
648                return findItemInStyle(parentStyle, itemName);
649            }
650        }
651
652        return item;
653    }
654
655    /**
656     * The input int[] attrs is one of com.android.internal.R.styleable fields where the name
657     * of the field is the style being referenced and the array contains one index per attribute.
658     * <p/>
659     * searchAttrs() finds all the names of the attributes referenced so for example if
660     * attrs == com.android.internal.R.styleable.View, this returns the list of the "xyz" where
661     * there's a field com.android.internal.R.styleable.View_xyz and the field value is the index
662     * that is used to reference the attribute later in the TypedArray.
663     *
664     * @param attrs An attribute array reference given to obtainStyledAttributes.
665     * @return A sorted map Attribute-Value to Attribute-Name for all attributes declared by the
666     *         attribute array. Returns null if nothing is found.
667     */
668    private TreeMap<Integer,String> searchAttrs(int[] attrs, boolean[] outFrameworkFlag) {
669        // get the name of the array from the framework resources
670        String arrayName = Bridge.resolveResourceValue(attrs);
671        if (arrayName != null) {
672            // if we found it, get the name of each of the int in the array.
673            TreeMap<Integer,String> attributes = new TreeMap<Integer, String>();
674            for (int i = 0 ; i < attrs.length ; i++) {
675                String[] info = Bridge.resolveResourceValue(attrs[i]);
676                if (info != null) {
677                    attributes.put(i, info[0]);
678                } else {
679                    // FIXME Not sure what we should be doing here...
680                    attributes.put(i, null);
681                }
682            }
683
684            if (outFrameworkFlag != null) {
685                outFrameworkFlag[0] = true;
686            }
687
688            return attributes;
689        }
690
691        // if the name was not found in the framework resources, look in the project
692        // resources
693        arrayName = mProjectCallback.resolveResourceValue(attrs);
694        if (arrayName != null) {
695            TreeMap<Integer,String> attributes = new TreeMap<Integer, String>();
696            for (int i = 0 ; i < attrs.length ; i++) {
697                String[] info = mProjectCallback.resolveResourceValue(attrs[i]);
698                if (info != null) {
699                    attributes.put(i, info[0]);
700                } else {
701                    // FIXME Not sure what we should be doing here...
702                    attributes.put(i, null);
703                }
704            }
705
706            if (outFrameworkFlag != null) {
707                outFrameworkFlag[0] = false;
708            }
709
710            return attributes;
711        }
712
713        return null;
714    }
715
716    /**
717     * Searches for the attribute referenced by its internal id.
718     *
719     * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
720     * @return The unique name of the attribute, if found, e.g. "buttonStyle". Returns null
721     *         if nothing is found.
722     */
723    public String searchAttr(int attr) {
724        String[] info = Bridge.resolveResourceValue(attr);
725        if (info != null) {
726            return info[0];
727        }
728
729        info = mProjectCallback.resolveResourceValue(attr);
730        if (info != null) {
731            return info[0];
732        }
733
734        return null;
735    }
736
737    int getDynamicIdByStyle(IStyleResourceValue resValue) {
738        if (mDynamicIdToStyleMap == null) {
739            // create the maps.
740            mDynamicIdToStyleMap = new HashMap<Integer, IStyleResourceValue>();
741            mStyleToDynamicIdMap = new HashMap<IStyleResourceValue, Integer>();
742        }
743
744        // look for an existing id
745        Integer id = mStyleToDynamicIdMap.get(resValue);
746
747        if (id == null) {
748            // generate a new id
749            id = Integer.valueOf(++mDynamicIdGenerator);
750
751            // and add it to the maps.
752            mDynamicIdToStyleMap.put(id, resValue);
753            mStyleToDynamicIdMap.put(resValue, id);
754        }
755
756        return id;
757    }
758
759    private IStyleResourceValue getStyleByDynamicId(int i) {
760        if (mDynamicIdToStyleMap != null) {
761            return mDynamicIdToStyleMap.get(i);
762        }
763
764        return null;
765    }
766
767    int getFrameworkIdValue(String idName, int defValue) {
768        Integer value = Bridge.getResourceValue(BridgeConstants.RES_ID, idName);
769        if (value != null) {
770            return value.intValue();
771        }
772
773        return defValue;
774    }
775
776    int getProjectIdValue(String idName, int defValue) {
777        if (mProjectCallback != null) {
778            Integer value = mProjectCallback.getResourceValue(BridgeConstants.RES_ID, idName);
779            if (value != null) {
780                return value.intValue();
781            }
782        }
783
784        return defValue;
785    }
786
787    //------------ NOT OVERRIDEN --------------------
788
789    @Override
790    public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
791        // TODO Auto-generated method stub
792        return false;
793    }
794
795    @Override
796    public int checkCallingOrSelfPermission(String arg0) {
797        // TODO Auto-generated method stub
798        return 0;
799    }
800
801    @Override
802    public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
803        // TODO Auto-generated method stub
804        return 0;
805    }
806
807    @Override
808    public int checkCallingPermission(String arg0) {
809        // TODO Auto-generated method stub
810        return 0;
811    }
812
813    @Override
814    public int checkCallingUriPermission(Uri arg0, int arg1) {
815        // TODO Auto-generated method stub
816        return 0;
817    }
818
819    @Override
820    public int checkPermission(String arg0, int arg1, int arg2) {
821        // TODO Auto-generated method stub
822        return 0;
823    }
824
825    @Override
826    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
827        // TODO Auto-generated method stub
828        return 0;
829    }
830
831    @Override
832    public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
833            int arg4, int arg5) {
834        // TODO Auto-generated method stub
835        return 0;
836    }
837
838    @Override
839    public void clearWallpaper() {
840        // TODO Auto-generated method stub
841
842    }
843
844    @Override
845    public Context createPackageContext(String arg0, int arg1) {
846        // TODO Auto-generated method stub
847        return null;
848    }
849
850    @Override
851    public String[] databaseList() {
852        // TODO Auto-generated method stub
853        return null;
854    }
855
856    @Override
857    public boolean deleteDatabase(String arg0) {
858        // TODO Auto-generated method stub
859        return false;
860    }
861
862    @Override
863    public boolean deleteFile(String arg0) {
864        // TODO Auto-generated method stub
865        return false;
866    }
867
868    @Override
869    public void enforceCallingOrSelfPermission(String arg0, String arg1) {
870        // TODO Auto-generated method stub
871
872    }
873
874    @Override
875    public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
876            String arg2) {
877        // TODO Auto-generated method stub
878
879    }
880
881    @Override
882    public void enforceCallingPermission(String arg0, String arg1) {
883        // TODO Auto-generated method stub
884
885    }
886
887    @Override
888    public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
889        // TODO Auto-generated method stub
890
891    }
892
893    @Override
894    public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
895        // TODO Auto-generated method stub
896
897    }
898
899    @Override
900    public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
901            String arg4) {
902        // TODO Auto-generated method stub
903
904    }
905
906    @Override
907    public void enforceUriPermission(Uri arg0, String arg1, String arg2,
908            int arg3, int arg4, int arg5, String arg6) {
909        // TODO Auto-generated method stub
910
911    }
912
913    @Override
914    public String[] fileList() {
915        // TODO Auto-generated method stub
916        return null;
917    }
918
919    @Override
920    public AssetManager getAssets() {
921        // TODO Auto-generated method stub
922        return null;
923    }
924
925    @Override
926    public File getCacheDir() {
927        // TODO Auto-generated method stub
928        return null;
929    }
930
931    @Override
932    public File getExternalCacheDir() {
933        // TODO Auto-generated method stub
934        return null;
935    }
936
937    @Override
938    public ContentResolver getContentResolver() {
939        if (mContentResolver == null) {
940            mContentResolver = new BridgeContentResolver(this);
941        }
942        return mContentResolver;
943    }
944
945    @Override
946    public File getDatabasePath(String arg0) {
947        // TODO Auto-generated method stub
948        return null;
949    }
950
951    @Override
952    public File getDir(String arg0, int arg1) {
953        // TODO Auto-generated method stub
954        return null;
955    }
956
957    @Override
958    public File getFileStreamPath(String arg0) {
959        // TODO Auto-generated method stub
960        return null;
961    }
962
963    @Override
964    public File getFilesDir() {
965        // TODO Auto-generated method stub
966        return null;
967    }
968
969    @Override
970    public File getExternalFilesDir(String type) {
971        // TODO Auto-generated method stub
972        return null;
973    }
974
975    @Override
976    public String getPackageCodePath() {
977        // TODO Auto-generated method stub
978        return null;
979    }
980
981    @Override
982    public PackageManager getPackageManager() {
983        // TODO Auto-generated method stub
984        return null;
985    }
986
987    @Override
988    public String getPackageName() {
989        // TODO Auto-generated method stub
990        return null;
991    }
992
993    @Override
994    public ApplicationInfo getApplicationInfo() {
995        // TODO Auto-generated method stub
996        return null;
997    }
998
999    @Override
1000    public String getPackageResourcePath() {
1001        // TODO Auto-generated method stub
1002        return null;
1003    }
1004
1005    @Override
1006    public File getSharedPrefsFile(String name) {
1007        // TODO Auto-generated method stub
1008        return null;
1009    }
1010
1011    @Override
1012    public SharedPreferences getSharedPreferences(String arg0, int arg1) {
1013        // TODO Auto-generated method stub
1014        return null;
1015    }
1016
1017    @Override
1018    public Drawable getWallpaper() {
1019        // TODO Auto-generated method stub
1020        return null;
1021    }
1022
1023    @Override
1024    public int getWallpaperDesiredMinimumWidth() {
1025        return -1;
1026    }
1027
1028    @Override
1029    public int getWallpaperDesiredMinimumHeight() {
1030        return -1;
1031    }
1032
1033    @Override
1034    public void grantUriPermission(String arg0, Uri arg1, int arg2) {
1035        // TODO Auto-generated method stub
1036
1037    }
1038
1039    @SuppressWarnings("unused")
1040    @Override
1041    public FileInputStream openFileInput(String arg0)
1042            throws FileNotFoundException {
1043        // TODO Auto-generated method stub
1044        return null;
1045    }
1046
1047    @SuppressWarnings("unused")
1048    @Override
1049    public FileOutputStream openFileOutput(String arg0, int arg1)
1050            throws FileNotFoundException {
1051        // TODO Auto-generated method stub
1052        return null;
1053    }
1054
1055    @Override
1056    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
1057            CursorFactory arg2) {
1058        // TODO Auto-generated method stub
1059        return null;
1060    }
1061
1062    @Override
1063    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
1064            CursorFactory arg2, DatabaseErrorHandler arg3) {
1065        // TODO Auto-generated method stub
1066        return null;
1067    }
1068
1069    @Override
1070    public Drawable peekWallpaper() {
1071        // TODO Auto-generated method stub
1072        return null;
1073    }
1074
1075    @Override
1076    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
1077        // TODO Auto-generated method stub
1078        return null;
1079    }
1080
1081    @Override
1082    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
1083            String arg2, Handler arg3) {
1084        // TODO Auto-generated method stub
1085        return null;
1086    }
1087
1088    @Override
1089    public void removeStickyBroadcast(Intent arg0) {
1090        // TODO Auto-generated method stub
1091
1092    }
1093
1094    @Override
1095    public void revokeUriPermission(Uri arg0, int arg1) {
1096        // TODO Auto-generated method stub
1097
1098    }
1099
1100    @Override
1101    public void sendBroadcast(Intent arg0) {
1102        // TODO Auto-generated method stub
1103
1104    }
1105
1106    @Override
1107    public void sendBroadcast(Intent arg0, String arg1) {
1108        // TODO Auto-generated method stub
1109
1110    }
1111
1112    @Override
1113    public void sendOrderedBroadcast(Intent arg0, String arg1) {
1114        // TODO Auto-generated method stub
1115
1116    }
1117
1118    @Override
1119    public void sendOrderedBroadcast(Intent arg0, String arg1,
1120            BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
1121            Bundle arg6) {
1122        // TODO Auto-generated method stub
1123
1124    }
1125
1126    @Override
1127    public void sendStickyBroadcast(Intent arg0) {
1128        // TODO Auto-generated method stub
1129
1130    }
1131
1132    @Override
1133    public void sendStickyOrderedBroadcast(Intent intent,
1134            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
1135           Bundle initialExtras) {
1136        // TODO Auto-generated method stub
1137    }
1138
1139    @Override
1140    public void setTheme(int arg0) {
1141        // TODO Auto-generated method stub
1142
1143    }
1144
1145    @SuppressWarnings("unused")
1146    @Override
1147    public void setWallpaper(Bitmap arg0) throws IOException {
1148        // TODO Auto-generated method stub
1149
1150    }
1151
1152    @SuppressWarnings("unused")
1153    @Override
1154    public void setWallpaper(InputStream arg0) throws IOException {
1155        // TODO Auto-generated method stub
1156
1157    }
1158
1159    @Override
1160    public void startActivity(Intent arg0) {
1161        // TODO Auto-generated method stub
1162
1163    }
1164
1165    @Override
1166    public void startIntentSender(IntentSender intent,
1167            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
1168            throws IntentSender.SendIntentException {
1169        // TODO Auto-generated method stub
1170    }
1171
1172    @Override
1173    public boolean startInstrumentation(ComponentName arg0, String arg1,
1174            Bundle arg2) {
1175        // TODO Auto-generated method stub
1176        return false;
1177    }
1178
1179    @Override
1180    public ComponentName startService(Intent arg0) {
1181        // TODO Auto-generated method stub
1182        return null;
1183    }
1184
1185    @Override
1186    public boolean stopService(Intent arg0) {
1187        // TODO Auto-generated method stub
1188        return false;
1189    }
1190
1191    @Override
1192    public void unbindService(ServiceConnection arg0) {
1193        // TODO Auto-generated method stub
1194
1195    }
1196
1197    @Override
1198    public void unregisterReceiver(BroadcastReceiver arg0) {
1199        // TODO Auto-generated method stub
1200
1201    }
1202
1203    @Override
1204    public Context getApplicationContext() {
1205        throw new UnsupportedOperationException();
1206    }
1207}
1208