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