BridgeContext.java revision 2c1ba9a961d4f96c26df260ee437655ad9e7c03e
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.android;
18
19import com.android.SdkConstants;
20import com.android.ide.common.rendering.api.AssetRepository;
21import com.android.ide.common.rendering.api.ILayoutPullParser;
22import com.android.ide.common.rendering.api.LayoutLog;
23import com.android.ide.common.rendering.api.LayoutlibCallback;
24import com.android.ide.common.rendering.api.RenderResources;
25import com.android.ide.common.rendering.api.ResourceReference;
26import com.android.ide.common.rendering.api.ResourceValue;
27import com.android.ide.common.rendering.api.StyleResourceValue;
28import com.android.layoutlib.bridge.Bridge;
29import com.android.layoutlib.bridge.BridgeConstants;
30import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
31import com.android.layoutlib.bridge.impl.ParserFactory;
32import com.android.layoutlib.bridge.impl.Stack;
33import com.android.resources.ResourceType;
34import com.android.util.Pair;
35
36import org.xmlpull.v1.XmlPullParser;
37import org.xmlpull.v1.XmlPullParserException;
38
39import android.annotation.NonNull;
40import android.annotation.Nullable;
41import android.content.BroadcastReceiver;
42import android.content.ComponentName;
43import android.content.ContentResolver;
44import android.content.Context;
45import android.content.ContextWrapper;
46import android.content.Intent;
47import android.content.IntentFilter;
48import android.content.IntentSender;
49import android.content.ServiceConnection;
50import android.content.SharedPreferences;
51import android.content.pm.ApplicationInfo;
52import android.content.pm.PackageManager;
53import android.content.res.AssetManager;
54import android.content.res.BridgeAssetManager;
55import android.content.res.BridgeResources;
56import android.content.res.BridgeTypedArray;
57import android.content.res.Configuration;
58import android.content.res.Resources;
59import android.content.res.Resources.Theme;
60import android.database.DatabaseErrorHandler;
61import android.database.sqlite.SQLiteDatabase;
62import android.database.sqlite.SQLiteDatabase.CursorFactory;
63import android.graphics.Bitmap;
64import android.graphics.drawable.Drawable;
65import android.hardware.display.DisplayManager;
66import android.net.Uri;
67import android.os.Build.VERSION_CODES;
68import android.os.Bundle;
69import android.os.Handler;
70import android.os.IBinder;
71import android.os.IInterface;
72import android.os.Looper;
73import android.os.Parcel;
74import android.os.PowerManager;
75import android.os.RemoteException;
76import android.os.ResultReceiver;
77import android.os.UserHandle;
78import android.util.AttributeSet;
79import android.util.DisplayMetrics;
80import android.util.TypedValue;
81import android.view.BridgeInflater;
82import android.view.Display;
83import android.view.DisplayAdjustments;
84import android.view.LayoutInflater;
85import android.view.View;
86import android.view.ViewGroup;
87import android.view.WindowManager;
88import android.view.accessibility.AccessibilityManager;
89import android.view.textservice.TextServicesManager;
90
91import java.io.File;
92import java.io.FileDescriptor;
93import java.io.FileInputStream;
94import java.io.FileNotFoundException;
95import java.io.FileOutputStream;
96import java.io.IOException;
97import java.io.InputStream;
98import java.util.ArrayList;
99import java.util.HashMap;
100import java.util.IdentityHashMap;
101import java.util.List;
102import java.util.Map;
103
104import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
105
106/**
107 * Custom implementation of Context/Activity to handle non compiled resources.
108 */
109@SuppressWarnings("deprecation")  // For use of Pair.
110public final class BridgeContext extends Context {
111
112    /** The map adds cookies to each view so that IDE can link xml tags to views. */
113    private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
114    /**
115     * In some cases, when inflating an xml, some objects are created. Then later, the objects are
116     * converted to views. This map stores the mapping from objects to cookies which can then be
117     * used to populate the mViewKeyMap.
118     */
119    private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<Object, Object>();
120    private final BridgeAssetManager mAssets;
121    private Resources mSystemResources;
122    private final Object mProjectKey;
123    private final DisplayMetrics mMetrics;
124    private final RenderResources mRenderResources;
125    private final Configuration mConfig;
126    private final ApplicationInfo mApplicationInfo;
127    private final LayoutlibCallback mLayoutlibCallback;
128    private final WindowManager mWindowManager;
129    private final DisplayManager mDisplayManager;
130    private final HashMap<View, Integer> mScrollYPos = new HashMap<View, Integer>();
131
132    private Resources.Theme mTheme;
133
134    private final Map<Object, Map<String, String>> mDefaultPropMaps =
135        new IdentityHashMap<Object, Map<String,String>>();
136
137    // maps for dynamically generated id representing style objects (StyleResourceValue)
138    @Nullable
139    private Map<Integer, StyleResourceValue> mDynamicIdToStyleMap;
140    private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
141    private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
142
143    // cache for TypedArray generated from StyleResourceValue object
144    private Map<int[], Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>
145            mTypedArrayCache;
146    private BridgeInflater mBridgeInflater;
147
148    private BridgeContentResolver mContentResolver;
149
150    private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>();
151    private SharedPreferences mSharedPreferences;
152    private ClassLoader mClassLoader;
153    private IBinder mBinder;
154    private PackageManager mPackageManager;
155
156
157    /**
158     * Some applications that target both pre API 17 and post API 17, set the newer attrs to
159     * reference the older ones. For example, android:paddingStart will resolve to
160     * android:paddingLeft. This way the apps need to only define paddingLeft at any other place.
161     * This a map from value to attribute name. Warning for missing references shouldn't be logged
162     * if value and attr name pair is the same as an entry in this map.
163     */
164    private static Map<String, String> RTL_ATTRS = new HashMap<String, String>(10);
165
166    static {
167        RTL_ATTRS.put("?android:attr/paddingLeft", "paddingStart");
168        RTL_ATTRS.put("?android:attr/paddingRight", "paddingEnd");
169        RTL_ATTRS.put("?android:attr/layout_marginLeft", "layout_marginStart");
170        RTL_ATTRS.put("?android:attr/layout_marginRight", "layout_marginEnd");
171        RTL_ATTRS.put("?android:attr/layout_toLeft", "layout_toStartOf");
172        RTL_ATTRS.put("?android:attr/layout_toRight", "layout_toEndOf");
173        RTL_ATTRS.put("?android:attr/layout_alignParentLeft", "layout_alignParentStart");
174        RTL_ATTRS.put("?android:attr/layout_alignParentRight", "layout_alignParentEnd");
175        RTL_ATTRS.put("?android:attr/drawableLeft", "drawableStart");
176        RTL_ATTRS.put("?android:attr/drawableRight", "drawableEnd");
177    }
178
179    /**
180     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
181     * @param metrics the {@link DisplayMetrics}.
182     * @param renderResources the configured resources (both framework and projects) for this
183     * render.
184     * @param config the Configuration object for this render.
185     * @param targetSdkVersion the targetSdkVersion of the application.
186     */
187    public BridgeContext(Object projectKey, DisplayMetrics metrics,
188            RenderResources renderResources,
189            AssetRepository assets,
190            LayoutlibCallback layoutlibCallback,
191            Configuration config,
192            int targetSdkVersion,
193            boolean hasRtlSupport) {
194        mProjectKey = projectKey;
195        mMetrics = metrics;
196        mLayoutlibCallback = layoutlibCallback;
197
198        mRenderResources = renderResources;
199        mConfig = config;
200        AssetManager systemAssetManager = AssetManager.getSystem();
201        if (systemAssetManager instanceof BridgeAssetManager) {
202            mAssets = (BridgeAssetManager) systemAssetManager;
203        } else {
204            throw new AssertionError("Creating BridgeContext without initializing Bridge");
205        }
206        mAssets.setAssetRepository(assets);
207
208        mApplicationInfo = new ApplicationInfo();
209        mApplicationInfo.targetSdkVersion = targetSdkVersion;
210        if (hasRtlSupport) {
211            mApplicationInfo.flags = mApplicationInfo.flags | ApplicationInfo.FLAG_SUPPORTS_RTL;
212        }
213
214        mWindowManager = new WindowManagerImpl(mMetrics);
215        mDisplayManager = new DisplayManager(this);
216    }
217
218    /**
219     * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
220     * {@link DisplayMetrics}, {@link Configuration}, and {@link LayoutlibCallback}.
221     *
222     * @see #disposeResources()
223     */
224    public void initResources() {
225        AssetManager assetManager = AssetManager.getSystem();
226
227        mSystemResources = BridgeResources.initSystem(
228                this,
229                assetManager,
230                mMetrics,
231                mConfig,
232                mLayoutlibCallback);
233        mTheme = mSystemResources.newTheme();
234    }
235
236    /**
237     * Disposes the {@link Resources} singleton.
238     */
239    public void disposeResources() {
240        BridgeResources.disposeSystem();
241    }
242
243    public void setBridgeInflater(BridgeInflater inflater) {
244        mBridgeInflater = inflater;
245    }
246
247    public void addViewKey(View view, Object viewKey) {
248        mViewKeyMap.put(view, viewKey);
249    }
250
251    public Object getViewKey(View view) {
252        return mViewKeyMap.get(view);
253    }
254
255    public void addCookie(Object o, Object cookie) {
256        mViewKeyHelpMap.put(o, cookie);
257    }
258
259    public Object getCookie(Object o) {
260        return mViewKeyHelpMap.get(o);
261    }
262
263    public Object getProjectKey() {
264        return mProjectKey;
265    }
266
267    public DisplayMetrics getMetrics() {
268        return mMetrics;
269    }
270
271    public LayoutlibCallback getLayoutlibCallback() {
272        return mLayoutlibCallback;
273    }
274
275    public RenderResources getRenderResources() {
276        return mRenderResources;
277    }
278
279    public Map<String, String> getDefaultPropMap(Object key) {
280        return mDefaultPropMaps.get(key);
281    }
282
283    public Configuration getConfiguration() {
284        return mConfig;
285    }
286
287    /**
288     * Adds a parser to the stack.
289     * @param parser the parser to add.
290     */
291    public void pushParser(BridgeXmlBlockParser parser) {
292        if (ParserFactory.LOG_PARSER) {
293            System.out.println("PUSH " + parser.getParser().toString());
294        }
295        mParserStack.push(parser);
296    }
297
298    /**
299     * Removes the parser at the top of the stack
300     */
301    public void popParser() {
302        BridgeXmlBlockParser parser = mParserStack.pop();
303        if (ParserFactory.LOG_PARSER) {
304            System.out.println("POPD " + parser.getParser().toString());
305        }
306    }
307
308    /**
309     * Returns the current parser at the top the of the stack.
310     * @return a parser or null.
311     */
312    public BridgeXmlBlockParser getCurrentParser() {
313        return mParserStack.peek();
314    }
315
316    /**
317     * Returns the previous parser.
318     * @return a parser or null if there isn't any previous parser
319     */
320    public BridgeXmlBlockParser getPreviousParser() {
321        if (mParserStack.size() < 2) {
322            return null;
323        }
324        return mParserStack.get(mParserStack.size() - 2);
325    }
326
327    public boolean resolveThemeAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
328        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid);
329        boolean isFrameworkRes = true;
330        if (resourceInfo == null) {
331            resourceInfo = mLayoutlibCallback.resolveResourceId(resid);
332            isFrameworkRes = false;
333        }
334
335        if (resourceInfo == null) {
336            return false;
337        }
338
339        ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond(),
340                isFrameworkRes);
341        if (resolveRefs) {
342            value = mRenderResources.resolveResValue(value);
343        }
344
345        if (value == null) {
346            // unable to find the attribute.
347            return false;
348        }
349
350        // check if this is a style resource
351        if (value instanceof StyleResourceValue) {
352            // get the id that will represent this style.
353            outValue.resourceId = getDynamicIdByStyle((StyleResourceValue) value);
354            return true;
355        }
356
357        int a;
358        // if this is a framework value.
359        if (value.isFramework()) {
360            // look for idName in the android R classes.
361            // use 0 a default res value as it's not a valid id value.
362            a = getFrameworkResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
363        } else {
364            // look for idName in the project R class.
365            // use 0 a default res value as it's not a valid id value.
366            a = getProjectResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
367        }
368
369        if (a != 0) {
370            outValue.resourceId = a;
371            return true;
372        }
373
374        return false;
375    }
376
377
378    public ResourceReference resolveId(int id) {
379        // first get the String related to this id in the framework
380        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
381
382        if (resourceInfo != null) {
383            return new ResourceReference(resourceInfo.getSecond(), true);
384        }
385
386        // didn't find a match in the framework? look in the project.
387        if (mLayoutlibCallback != null) {
388            resourceInfo = mLayoutlibCallback.resolveResourceId(id);
389
390            if (resourceInfo != null) {
391                return new ResourceReference(resourceInfo.getSecond(), false);
392            }
393        }
394
395        // The base value for R.style is 0x01030000 and the custom style is 0x02030000.
396        // So, if the second byte is 03, it's probably a style.
397        if ((id >> 16 & 0xFF) == 0x03) {
398            return getStyleByDynamicId(id);
399        }
400        return null;
401    }
402
403    public Pair<View, Boolean> inflateView(ResourceReference resource, ViewGroup parent,
404            boolean attachToRoot, boolean skipCallbackParser) {
405        boolean isPlatformLayout = resource.isFramework();
406
407        if (!isPlatformLayout && !skipCallbackParser) {
408            // check if the project callback can provide us with a custom parser.
409            ILayoutPullParser parser = getParser(resource);
410
411            if (parser != null) {
412                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
413                        this, resource.isFramework());
414                try {
415                    pushParser(blockParser);
416                    return Pair.of(
417                            mBridgeInflater.inflate(blockParser, parent, attachToRoot),
418                            Boolean.TRUE);
419                } finally {
420                    popParser();
421                }
422            }
423        }
424
425        ResourceValue resValue;
426        if (resource instanceof ResourceValue) {
427            resValue = (ResourceValue) resource;
428        } else {
429            if (isPlatformLayout) {
430                resValue = mRenderResources.getFrameworkResource(ResourceType.LAYOUT,
431                        resource.getName());
432            } else {
433                resValue = mRenderResources.getProjectResource(ResourceType.LAYOUT,
434                        resource.getName());
435            }
436        }
437
438        if (resValue != null) {
439
440            File xml = new File(resValue.getValue());
441            if (xml.isFile()) {
442                // we need to create a pull parser around the layout XML file, and then
443                // give that to our XmlBlockParser
444                try {
445                    XmlPullParser parser = ParserFactory.create(xml, true);
446
447                    // set the resource ref to have correct view cookies
448                    mBridgeInflater.setResourceReference(resource);
449
450                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
451                            this, resource.isFramework());
452                    try {
453                        pushParser(blockParser);
454                        return Pair.of(
455                                mBridgeInflater.inflate(blockParser, parent, attachToRoot),
456                                Boolean.FALSE);
457                    } finally {
458                        popParser();
459                    }
460                } catch (XmlPullParserException e) {
461                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
462                            "Failed to configure parser for " + xml, e, null /*data*/);
463                    // we'll return null below.
464                } catch (FileNotFoundException e) {
465                    // this shouldn't happen since we check above.
466                } finally {
467                    mBridgeInflater.setResourceReference(null);
468                }
469            } else {
470                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
471                        String.format("File %s is missing!", xml), null);
472            }
473        } else {
474            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
475                    String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "",
476                            resource.getName()), null);
477        }
478
479        return Pair.of(null, Boolean.FALSE);
480    }
481
482    @SuppressWarnings("deprecation")
483    private ILayoutPullParser getParser(ResourceReference resource) {
484        ILayoutPullParser parser;
485        if (resource instanceof ResourceValue) {
486            parser = mLayoutlibCallback.getParser((ResourceValue) resource);
487        } else {
488            parser = mLayoutlibCallback.getParser(resource.getName());
489        }
490        return parser;
491    }
492
493    // ------------ Context methods
494
495    @Override
496    public Resources getResources() {
497        return mSystemResources;
498    }
499
500    @Override
501    public Theme getTheme() {
502        return mTheme;
503    }
504
505    @Override
506    public ClassLoader getClassLoader() {
507        // The documentation for this method states that it should return a class loader one can
508        // use to retrieve classes in this package. However, when called by LayoutInflater, we do
509        // not want the class loader to return app's custom views.
510        // This is so that the IDE can instantiate the custom views and also generate proper error
511        // messages in case of failure. This also enables the IDE to fallback to MockView in case
512        // there's an exception thrown when trying to inflate the custom view.
513        // To work around this issue, LayoutInflater is modified via LayoutLib Create tool to
514        // replace invocations of this method to a new method: getFrameworkClassLoader(). Also,
515        // the method is injected into Context. The implementation of getFrameworkClassLoader() is:
516        // "return getClass().getClassLoader();". This means that when LayoutInflater asks for
517        // the context ClassLoader, it gets only LayoutLib's ClassLoader which doesn't have
518        // access to the apps's custom views.
519        // This method can now return the right ClassLoader, which CustomViews can use to do the
520        // right thing.
521        if (mClassLoader == null) {
522            mClassLoader = new ClassLoader(getClass().getClassLoader()) {
523                @Override
524                protected Class<?> findClass(String name) throws ClassNotFoundException {
525                    for (String prefix : BridgeInflater.getClassPrefixList()) {
526                        if (name.startsWith(prefix)) {
527                            // These are framework classes and should not be loaded from the app.
528                            throw new ClassNotFoundException(name + " not found");
529                        }
530                    }
531                    return BridgeContext.this.mLayoutlibCallback.findClass(name);
532                }
533            };
534        }
535        return mClassLoader;
536    }
537
538    @Override
539    public Object getSystemService(String service) {
540        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
541            return mBridgeInflater;
542        }
543
544        if (TEXT_SERVICES_MANAGER_SERVICE.equals(service)) {
545            // we need to return a valid service to avoid NPE
546            return TextServicesManager.getInstance();
547        }
548
549        if (WINDOW_SERVICE.equals(service)) {
550            return mWindowManager;
551        }
552
553        // needed by SearchView
554        if (INPUT_METHOD_SERVICE.equals(service)) {
555            return null;
556        }
557
558        if (POWER_SERVICE.equals(service)) {
559            return new PowerManager(this, new BridgePowerManager(), new Handler());
560        }
561
562        if (DISPLAY_SERVICE.equals(service)) {
563            return mDisplayManager;
564        }
565
566        if (ACCESSIBILITY_SERVICE.equals(service)) {
567            return AccessibilityManager.getInstance(this);
568        }
569
570        throw new UnsupportedOperationException("Unsupported Service: " + service);
571    }
572
573    @Override
574    public String getSystemServiceName(Class<?> serviceClass) {
575        if (serviceClass.equals(LayoutInflater.class)) {
576            return LAYOUT_INFLATER_SERVICE;
577        }
578
579        if (serviceClass.equals(TextServicesManager.class)) {
580            return TEXT_SERVICES_MANAGER_SERVICE;
581        }
582
583        if (serviceClass.equals(WindowManager.class)) {
584            return WINDOW_SERVICE;
585        }
586
587        if (serviceClass.equals(PowerManager.class)) {
588            return POWER_SERVICE;
589        }
590
591        if (serviceClass.equals(DisplayManager.class)) {
592            return DISPLAY_SERVICE;
593        }
594
595        if (serviceClass.equals(AccessibilityManager.class)) {
596            return ACCESSIBILITY_SERVICE;
597        }
598
599        throw new UnsupportedOperationException("Unsupported Service: " + serviceClass);
600    }
601
602    @Override
603    public final BridgeTypedArray obtainStyledAttributes(int[] attrs) {
604        // No style is specified here, so create the typed array based on the default theme
605        // and the styles already applied to it. A null value of style indicates that the default
606        // theme should be used.
607        return createStyleBasedTypedArray(null, attrs);
608    }
609
610    @Override
611    public final BridgeTypedArray obtainStyledAttributes(int resid, int[] attrs)
612            throws Resources.NotFoundException {
613        StyleResourceValue style = null;
614        // get the StyleResourceValue based on the resId;
615        if (resid != 0) {
616            style = getStyleByDynamicId(resid);
617
618            if (style == null) {
619                // In some cases, style may not be a dynamic id, so we do a full search.
620                ResourceReference ref = resolveId(resid);
621                if (ref != null) {
622                    style = mRenderResources.getStyle(ref.getName(), ref.isFramework());
623                }
624            }
625
626            if (style == null) {
627                throw new Resources.NotFoundException();
628            }
629        }
630
631        // The map is from
632        // attrs (int[]) -> context's current themes (List<StyleRV>) -> resid (int) -> typed array.
633        if (mTypedArrayCache == null) {
634            mTypedArrayCache = new IdentityHashMap<int[],
635                    Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>();
636        }
637
638        // get the 2nd map
639        Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>> map2 =
640                mTypedArrayCache.get(attrs);
641        if (map2 == null) {
642            map2 = new HashMap<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>();
643            mTypedArrayCache.put(attrs, map2);
644        }
645
646        // get the 3rd map
647        List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
648        Map<Integer, BridgeTypedArray> map3 = map2.get(currentThemes);
649        if (map3 == null) {
650            map3 = new HashMap<Integer, BridgeTypedArray>();
651            // Create a copy of the list before adding it to the map. This allows reusing the
652            // existing list.
653            currentThemes = new ArrayList<StyleResourceValue>(currentThemes);
654            map2.put(currentThemes, map3);
655        }
656
657        // get the array from the 3rd map
658        BridgeTypedArray ta = map3.get(resid);
659
660        if (ta == null) {
661            ta = createStyleBasedTypedArray(style, attrs);
662            map3.put(resid, ta);
663        }
664
665        return ta;
666    }
667
668    @Override
669    public final BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
670        return obtainStyledAttributes(set, attrs, 0, 0);
671    }
672
673    @Override
674    public BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
675            int defStyleAttr, int defStyleRes) {
676
677        Map<String, String> defaultPropMap = null;
678        boolean isPlatformFile = true;
679
680        // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
681        if (set instanceof BridgeXmlBlockParser) {
682            BridgeXmlBlockParser parser;
683            parser = (BridgeXmlBlockParser)set;
684
685            isPlatformFile = parser.isPlatformFile();
686
687            Object key = parser.getViewCookie();
688            if (key != null) {
689                defaultPropMap = mDefaultPropMaps.get(key);
690                if (defaultPropMap == null) {
691                    defaultPropMap = new HashMap<String, String>();
692                    mDefaultPropMaps.put(key, defaultPropMap);
693                }
694            }
695
696        } else if (set instanceof BridgeLayoutParamsMapAttributes) {
697            // this is only for temp layout params generated dynamically, so this is never
698            // platform content.
699            isPlatformFile = false;
700        } else if (set != null) { // null parser is ok
701            // really this should not be happening since its instantiated in Bridge
702            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
703                    "Parser is not a BridgeXmlBlockParser!", null);
704            return null;
705        }
706
707        List<Pair<String, Boolean>> attributeList = searchAttrs(attrs);
708
709        BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
710                isPlatformFile);
711
712        // look for a custom style.
713        String customStyle = null;
714        if (set != null) {
715            customStyle = set.getAttributeValue(null, "style");
716        }
717
718        StyleResourceValue customStyleValues = null;
719        if (customStyle != null) {
720            ResourceValue item = mRenderResources.findResValue(customStyle,
721                    isPlatformFile /*forceFrameworkOnly*/);
722
723            // resolve it in case it links to something else
724            item = mRenderResources.resolveResValue(item);
725
726            if (item instanceof StyleResourceValue) {
727                customStyleValues = (StyleResourceValue)item;
728            }
729        }
730
731        // resolve the defStyleAttr value into a IStyleResourceValue
732        StyleResourceValue defStyleValues = null;
733
734        if (defStyleAttr != 0) {
735            // get the name from the int.
736            Pair<String, Boolean> defStyleAttribute = searchAttr(defStyleAttr);
737
738            if (defStyleAttribute == null) {
739                // This should be rare. Happens trying to map R.style.foo to @style/foo fails.
740                // This will happen if the user explicitly used a non existing int value for
741                // defStyleAttr or there's something wrong with the project structure/build.
742                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
743                        "Failed to find the style corresponding to the id " + defStyleAttr, null);
744            } else {
745                if (defaultPropMap != null) {
746                    String defStyleName = defStyleAttribute.getFirst();
747                    if (defStyleAttribute.getSecond()) {
748                        defStyleName = "android:" + defStyleName;
749                    }
750                    defaultPropMap.put("style", defStyleName);
751                }
752
753                // look for the style in the current theme, and its parent:
754                ResourceValue item = mRenderResources.findItemInTheme(defStyleAttribute.getFirst(),
755                        defStyleAttribute.getSecond());
756
757                if (item != null) {
758                    // item is a reference to a style entry. Search for it.
759                    item = mRenderResources.findResValue(item.getValue(), item.isFramework());
760                    item = mRenderResources.resolveResValue(item);
761                    if (item instanceof StyleResourceValue) {
762                        defStyleValues = (StyleResourceValue) item;
763                    }
764                } else {
765                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
766                            String.format(
767                                    "Failed to find style '%s' in current theme",
768                                    defStyleAttribute.getFirst()),
769                            null);
770                }
771            }
772        } else if (defStyleRes != 0) {
773            StyleResourceValue item = getStyleByDynamicId(defStyleRes);
774            if (item != null) {
775                defStyleValues = item;
776            } else {
777                boolean isFrameworkRes = true;
778                Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
779                if (value == null) {
780                    value = mLayoutlibCallback.resolveResourceId(defStyleRes);
781                    isFrameworkRes = false;
782                }
783
784                if (value != null) {
785                    if ((value.getFirst() == ResourceType.STYLE)) {
786                        // look for the style in all resources:
787                        item = mRenderResources.getStyle(value.getSecond(), isFrameworkRes);
788                        if (item != null) {
789                            if (defaultPropMap != null) {
790                                defaultPropMap.put("style", item.getName());
791                            }
792
793                            defStyleValues = item;
794                        } else {
795                            Bridge.getLog().error(null,
796                                    String.format(
797                                            "Style with id 0x%x (resolved to '%s') does not exist.",
798                                            defStyleRes, value.getSecond()),
799                                    null);
800                        }
801                    } else {
802                        Bridge.getLog().error(null,
803                                String.format(
804                                        "Resource id 0x%x is not of type STYLE (instead %s)",
805                                        defStyleRes, value.getFirst().toString()),
806                                null);
807                    }
808                } else {
809                    Bridge.getLog().error(null,
810                            String.format(
811                                    "Failed to find style with id 0x%x in current theme",
812                                    defStyleRes),
813                            null);
814                }
815            }
816        }
817
818        String appNamespace = mLayoutlibCallback.getNamespace();
819
820        if (attributeList != null) {
821            for (int index = 0 ; index < attributeList.size() ; index++) {
822                Pair<String, Boolean> attribute = attributeList.get(index);
823
824                if (attribute == null) {
825                    continue;
826                }
827
828                String attrName = attribute.getFirst();
829                boolean frameworkAttr = attribute.getSecond();
830                String value = null;
831                if (set != null) {
832                    value = set.getAttributeValue(
833                            frameworkAttr ? BridgeConstants.NS_RESOURCES : appNamespace,
834                                    attrName);
835
836                    // if this is an app attribute, and the first get fails, try with the
837                    // new res-auto namespace as well
838                    if (!frameworkAttr && value == null) {
839                        value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
840                    }
841                }
842
843                // if there's no direct value for this attribute in the XML, we look for default
844                // values in the widget defStyle, and then in the theme.
845                if (value == null) {
846                    ResourceValue resValue = null;
847
848                    // look for the value in the custom style first (and its parent if needed)
849                    if (customStyleValues != null) {
850                        resValue = mRenderResources.findItemInStyle(customStyleValues,
851                                attrName, frameworkAttr);
852                    }
853
854                    // then look for the value in the default Style (and its parent if needed)
855                    if (resValue == null && defStyleValues != null) {
856                        resValue = mRenderResources.findItemInStyle(defStyleValues,
857                                attrName, frameworkAttr);
858                    }
859
860                    // if the item is not present in the defStyle, we look in the main theme (and
861                    // its parent themes)
862                    if (resValue == null) {
863                        resValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
864                    }
865
866                    // if we found a value, we make sure this doesn't reference another value.
867                    // So we resolve it.
868                    if (resValue != null) {
869                        // put the first default value, before the resolution.
870                        if (defaultPropMap != null) {
871                            defaultPropMap.put(attrName, resValue.getValue());
872                        }
873
874                        resValue = mRenderResources.resolveResValue(resValue);
875
876                        // If the value is a reference to another theme attribute that doesn't
877                        // exist, we should log a warning and omit it.
878                        String val = resValue.getValue();
879                        if (val != null && val.startsWith(SdkConstants.PREFIX_THEME_REF)) {
880                            if (!attrName.equals(RTL_ATTRS.get(val)) ||
881                                    getApplicationInfo().targetSdkVersion <
882                                            VERSION_CODES.JELLY_BEAN_MR1) {
883                                // Only log a warning if the referenced value isn't one of the RTL
884                                // attributes, or the app targets old API.
885                                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
886                                        String.format("Failed to find '%s' in current theme.", val),
887                                        val);
888                            }
889                            resValue = null;
890                        }
891                    }
892
893                    ta.bridgeSetValue(index, attrName, frameworkAttr, resValue);
894                } else {
895                    // there is a value in the XML, but we need to resolve it in case it's
896                    // referencing another resource or a theme value.
897                    ta.bridgeSetValue(index, attrName, frameworkAttr,
898                            mRenderResources.resolveValue(null, attrName, value, isPlatformFile));
899                }
900            }
901        }
902
903        ta.sealArray();
904
905        return ta;
906    }
907
908    @Override
909    public Looper getMainLooper() {
910        return Looper.myLooper();
911    }
912
913
914    @Override
915    public String getPackageName() {
916        if (mApplicationInfo.packageName == null) {
917            mApplicationInfo.packageName = mLayoutlibCallback.getFlag(FLAG_KEY_APPLICATION_PACKAGE);
918        }
919        return mApplicationInfo.packageName;
920    }
921
922    @Override
923    public PackageManager getPackageManager() {
924        if (mPackageManager == null) {
925            mPackageManager = new BridgePackageManager();
926        }
927        return mPackageManager;
928    }
929
930    // ------------- private new methods
931
932    /**
933     * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
934     * values found in the given style. If no style is specified, the default theme, along with the
935     * styles applied to it are used.
936     *
937     * @see #obtainStyledAttributes(int, int[])
938     */
939    private BridgeTypedArray createStyleBasedTypedArray(@Nullable StyleResourceValue style,
940            int[] attrs) throws Resources.NotFoundException {
941
942        List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
943
944        BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
945                false);
946
947        // for each attribute, get its name so that we can search it in the style
948        for (int i = 0 ; i < attrs.length ; i++) {
949            Pair<String, Boolean> attribute = attributes.get(i);
950
951            if (attribute != null) {
952                // look for the value in the given style
953                ResourceValue resValue;
954                if (style != null) {
955                    resValue = mRenderResources.findItemInStyle(style, attribute.getFirst(),
956                            attribute.getSecond());
957                } else {
958                    resValue = mRenderResources.findItemInTheme(attribute.getFirst(),
959                            attribute.getSecond());
960                }
961
962                if (resValue != null) {
963                    // resolve it to make sure there are no references left.
964                    ta.bridgeSetValue(i, attribute.getFirst(), attribute.getSecond(),
965                            mRenderResources.resolveResValue(resValue));
966                }
967            }
968        }
969
970        ta.sealArray();
971
972        return ta;
973    }
974
975    /**
976     * The input int[] attrs is a list of attributes. The returns a list of information about
977     * each attributes. The information is (name, isFramework)
978     * <p/>
979     *
980     * @param attrs An attribute array reference given to obtainStyledAttributes.
981     * @return List of attribute information.
982     */
983    private List<Pair<String, Boolean>> searchAttrs(int[] attrs) {
984        List<Pair<String, Boolean>> results = new ArrayList<Pair<String, Boolean>>(attrs.length);
985
986        // for each attribute, get its name so that we can search it in the style
987        for (int attr : attrs) {
988            Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attr);
989            boolean isFramework = false;
990            if (resolvedResource != null) {
991                isFramework = true;
992            } else {
993                resolvedResource = mLayoutlibCallback.resolveResourceId(attr);
994            }
995
996            if (resolvedResource != null) {
997                results.add(Pair.of(resolvedResource.getSecond(), isFramework));
998            } else {
999                results.add(null);
1000            }
1001        }
1002
1003        return results;
1004    }
1005
1006    /**
1007     * Searches for the attribute referenced by its internal id.
1008     *
1009     * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
1010     * @return A (name, isFramework) pair describing the attribute if found. Returns null
1011     *         if nothing is found.
1012     */
1013    public Pair<String, Boolean> searchAttr(int attr) {
1014        Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
1015        if (info != null) {
1016            return Pair.of(info.getSecond(), Boolean.TRUE);
1017        }
1018
1019        info = mLayoutlibCallback.resolveResourceId(attr);
1020        if (info != null) {
1021            return Pair.of(info.getSecond(), Boolean.FALSE);
1022        }
1023
1024        return null;
1025    }
1026
1027    public int getDynamicIdByStyle(StyleResourceValue resValue) {
1028        if (mDynamicIdToStyleMap == null) {
1029            // create the maps.
1030            mDynamicIdToStyleMap = new HashMap<Integer, StyleResourceValue>();
1031            mStyleToDynamicIdMap = new HashMap<StyleResourceValue, Integer>();
1032        }
1033
1034        // look for an existing id
1035        Integer id = mStyleToDynamicIdMap.get(resValue);
1036
1037        if (id == null) {
1038            // generate a new id
1039            id = ++mDynamicIdGenerator;
1040
1041            // and add it to the maps.
1042            mDynamicIdToStyleMap.put(id, resValue);
1043            mStyleToDynamicIdMap.put(resValue, id);
1044        }
1045
1046        return id;
1047    }
1048
1049    private StyleResourceValue getStyleByDynamicId(int i) {
1050        if (mDynamicIdToStyleMap != null) {
1051            return mDynamicIdToStyleMap.get(i);
1052        }
1053
1054        return null;
1055    }
1056
1057    public int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
1058        if (getRenderResources().getFrameworkResource(resType, resName) != null) {
1059            // Bridge.getResourceId creates a new resource id if an existing one isn't found. So,
1060            // we check for the existence of the resource before calling it.
1061            return Bridge.getResourceId(resType, resName);
1062        }
1063
1064        return defValue;
1065    }
1066
1067    public int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
1068        // getResourceId creates a new resource id if an existing resource id isn't found. So, we
1069        // check for the existence of the resource before calling it.
1070        if (getRenderResources().getProjectResource(resType, resName) != null) {
1071            if (mLayoutlibCallback != null) {
1072                Integer value = mLayoutlibCallback.getResourceId(resType, resName);
1073                if (value != null) {
1074                    return value;
1075                }
1076            }
1077        }
1078
1079        return defValue;
1080    }
1081
1082    public static Context getBaseContext(Context context) {
1083        while (context instanceof ContextWrapper) {
1084            context = ((ContextWrapper) context).getBaseContext();
1085        }
1086        return context;
1087    }
1088
1089    public IBinder getBinder() {
1090        if (mBinder == null) {
1091            // create a dummy binder. We only need it be not null.
1092            mBinder = new IBinder() {
1093                @Override
1094                public String getInterfaceDescriptor() throws RemoteException {
1095                    return null;
1096                }
1097
1098                @Override
1099                public boolean pingBinder() {
1100                    return false;
1101                }
1102
1103                @Override
1104                public boolean isBinderAlive() {
1105                    return false;
1106                }
1107
1108                @Override
1109                public IInterface queryLocalInterface(String descriptor) {
1110                    return null;
1111                }
1112
1113                @Override
1114                public void dump(FileDescriptor fd, String[] args) throws RemoteException {
1115
1116                }
1117
1118                @Override
1119                public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
1120
1121                }
1122
1123                @Override
1124                public boolean transact(int code, Parcel data, Parcel reply, int flags)
1125                        throws RemoteException {
1126                    return false;
1127                }
1128
1129                @Override
1130                public void linkToDeath(DeathRecipient recipient, int flags)
1131                        throws RemoteException {
1132
1133                }
1134
1135                @Override
1136                public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
1137                    return false;
1138                }
1139
1140                @Override
1141                public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
1142                  String[] args, ResultReceiver resultReceiver) {
1143                }
1144            };
1145        }
1146        return mBinder;
1147    }
1148
1149    //------------ NOT OVERRIDEN --------------------
1150
1151    @Override
1152    public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
1153        // pass
1154        return false;
1155    }
1156
1157    @Override
1158    public int checkCallingOrSelfPermission(String arg0) {
1159        // pass
1160        return 0;
1161    }
1162
1163    @Override
1164    public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
1165        // pass
1166        return 0;
1167    }
1168
1169    @Override
1170    public int checkCallingPermission(String arg0) {
1171        // pass
1172        return 0;
1173    }
1174
1175    @Override
1176    public int checkCallingUriPermission(Uri arg0, int arg1) {
1177        // pass
1178        return 0;
1179    }
1180
1181    @Override
1182    public int checkPermission(String arg0, int arg1, int arg2) {
1183        // pass
1184        return 0;
1185    }
1186
1187    @Override
1188    public int checkSelfPermission(String arg0) {
1189        // pass
1190        return 0;
1191    }
1192
1193    @Override
1194    public int checkPermission(String arg0, int arg1, int arg2, IBinder arg3) {
1195        // pass
1196        return 0;
1197    }
1198
1199    @Override
1200    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
1201        // pass
1202        return 0;
1203    }
1204
1205    @Override
1206    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3, IBinder arg4) {
1207        // pass
1208        return 0;
1209    }
1210
1211    @Override
1212    public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
1213            int arg4, int arg5) {
1214        // pass
1215        return 0;
1216    }
1217
1218    @Override
1219    public void clearWallpaper() {
1220        // pass
1221
1222    }
1223
1224    @Override
1225    public Context createPackageContext(String arg0, int arg1) {
1226        // pass
1227        return null;
1228    }
1229
1230    @Override
1231    public Context createPackageContextAsUser(String arg0, int arg1, UserHandle user) {
1232        // pass
1233        return null;
1234    }
1235
1236    @Override
1237    public Context createConfigurationContext(Configuration overrideConfiguration) {
1238        // pass
1239        return null;
1240    }
1241
1242    @Override
1243    public Context createDisplayContext(Display display) {
1244        // pass
1245        return null;
1246    }
1247
1248    @Override
1249    public String[] databaseList() {
1250        // pass
1251        return null;
1252    }
1253
1254    @Override
1255    public Context createApplicationContext(ApplicationInfo application, int flags)
1256            throws PackageManager.NameNotFoundException {
1257        return null;
1258    }
1259
1260    @Override
1261    public boolean migrateDatabaseFrom(Context sourceContext, String name) {
1262        // pass
1263        return false;
1264    }
1265
1266    @Override
1267    public boolean deleteDatabase(String arg0) {
1268        // pass
1269        return false;
1270    }
1271
1272    @Override
1273    public boolean deleteFile(String arg0) {
1274        // pass
1275        return false;
1276    }
1277
1278    @Override
1279    public void enforceCallingOrSelfPermission(String arg0, String arg1) {
1280        // pass
1281
1282    }
1283
1284    @Override
1285    public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
1286            String arg2) {
1287        // pass
1288
1289    }
1290
1291    @Override
1292    public void enforceCallingPermission(String arg0, String arg1) {
1293        // pass
1294
1295    }
1296
1297    @Override
1298    public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
1299        // pass
1300
1301    }
1302
1303    @Override
1304    public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
1305        // pass
1306
1307    }
1308
1309    @Override
1310    public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
1311            String arg4) {
1312        // pass
1313
1314    }
1315
1316    @Override
1317    public void enforceUriPermission(Uri arg0, String arg1, String arg2,
1318            int arg3, int arg4, int arg5, String arg6) {
1319        // pass
1320
1321    }
1322
1323    @Override
1324    public String[] fileList() {
1325        // pass
1326        return null;
1327    }
1328
1329    @Override
1330    public BridgeAssetManager getAssets() {
1331        return mAssets;
1332    }
1333
1334    @Override
1335    public File getCacheDir() {
1336        // pass
1337        return null;
1338    }
1339
1340    @Override
1341    public File getCodeCacheDir() {
1342        // pass
1343        return null;
1344    }
1345
1346    @Override
1347    public File getExternalCacheDir() {
1348        // pass
1349        return null;
1350    }
1351
1352    @Override
1353    public ContentResolver getContentResolver() {
1354        if (mContentResolver == null) {
1355            mContentResolver = new BridgeContentResolver(this);
1356        }
1357        return mContentResolver;
1358    }
1359
1360    @Override
1361    public File getDatabasePath(String arg0) {
1362        // pass
1363        return null;
1364    }
1365
1366    @Override
1367    public File getDir(String arg0, int arg1) {
1368        // pass
1369        return null;
1370    }
1371
1372    @Override
1373    public File getFileStreamPath(String arg0) {
1374        // pass
1375        return null;
1376    }
1377
1378    @Override
1379    public File getSharedPreferencesPath(String name) {
1380        // pass
1381        return null;
1382    }
1383
1384    @Override
1385    public File getDataDir() {
1386        // pass
1387        return null;
1388    }
1389
1390    @Override
1391    public File getFilesDir() {
1392        // pass
1393        return null;
1394    }
1395
1396    @Override
1397    public File getNoBackupFilesDir() {
1398        // pass
1399        return null;
1400    }
1401
1402    @Override
1403    public File getExternalFilesDir(String type) {
1404        // pass
1405        return null;
1406    }
1407
1408    @Override
1409    public String getPackageCodePath() {
1410        // pass
1411        return null;
1412    }
1413
1414    @Override
1415    public String getBasePackageName() {
1416        // pass
1417        return null;
1418    }
1419
1420    @Override
1421    public String getOpPackageName() {
1422        // pass
1423        return null;
1424    }
1425
1426    @Override
1427    public ApplicationInfo getApplicationInfo() {
1428        return mApplicationInfo;
1429    }
1430
1431    @Override
1432    public String getPackageResourcePath() {
1433        // pass
1434        return null;
1435    }
1436
1437    @Override
1438    public SharedPreferences getSharedPreferences(String arg0, int arg1) {
1439        if (mSharedPreferences == null) {
1440            mSharedPreferences = new BridgeSharedPreferences();
1441        }
1442        return mSharedPreferences;
1443    }
1444
1445    @Override
1446    public SharedPreferences getSharedPreferences(File arg0, int arg1) {
1447        if (mSharedPreferences == null) {
1448            mSharedPreferences = new BridgeSharedPreferences();
1449        }
1450        return mSharedPreferences;
1451    }
1452
1453    @Override
1454    public boolean migrateSharedPreferencesFrom(Context sourceContext, String name) {
1455        // pass
1456        return false;
1457    }
1458
1459    @Override
1460    public boolean deleteSharedPreferences(String name) {
1461        // pass
1462        return false;
1463    }
1464
1465    @Override
1466    public Drawable getWallpaper() {
1467        // pass
1468        return null;
1469    }
1470
1471    @Override
1472    public int getWallpaperDesiredMinimumWidth() {
1473        return -1;
1474    }
1475
1476    @Override
1477    public int getWallpaperDesiredMinimumHeight() {
1478        return -1;
1479    }
1480
1481    @Override
1482    public void grantUriPermission(String arg0, Uri arg1, int arg2) {
1483        // pass
1484
1485    }
1486
1487    @Override
1488    public FileInputStream openFileInput(String arg0) throws FileNotFoundException {
1489        // pass
1490        return null;
1491    }
1492
1493    @Override
1494    public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException {
1495        // pass
1496        return null;
1497    }
1498
1499    @Override
1500    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) {
1501        // pass
1502        return null;
1503    }
1504
1505    @Override
1506    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
1507            CursorFactory arg2, DatabaseErrorHandler arg3) {
1508        // pass
1509        return null;
1510    }
1511
1512    @Override
1513    public Drawable peekWallpaper() {
1514        // pass
1515        return null;
1516    }
1517
1518    @Override
1519    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
1520        // pass
1521        return null;
1522    }
1523
1524    @Override
1525    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
1526            String arg2, Handler arg3) {
1527        // pass
1528        return null;
1529    }
1530
1531    @Override
1532    public Intent registerReceiverAsUser(BroadcastReceiver arg0, UserHandle arg0p5,
1533            IntentFilter arg1, String arg2, Handler arg3) {
1534        // pass
1535        return null;
1536    }
1537
1538    @Override
1539    public void removeStickyBroadcast(Intent arg0) {
1540        // pass
1541
1542    }
1543
1544    @Override
1545    public void revokeUriPermission(Uri arg0, int arg1) {
1546        // pass
1547
1548    }
1549
1550    @Override
1551    public void sendBroadcast(Intent arg0) {
1552        // pass
1553
1554    }
1555
1556    @Override
1557    public void sendBroadcast(Intent arg0, String arg1) {
1558        // pass
1559
1560    }
1561
1562    @Override
1563    public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
1564        // pass
1565
1566    }
1567
1568    @Override
1569    public void sendBroadcast(Intent arg0, String arg1, Bundle arg2) {
1570        // pass
1571
1572    }
1573
1574    @Override
1575    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
1576        // pass
1577    }
1578
1579    @Override
1580    public void sendOrderedBroadcast(Intent arg0, String arg1) {
1581        // pass
1582
1583    }
1584
1585    @Override
1586    public void sendOrderedBroadcast(Intent arg0, String arg1,
1587            BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
1588            Bundle arg6) {
1589        // pass
1590
1591    }
1592
1593    @Override
1594    public void sendOrderedBroadcast(Intent arg0, String arg1,
1595            Bundle arg7, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
1596            Bundle arg6) {
1597        // pass
1598
1599    }
1600
1601    @Override
1602    public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
1603            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
1604            String initialData, Bundle initialExtras) {
1605        // pass
1606    }
1607
1608    @Override
1609    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
1610        // pass
1611    }
1612
1613    @Override
1614    public void sendBroadcastAsUser(Intent intent, UserHandle user,
1615            String receiverPermission) {
1616        // pass
1617    }
1618
1619    public void sendBroadcastAsUser(Intent intent, UserHandle user,
1620            String receiverPermission, int appOp) {
1621        // pass
1622    }
1623
1624    @Override
1625    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1626            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
1627            int initialCode, String initialData, Bundle initialExtras) {
1628        // pass
1629    }
1630
1631    @Override
1632    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1633            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
1634            Handler scheduler,
1635            int initialCode, String initialData, Bundle initialExtras) {
1636        // pass
1637    }
1638
1639    @Override
1640    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1641            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
1642            Handler scheduler,
1643            int initialCode, String initialData, Bundle initialExtras) {
1644        // pass
1645    }
1646
1647    @Override
1648    public void sendStickyBroadcast(Intent arg0) {
1649        // pass
1650
1651    }
1652
1653    @Override
1654    public void sendStickyOrderedBroadcast(Intent intent,
1655            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
1656           Bundle initialExtras) {
1657        // pass
1658    }
1659
1660    @Override
1661    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
1662        // pass
1663    }
1664
1665    @Override
1666    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
1667        // pass
1668    }
1669
1670    @Override
1671    public void sendStickyOrderedBroadcastAsUser(Intent intent,
1672            UserHandle user, BroadcastReceiver resultReceiver,
1673            Handler scheduler, int initialCode, String initialData,
1674            Bundle initialExtras) {
1675        // pass
1676    }
1677
1678    @Override
1679    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
1680        // pass
1681    }
1682
1683    @Override
1684    public void setTheme(int arg0) {
1685        // pass
1686
1687    }
1688
1689    @Override
1690    public void setWallpaper(Bitmap arg0) throws IOException {
1691        // pass
1692
1693    }
1694
1695    @Override
1696    public void setWallpaper(InputStream arg0) throws IOException {
1697        // pass
1698
1699    }
1700
1701    @Override
1702    public void startActivity(Intent arg0) {
1703        // pass
1704    }
1705
1706    @Override
1707    public void startActivity(Intent arg0, Bundle arg1) {
1708        // pass
1709    }
1710
1711    @Override
1712    public void startIntentSender(IntentSender intent,
1713            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
1714            throws IntentSender.SendIntentException {
1715        // pass
1716    }
1717
1718    @Override
1719    public void startIntentSender(IntentSender intent,
1720            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
1721            Bundle options) throws IntentSender.SendIntentException {
1722        // pass
1723    }
1724
1725    @Override
1726    public boolean startInstrumentation(ComponentName arg0, String arg1,
1727            Bundle arg2) {
1728        // pass
1729        return false;
1730    }
1731
1732    @Override
1733    public ComponentName startService(Intent arg0) {
1734        // pass
1735        return null;
1736    }
1737
1738    @Override
1739    public boolean stopService(Intent arg0) {
1740        // pass
1741        return false;
1742    }
1743
1744    @Override
1745    public ComponentName startServiceAsUser(Intent arg0, UserHandle arg1) {
1746        // pass
1747        return null;
1748    }
1749
1750    @Override
1751    public boolean stopServiceAsUser(Intent arg0, UserHandle arg1) {
1752        // pass
1753        return false;
1754    }
1755
1756    @Override
1757    public void unbindService(ServiceConnection arg0) {
1758        // pass
1759
1760    }
1761
1762    @Override
1763    public void unregisterReceiver(BroadcastReceiver arg0) {
1764        // pass
1765
1766    }
1767
1768    @Override
1769    public Context getApplicationContext() {
1770        return this;
1771    }
1772
1773    @Override
1774    public void startActivities(Intent[] arg0) {
1775        // pass
1776
1777    }
1778
1779    @Override
1780    public void startActivities(Intent[] arg0, Bundle arg1) {
1781        // pass
1782
1783    }
1784
1785    @Override
1786    public boolean isRestricted() {
1787        return false;
1788    }
1789
1790    @Override
1791    public File getObbDir() {
1792        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null);
1793        return null;
1794    }
1795
1796    @Override
1797    public DisplayAdjustments getDisplayAdjustments(int displayId) {
1798        // pass
1799        return null;
1800    }
1801
1802    @Override
1803    public int getUserId() {
1804        return 0; // not used
1805    }
1806
1807    @Override
1808    public File[] getExternalFilesDirs(String type) {
1809        // pass
1810        return new File[0];
1811    }
1812
1813    @Override
1814    public File[] getObbDirs() {
1815        // pass
1816        return new File[0];
1817    }
1818
1819    @Override
1820    public File[] getExternalCacheDirs() {
1821        // pass
1822        return new File[0];
1823    }
1824
1825    @Override
1826    public File[] getExternalMediaDirs() {
1827        // pass
1828        return new File[0];
1829    }
1830
1831    public void setScrollYPos(@NonNull View view, int scrollPos) {
1832        mScrollYPos.put(view, scrollPos);
1833    }
1834
1835    public int getScrollYPos(@NonNull View view) {
1836        Integer pos = mScrollYPos.get(view);
1837        return pos != null ? pos : 0;
1838    }
1839
1840    @Override
1841    public Context createDeviceEncryptedStorageContext() {
1842        // pass
1843        return null;
1844    }
1845
1846    @Override
1847    public Context createCredentialEncryptedStorageContext() {
1848        // pass
1849        return null;
1850    }
1851
1852    @Override
1853    public boolean isDeviceEncryptedStorage() {
1854        return false;
1855    }
1856
1857    @Override
1858    public boolean isCredentialEncryptedStorage() {
1859        return false;
1860    }
1861}
1862