• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.layoutlib.bridge.android;
18 
19 import com.android.SdkConstants;
20 import com.android.ide.common.rendering.api.AssetRepository;
21 import com.android.ide.common.rendering.api.ILayoutLog;
22 import com.android.ide.common.rendering.api.ILayoutPullParser;
23 import com.android.ide.common.rendering.api.LayoutlibCallback;
24 import com.android.ide.common.rendering.api.RenderResources;
25 import com.android.ide.common.rendering.api.ResourceNamespace;
26 import com.android.ide.common.rendering.api.ResourceNamespace.Resolver;
27 import com.android.ide.common.rendering.api.ResourceReference;
28 import com.android.ide.common.rendering.api.ResourceValue;
29 import com.android.ide.common.rendering.api.ResourceValueImpl;
30 import com.android.ide.common.rendering.api.StyleResourceValue;
31 import com.android.layoutlib.bridge.Bridge;
32 import com.android.layoutlib.bridge.BridgeConstants;
33 import com.android.layoutlib.bridge.impl.ParserFactory;
34 import com.android.layoutlib.bridge.impl.ResourceHelper;
35 import com.android.layoutlib.bridge.impl.Stack;
36 import com.android.resources.ResourceType;
37 import com.android.utils.Pair;
38 
39 import org.xmlpull.v1.XmlPullParser;
40 import org.xmlpull.v1.XmlPullParserException;
41 
42 import android.annotation.NonNull;
43 import android.annotation.Nullable;
44 import android.app.ActivityManager;
45 import android.app.ActivityManager_Accessor;
46 import android.app.SystemServiceRegistry;
47 import android.content.BroadcastReceiver;
48 import android.content.ClipboardManager;
49 import android.content.ComponentCallbacks;
50 import android.content.ComponentName;
51 import android.content.ContentResolver;
52 import android.content.Context;
53 import android.content.ContextWrapper;
54 import android.content.Intent;
55 import android.content.IntentFilter;
56 import android.content.IntentSender;
57 import android.content.ServiceConnection;
58 import android.content.SharedPreferences;
59 import android.content.pm.ApplicationInfo;
60 import android.content.pm.PackageManager;
61 import android.content.res.AssetManager;
62 import android.content.res.BridgeAssetManager;
63 import android.content.res.BridgeTypedArray;
64 import android.content.res.Configuration;
65 import android.content.res.Resources;
66 import android.content.res.Resources.Theme;
67 import android.content.res.Resources_Delegate;
68 import android.database.DatabaseErrorHandler;
69 import android.database.sqlite.SQLiteDatabase;
70 import android.database.sqlite.SQLiteDatabase.CursorFactory;
71 import android.graphics.Bitmap;
72 import android.graphics.drawable.Drawable;
73 import android.hardware.display.DisplayManager;
74 import android.net.ConnectivityManager;
75 import android.net.Uri;
76 import android.os.Bundle;
77 import android.os.Handler;
78 import android.os.IBinder;
79 import android.os.IInterface;
80 import android.os.Looper;
81 import android.os.Parcel;
82 import android.os.PowerManager;
83 import android.os.RemoteException;
84 import android.os.ResultReceiver;
85 import android.os.ShellCallback;
86 import android.os.UserHandle;
87 import android.util.AttributeSet;
88 import android.util.DisplayMetrics;
89 import android.util.TypedValue;
90 import android.view.BridgeInflater;
91 import android.view.Display;
92 import android.view.DisplayAdjustments;
93 import android.view.View;
94 import android.view.ViewGroup;
95 import android.view.WindowManager;
96 import android.view.WindowManagerImpl;
97 import android.view.accessibility.AccessibilityManager;
98 import android.view.autofill.AutofillManager;
99 import android.view.autofill.IAutoFillManager.Default;
100 import android.view.inputmethod.InputMethodManager;
101 import android.view.textservice.TextServicesManager;
102 
103 import java.io.File;
104 import java.io.FileDescriptor;
105 import java.io.FileInputStream;
106 import java.io.FileNotFoundException;
107 import java.io.FileOutputStream;
108 import java.io.IOException;
109 import java.io.InputStream;
110 import java.util.ArrayList;
111 import java.util.HashMap;
112 import java.util.IdentityHashMap;
113 import java.util.List;
114 import java.util.Map;
115 import java.util.concurrent.Executor;
116 
117 import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1;
118 import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
119 
120 /**
121  * Custom implementation of Context/Activity to handle non compiled resources.
122  */
123 public class BridgeContext extends Context {
124     private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat";
125 
126     private static final Map<String, ResourceValue> FRAMEWORK_PATCHED_VALUES = new HashMap<>(2);
127     private static final Map<String, ResourceValue> FRAMEWORK_REPLACE_VALUES = new HashMap<>(3);
128 
129     static {
130         FRAMEWORK_PATCHED_VALUES.put("animateFirstView",
131                 new ResourceValueImpl(ResourceNamespace.ANDROID, ResourceType.BOOL,
132                         "animateFirstView", "false"));
133         FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges",
134                 new ResourceValueImpl(ResourceNamespace.ANDROID, ResourceType.BOOL,
135                         "animateLayoutChanges", "false"));
136 
137 
138         FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout",
139                 new ResourceValueImpl(ResourceNamespace.ANDROID, ResourceType.LAYOUT,
140                         "textEditSuggestionItemLayout", "text_edit_suggestion_item"));
141         FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout",
142                 new ResourceValueImpl(ResourceNamespace.ANDROID, ResourceType.LAYOUT,
143                         "textEditSuggestionContainerLayout", "text_edit_suggestion_container"));
144         FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle",
145                 new ResourceValueImpl(ResourceNamespace.ANDROID, ResourceType.STYLE,
146                         "textEditSuggestionHighlightStyle",
147                         "TextAppearance.Holo.SuggestionHighlight"));
148     }
149 
150     /** The map adds cookies to each view so that IDE can link xml tags to views. */
151     private final HashMap<View, Object> mViewKeyMap = new HashMap<>();
152     /**
153      * In some cases, when inflating an xml, some objects are created. Then later, the objects are
154      * converted to views. This map stores the mapping from objects to cookies which can then be
155      * used to populate the mViewKeyMap.
156      */
157     private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<>();
158     private final BridgeAssetManager mAssets;
159     private final boolean mShadowsEnabled;
160     private final boolean mHighQualityShadows;
161     private Resources mSystemResources;
162     private final Object mProjectKey;
163     private final DisplayMetrics mMetrics;
164     private final RenderResources mRenderResources;
165     private final Configuration mConfig;
166     private final ApplicationInfo mApplicationInfo;
167     private final LayoutlibCallback mLayoutlibCallback;
168     private final WindowManager mWindowManager;
169     private final DisplayManager mDisplayManager;
170     private final AutofillManager mAutofillManager;
171     private final ClipboardManager mClipboardManager;
172     private final ActivityManager mActivityManager;
173     private final ConnectivityManager mConnectivityManager;
174     private final HashMap<View, Integer> mScrollYPos = new HashMap<>();
175     private final HashMap<View, Integer> mScrollXPos = new HashMap<>();
176 
177     private Resources.Theme mTheme;
178 
179     private final Map<Object, Map<ResourceReference, ResourceValue>> mDefaultPropMaps =
180             new IdentityHashMap<>();
181     private final Map<Object, ResourceReference> mDefaultStyleMap = new IdentityHashMap<>();
182 
183     // cache for TypedArray generated from StyleResourceValue object
184     private TypedArrayCache mTypedArrayCache;
185     private BridgeInflater mBridgeInflater;
186 
187     private BridgeContentResolver mContentResolver;
188 
189     private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<>();
190     private SharedPreferences mSharedPreferences;
191     private ClassLoader mClassLoader;
192     private IBinder mBinder;
193     private PackageManager mPackageManager;
194     private Boolean mIsThemeAppCompat;
195     private final ResourceNamespace mAppCompatNamespace;
196     private final Map<Key<?>, Object> mUserData = new HashMap<>();
197 
198     /**
199      * Some applications that target both pre API 17 and post API 17, set the newer attrs to
200      * reference the older ones. For example, android:paddingStart will resolve to
201      * android:paddingLeft. This way the apps need to only define paddingLeft at any other place.
202      * This a map from value to attribute name. Warning for missing references shouldn't be logged
203      * if value and attr name pair is the same as an entry in this map.
204      */
205     private static Map<String, String> RTL_ATTRS = new HashMap<>(10);
206 
207     static {
208         RTL_ATTRS.put("?android:attr/paddingLeft", "paddingStart");
209         RTL_ATTRS.put("?android:attr/paddingRight", "paddingEnd");
210         RTL_ATTRS.put("?android:attr/layout_marginLeft", "layout_marginStart");
211         RTL_ATTRS.put("?android:attr/layout_marginRight", "layout_marginEnd");
212         RTL_ATTRS.put("?android:attr/layout_toLeftOf", "layout_toStartOf");
213         RTL_ATTRS.put("?android:attr/layout_toRightOf", "layout_toEndOf");
214         RTL_ATTRS.put("?android:attr/layout_alignParentLeft", "layout_alignParentStart");
215         RTL_ATTRS.put("?android:attr/layout_alignParentRight", "layout_alignParentEnd");
216         RTL_ATTRS.put("?android:attr/drawableLeft", "drawableStart");
217         RTL_ATTRS.put("?android:attr/drawableRight", "drawableEnd");
218     }
219 
220     /**
221      * @param projectKey An Object identifying the project. This is used for the cache mechanism.
222      * @param metrics the {@link DisplayMetrics}.
223      * @param renderResources the configured resources (both framework and projects) for this
224      * render.
225      * @param config the Configuration object for this render.
226      * @param targetSdkVersion the targetSdkVersion of the application.
227      */
BridgeContext(Object projectKey, @NonNull DisplayMetrics metrics, @NonNull RenderResources renderResources, @NonNull AssetRepository assets, @NonNull LayoutlibCallback layoutlibCallback, @NonNull Configuration config, int targetSdkVersion, boolean hasRtlSupport, boolean shadowsEnabled, boolean highQualityShadows)228     public BridgeContext(Object projectKey, @NonNull DisplayMetrics metrics,
229             @NonNull RenderResources renderResources,
230             @NonNull AssetRepository assets,
231             @NonNull LayoutlibCallback layoutlibCallback,
232             @NonNull Configuration config,
233             int targetSdkVersion,
234             boolean hasRtlSupport,
235             boolean shadowsEnabled,
236             boolean highQualityShadows) {
237         mProjectKey = projectKey;
238         mMetrics = metrics;
239         mLayoutlibCallback = layoutlibCallback;
240 
241         mRenderResources = renderResources;
242         mConfig = config;
243         AssetManager systemAssetManager = AssetManager.getSystem();
244         if (systemAssetManager instanceof BridgeAssetManager) {
245             mAssets = (BridgeAssetManager) systemAssetManager;
246         } else {
247             throw new AssertionError("Creating BridgeContext without initializing Bridge");
248         }
249         mAssets.setAssetRepository(assets);
250 
251         mApplicationInfo = new ApplicationInfo();
252         mApplicationInfo.targetSdkVersion = targetSdkVersion;
253         if (hasRtlSupport) {
254             mApplicationInfo.flags = mApplicationInfo.flags | ApplicationInfo.FLAG_SUPPORTS_RTL;
255         }
256 
257         mWindowManager = new WindowManagerImpl(this, mMetrics);
258         mDisplayManager = new DisplayManager(this);
259         mAutofillManager = new AutofillManager(this, new Default());
260         mClipboardManager = new ClipboardManager(this, null);
261         mActivityManager = ActivityManager_Accessor.getActivityManagerInstance(this);
262         mConnectivityManager = new ConnectivityManager(this, null);
263 
264         if (mLayoutlibCallback.isResourceNamespacingRequired()) {
265             if (mLayoutlibCallback.hasAndroidXAppCompat()) {
266                 mAppCompatNamespace = ResourceNamespace.APPCOMPAT;
267             } else {
268                 mAppCompatNamespace = ResourceNamespace.APPCOMPAT_LEGACY;
269             }
270         } else {
271             mAppCompatNamespace = ResourceNamespace.RES_AUTO;
272         }
273 
274         mShadowsEnabled = shadowsEnabled;
275         mHighQualityShadows = highQualityShadows;
276     }
277 
278     /**
279      * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
280      * {@link DisplayMetrics}, {@link Configuration}, and {@link LayoutlibCallback}.
281      *
282      * @see #disposeResources()
283      */
initResources()284     public void initResources() {
285         AssetManager assetManager = AssetManager.getSystem();
286 
287         mSystemResources = Resources_Delegate.initSystem(
288                 this,
289                 assetManager,
290                 mMetrics,
291                 mConfig,
292                 mLayoutlibCallback);
293         mTheme = mSystemResources.newTheme();
294     }
295 
296     /**
297      * Disposes the {@link Resources} singleton and the AssetRepository inside BridgeAssetManager.
298      */
disposeResources()299     public void disposeResources() {
300         Resources_Delegate.disposeSystem();
301 
302         // The BridgeAssetManager pointed to by the mAssets field is a long-lived object, but
303         // the AssetRepository is not. To prevent it from leaking clear a reference to it from
304         // the BridgeAssetManager.
305         mAssets.releaseAssetRepository();
306     }
307 
setBridgeInflater(BridgeInflater inflater)308     public void setBridgeInflater(BridgeInflater inflater) {
309         mBridgeInflater = inflater;
310     }
311 
addViewKey(View view, Object viewKey)312     public void addViewKey(View view, Object viewKey) {
313         mViewKeyMap.put(view, viewKey);
314     }
315 
getViewKey(View view)316     public Object getViewKey(View view) {
317         return mViewKeyMap.get(view);
318     }
319 
addCookie(Object o, Object cookie)320     public void addCookie(Object o, Object cookie) {
321         mViewKeyHelpMap.put(o, cookie);
322     }
323 
getCookie(Object o)324     public Object getCookie(Object o) {
325         return mViewKeyHelpMap.get(o);
326     }
327 
getProjectKey()328     public Object getProjectKey() {
329         return mProjectKey;
330     }
331 
getMetrics()332     public DisplayMetrics getMetrics() {
333         return mMetrics;
334     }
335 
getLayoutlibCallback()336     public LayoutlibCallback getLayoutlibCallback() {
337         return mLayoutlibCallback;
338     }
339 
getRenderResources()340     public RenderResources getRenderResources() {
341         return mRenderResources;
342     }
343 
getDefaultProperties()344     public Map<Object, Map<ResourceReference, ResourceValue>> getDefaultProperties() {
345         return mDefaultPropMaps;
346     }
347 
getDefaultNamespacedStyles()348     public Map<Object, ResourceReference> getDefaultNamespacedStyles() {
349         return mDefaultStyleMap;
350     }
351 
getConfiguration()352     public Configuration getConfiguration() {
353         return mConfig;
354     }
355 
356     /**
357      * Adds a parser to the stack.
358      * @param parser the parser to add.
359      */
pushParser(BridgeXmlBlockParser parser)360     public void pushParser(BridgeXmlBlockParser parser) {
361         if (ParserFactory.LOG_PARSER) {
362             System.out.println("PUSH " + parser.getParser().toString());
363         }
364         mParserStack.push(parser);
365     }
366 
367     /**
368      * Removes the parser at the top of the stack
369      */
popParser()370     public void popParser() {
371         BridgeXmlBlockParser parser = mParserStack.pop();
372         if (ParserFactory.LOG_PARSER) {
373             System.out.println("POPD " + parser.getParser().toString());
374         }
375     }
376 
377     /**
378      * Returns the current parser at the top the of the stack.
379      * @return a parser or null.
380      */
getCurrentParser()381     private BridgeXmlBlockParser getCurrentParser() {
382         return mParserStack.peek();
383     }
384 
385     /**
386      * Returns the previous parser.
387      * @return a parser or null if there isn't any previous parser
388      */
getPreviousParser()389     public BridgeXmlBlockParser getPreviousParser() {
390         if (mParserStack.size() < 2) {
391             return null;
392         }
393         return mParserStack.get(mParserStack.size() - 2);
394     }
395 
resolveThemeAttribute(int resId, TypedValue outValue, boolean resolveRefs)396     public boolean resolveThemeAttribute(int resId, TypedValue outValue, boolean resolveRefs) {
397         ResourceReference resourceInfo = Bridge.resolveResourceId(resId);
398         if (resourceInfo == null) {
399             resourceInfo = mLayoutlibCallback.resolveResourceId(resId);
400         }
401 
402         if (resourceInfo == null || resourceInfo.getResourceType() != ResourceType.ATTR) {
403             return false;
404         }
405 
406         ResourceValue value = mRenderResources.findItemInTheme(resourceInfo);
407         if (resolveRefs) {
408             value = mRenderResources.resolveResValue(value);
409         }
410 
411         if (value == null) {
412             // unable to find the attribute.
413             return false;
414         }
415 
416         // check if this is a style resource
417         if (value instanceof StyleResourceValue) {
418             // get the id that will represent this style.
419             outValue.resourceId = getDynamicIdByStyle((StyleResourceValue) value);
420             return true;
421         }
422 
423         String stringValue = value.getValue();
424         if (!stringValue.isEmpty()) {
425             if (stringValue.charAt(0) == '#') {
426                 outValue.data = ResourceHelper.getColor(stringValue);
427                 switch (stringValue.length()) {
428                     case 4:
429                         outValue.type = TypedValue.TYPE_INT_COLOR_RGB4;
430                         break;
431                     case 5:
432                         outValue.type = TypedValue.TYPE_INT_COLOR_ARGB4;
433                         break;
434                     case 7:
435                         outValue.type = TypedValue.TYPE_INT_COLOR_RGB8;
436                         break;
437                     default:
438                         outValue.type = TypedValue.TYPE_INT_COLOR_ARGB8;
439                 }
440             }
441             else if (stringValue.charAt(0) == '@') {
442                 outValue.type = TypedValue.TYPE_REFERENCE;
443             }
444             else if ("true".equals(stringValue) || "false".equals(stringValue)) {
445                 outValue.type = TypedValue.TYPE_INT_BOOLEAN;
446                 outValue.data = "true".equals(stringValue) ? 1 : 0;
447             }
448         }
449 
450         int a = getResourceId(value.asReference(), 0 /*defValue*/);
451 
452         if (a != 0) {
453             outValue.resourceId = a;
454             return true;
455         }
456 
457         // If the value is not a valid reference, fallback to pass the value as a string.
458         outValue.string = stringValue;
459         return true;
460     }
461 
462 
resolveId(int id)463     public ResourceReference resolveId(int id) {
464         // first get the String related to this id in the framework
465         ResourceReference resourceInfo = Bridge.resolveResourceId(id);
466 
467         if (resourceInfo != null) {
468             return resourceInfo;
469         }
470 
471         // didn't find a match in the framework? look in the project.
472         if (mLayoutlibCallback != null) {
473             resourceInfo = mLayoutlibCallback.resolveResourceId(id);
474 
475             if (resourceInfo != null) {
476                 return resourceInfo;
477             }
478         }
479 
480         return null;
481     }
482 
inflateView(ResourceReference layout, ViewGroup parent, @SuppressWarnings("SameParameterValue") boolean attachToRoot, boolean skipCallbackParser)483     public Pair<View, Boolean> inflateView(ResourceReference layout, ViewGroup parent,
484             @SuppressWarnings("SameParameterValue") boolean attachToRoot,
485             boolean skipCallbackParser) {
486         boolean isPlatformLayout = layout.getNamespace().equals(ResourceNamespace.ANDROID);
487 
488         if (!isPlatformLayout && !skipCallbackParser) {
489             // check if the project callback can provide us with a custom parser.
490             ILayoutPullParser parser = null;
491             ResourceValue layoutValue = mRenderResources.getResolvedResource(layout);
492             if (layoutValue != null) {
493                 parser = getLayoutlibCallback().getParser(layoutValue);
494             }
495 
496             if (parser != null) {
497                 BridgeXmlBlockParser blockParser =
498                         new BridgeXmlBlockParser(parser, this, layout.getNamespace());
499                 try {
500                     pushParser(blockParser);
501                     return Pair.of(
502                             mBridgeInflater.inflate(blockParser, parent, attachToRoot),
503                             Boolean.TRUE);
504                 } finally {
505                     popParser();
506                 }
507             }
508         }
509 
510         ResourceValue resValue = mRenderResources.getResolvedResource(layout);
511 
512         if (resValue != null) {
513             String path = resValue.getValue();
514             // We need to create a pull parser around the layout XML file, and then
515             // give that to our XmlBlockParser.
516             try {
517                 XmlPullParser parser = ParserFactory.create(path, true);
518                 if (parser != null) {
519                     // Set the layout ref to have correct view cookies.
520                     mBridgeInflater.setResourceReference(layout);
521 
522                     BridgeXmlBlockParser blockParser =
523                             new BridgeXmlBlockParser(parser, this, layout.getNamespace());
524                     try {
525                         pushParser(blockParser);
526                         return Pair.of(mBridgeInflater.inflate(blockParser, parent, attachToRoot),
527                                 Boolean.FALSE);
528                     } finally {
529                         popParser();
530                     }
531                 } else {
532                     Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
533                             String.format("File %s is missing!", path), null, null);
534                 }
535             } catch (XmlPullParserException e) {
536                 Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
537                         "Failed to parse file " + path, e, null, null /*data*/);
538                 // we'll return null below.
539             } finally {
540                 mBridgeInflater.setResourceReference(null);
541             }
542         } else {
543             Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
544                     String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "",
545                             layout.getName()), null, null);
546         }
547 
548         return Pair.of(null, Boolean.FALSE);
549     }
550 
551     /**
552      * Returns whether the current selected theme is based on AppCompat
553      */
isAppCompatTheme()554     public boolean isAppCompatTheme() {
555         // If a cached value exists, return it.
556         if (mIsThemeAppCompat != null) {
557             return mIsThemeAppCompat;
558         }
559         // Ideally, we should check if the corresponding activity extends
560         // android.support.v7.app.ActionBarActivity, and not care about the theme name at all.
561         StyleResourceValue defaultTheme = mRenderResources.getDefaultTheme();
562         // We can't simply check for parent using resources.themeIsParentOf() since the
563         // inheritance structure isn't really what one would expect. The first common parent
564         // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21).
565         boolean isThemeAppCompat = false;
566         for (int i = 0; i < 50; i++) {
567             if (defaultTheme == null) {
568                 break;
569             }
570             // for loop ensures that we don't run into cyclic theme inheritance.
571             if (defaultTheme.getName().startsWith(PREFIX_THEME_APPCOMPAT)) {
572                 isThemeAppCompat = true;
573                 break;
574             }
575             defaultTheme = mRenderResources.getParent(defaultTheme);
576         }
577         mIsThemeAppCompat = isThemeAppCompat;
578         return isThemeAppCompat;
579     }
580 
581     // ------------ Context methods
582 
583     @Override
getResources()584     public Resources getResources() {
585         return mSystemResources;
586     }
587 
588     @Override
getTheme()589     public Theme getTheme() {
590         return mTheme;
591     }
592 
593     @Override
getClassLoader()594     public ClassLoader getClassLoader() {
595         // The documentation for this method states that it should return a class loader one can
596         // use to retrieve classes in this package. However, when called by LayoutInflater, we do
597         // not want the class loader to return app's custom views.
598         // This is so that the IDE can instantiate the custom views and also generate proper error
599         // messages in case of failure. This also enables the IDE to fallback to MockView in case
600         // there's an exception thrown when trying to inflate the custom view.
601         // To work around this issue, LayoutInflater is modified via LayoutLib Create tool to
602         // replace invocations of this method to a new method: getFrameworkClassLoader(). Also,
603         // the method is injected into Context. The implementation of getFrameworkClassLoader() is:
604         // "return getClass().getClassLoader();". This means that when LayoutInflater asks for
605         // the context ClassLoader, it gets only LayoutLib's ClassLoader which doesn't have
606         // access to the apps's custom views.
607         // This method can now return the right ClassLoader, which CustomViews can use to do the
608         // right thing.
609         if (mClassLoader == null) {
610             mClassLoader = new ClassLoader(getClass().getClassLoader()) {
611                 @Override
612                 protected Class<?> findClass(String name) throws ClassNotFoundException {
613                     for (String prefix : BridgeInflater.getClassPrefixList()) {
614                         if (name.startsWith(prefix)) {
615                             // These are framework classes and should not be loaded from the app.
616                             throw new ClassNotFoundException(name + " not found");
617                         }
618                     }
619                     return BridgeContext.this.mLayoutlibCallback.findClass(name);
620                 }
621             };
622         }
623         return mClassLoader;
624     }
625 
626     @Override
getSystemService(String service)627     public Object getSystemService(String service) {
628         switch (service) {
629             case LAYOUT_INFLATER_SERVICE:
630                 return mBridgeInflater;
631 
632             case TEXT_SERVICES_MANAGER_SERVICE:
633                 // we need to return a valid service to avoid NPE
634                 return TextServicesManager.getInstance();
635 
636             case WINDOW_SERVICE:
637                 return mWindowManager;
638 
639             case POWER_SERVICE:
640                 return new PowerManager(this, new BridgePowerManager(), new BridgeThermalService(),
641                         new Handler());
642 
643             case DISPLAY_SERVICE:
644                 return mDisplayManager;
645 
646             case ACCESSIBILITY_SERVICE:
647                 return AccessibilityManager.getInstance(this);
648 
649             case INPUT_METHOD_SERVICE:  // needed by SearchView and Compose
650                 return InputMethodManager.forContext(this);
651 
652             case AUTOFILL_MANAGER_SERVICE:
653                 return mAutofillManager;
654 
655             case CLIPBOARD_SERVICE:
656                 return mClipboardManager;
657 
658             case ACTIVITY_SERVICE:
659                 return mActivityManager;
660 
661             case CONNECTIVITY_SERVICE:
662                 return mConnectivityManager;
663 
664             case AUDIO_SERVICE:
665             case TEXT_CLASSIFICATION_SERVICE:
666             case CONTENT_CAPTURE_MANAGER_SERVICE:
667                 return null;
668             default:
669                 assert false : "Unsupported Service: " + service;
670         }
671 
672         return null;
673     }
674 
675     @Override
getSystemServiceName(Class<?> serviceClass)676     public String getSystemServiceName(Class<?> serviceClass) {
677         return SystemServiceRegistry.getSystemServiceName(serviceClass);
678     }
679 
680     /**
681      * Same as Context#obtainStyledAttributes. We do not override the base method to give the
682      * original Context the chance to override the theme when needed.
683      */
684     @Nullable
internalObtainStyledAttributes(int resId, int[] attrs)685     public final BridgeTypedArray internalObtainStyledAttributes(int resId, int[] attrs)
686             throws Resources.NotFoundException {
687         StyleResourceValue style = null;
688         // get the StyleResourceValue based on the resId;
689         if (resId != 0) {
690             style = getStyleByDynamicId(resId);
691 
692             if (style == null) {
693                 // In some cases, style may not be a dynamic id, so we do a full search.
694                 ResourceReference ref = resolveId(resId);
695                 if (ref != null) {
696                     style = mRenderResources.getStyle(ref);
697                 }
698             }
699 
700             if (style == null) {
701                 Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE,
702                         "Failed to find style with " + resId, null, null);
703                 return null;
704             }
705         }
706 
707         if (mTypedArrayCache == null) {
708             mTypedArrayCache = new TypedArrayCache();
709         }
710 
711         List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
712 
713         Pair<BridgeTypedArray, Map<ResourceReference, ResourceValue>> typeArrayAndPropertiesPair =
714                 mTypedArrayCache.get(attrs, currentThemes, resId);
715 
716         if (typeArrayAndPropertiesPair == null) {
717             typeArrayAndPropertiesPair = createStyleBasedTypedArray(style, attrs);
718             mTypedArrayCache.put(attrs, currentThemes, resId, typeArrayAndPropertiesPair);
719         }
720         // Add value to defaultPropsMap if needed
721         if (typeArrayAndPropertiesPair.getSecond() != null) {
722             BridgeXmlBlockParser parser = getCurrentParser();
723             Object key = parser != null ? parser.getViewCookie() : null;
724             if (key != null) {
725                 Map<ResourceReference, ResourceValue> defaultPropMap = mDefaultPropMaps.get(key);
726                 if (defaultPropMap == null) {
727                     defaultPropMap = typeArrayAndPropertiesPair.getSecond();
728                     mDefaultPropMaps.put(key, defaultPropMap);
729                 } else {
730                     defaultPropMap.putAll(typeArrayAndPropertiesPair.getSecond());
731                 }
732             }
733         }
734         return typeArrayAndPropertiesPair.getFirst();
735     }
736 
737     /**
738      * Same as Context#obtainStyledAttributes. We do not override the base method to give the
739      * original Context the chance to override the theme when needed.
740      */
741     @Nullable
internalObtainStyledAttributes(@ullable AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)742     public BridgeTypedArray internalObtainStyledAttributes(@Nullable AttributeSet set, int[] attrs,
743             int defStyleAttr, int defStyleRes) {
744 
745         Map<ResourceReference, ResourceValue> defaultPropMap = null;
746         Object key = null;
747 
748         ResourceNamespace currentFileNamespace;
749         ResourceNamespace.Resolver resolver;
750 
751         // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
752         if (set instanceof BridgeXmlBlockParser) {
753             BridgeXmlBlockParser parser;
754             parser = (BridgeXmlBlockParser)set;
755 
756             key = parser.getViewCookie();
757             if (key != null) {
758                 defaultPropMap = mDefaultPropMaps.computeIfAbsent(key, k -> new HashMap<>());
759             }
760 
761             currentFileNamespace = parser.getFileResourceNamespace();
762             resolver = new XmlPullParserResolver(parser, mLayoutlibCallback.getImplicitNamespaces());
763         } else if (set instanceof BridgeLayoutParamsMapAttributes) {
764             // This is for temp layout params generated dynamically in MockView. The set contains
765             // hardcoded values and we don't need to worry about resolving them.
766             currentFileNamespace = ResourceNamespace.RES_AUTO;
767             resolver = Resolver.EMPTY_RESOLVER;
768         } else if (set != null) {
769             // really this should not be happening since its instantiated in Bridge
770             Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
771                     "Parser is not a BridgeXmlBlockParser!", null, null);
772             return null;
773         } else {
774             // `set` is null, so there will be no values to resolve.
775             currentFileNamespace = ResourceNamespace.RES_AUTO;
776             resolver = Resolver.EMPTY_RESOLVER;
777         }
778 
779         List<AttributeHolder> attributeList = searchAttrs(attrs);
780 
781         BridgeTypedArray ta =
782                 Resources_Delegate.newTypeArray(mSystemResources, attrs.length);
783 
784         // Look for a custom style.
785         StyleResourceValue customStyleValues = null;
786         if (set != null) {
787             String customStyle = set.getAttributeValue(null, "style");
788             if (customStyle != null) {
789                 ResourceValue resolved = mRenderResources.resolveResValue(
790                         new UnresolvedResourceValue(customStyle, currentFileNamespace, resolver));
791 
792                 if (resolved instanceof StyleResourceValue) {
793                     customStyleValues = (StyleResourceValue) resolved;
794                 }
795             }
796         }
797 
798         // resolve the defStyleAttr value into a StyleResourceValue
799         StyleResourceValue defStyleValues = null;
800 
801         if (defStyleAttr != 0) {
802             // get the name from the int.
803             ResourceReference defStyleAttribute = searchAttr(defStyleAttr);
804 
805             if (defStyleAttribute == null) {
806                 // This should be rare. Happens trying to map R.style.foo to @style/foo fails.
807                 // This will happen if the user explicitly used a non existing int value for
808                 // defStyleAttr or there's something wrong with the project structure/build.
809                 Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE,
810                         "Failed to find the style corresponding to the id " + defStyleAttr, null,
811                         null);
812             } else {
813                 // look for the style in the current theme, and its parent:
814                 ResourceValue item = mRenderResources.findItemInTheme(defStyleAttribute);
815 
816                 if (item != null) {
817                     if (key != null) {
818                         mDefaultStyleMap.put(key, defStyleAttribute);
819                     }
820                     // item is a reference to a style entry. Search for it.
821                     item = mRenderResources.resolveResValue(item);
822                     if (item instanceof StyleResourceValue) {
823                         defStyleValues = (StyleResourceValue) item;
824                     }
825                 }
826             }
827         }
828 
829         if (defStyleValues == null && defStyleRes != 0) {
830             StyleResourceValue item = getStyleByDynamicId(defStyleRes);
831             if (item != null) {
832                 defStyleValues = item;
833             } else {
834                 ResourceReference value = Bridge.resolveResourceId(defStyleRes);
835                 if (value == null) {
836                     value = mLayoutlibCallback.resolveResourceId(defStyleRes);
837                 }
838 
839                 if (value != null) {
840                     if ((value.getResourceType() == ResourceType.STYLE)) {
841                         // look for the style in all resources:
842                         item = mRenderResources.getStyle(value);
843                         if (item != null) {
844                             if (key != null) {
845                                 mDefaultStyleMap.put(key, item.asReference());
846                             }
847 
848                             defStyleValues = item;
849                         } else {
850                             Bridge.getLog().error(null,
851                                     String.format(
852                                             "Style with id 0x%x (resolved to '%s') does not exist.",
853                                             defStyleRes, value.getName()),
854                                     null, null);
855                         }
856                     } else {
857                         Bridge.getLog().error(null,
858                                 String.format(
859                                         "Resource id 0x%x is not of type STYLE (instead %s)",
860                                         defStyleRes, value.getResourceType().name()),
861                                 null, null);
862                     }
863                 } else {
864                     Bridge.getLog().error(null,
865                             String.format(
866                                     "Failed to find style with id 0x%x in current theme",
867                                     defStyleRes),
868                             null, null);
869                 }
870             }
871         }
872 
873         if (attributeList != null) {
874             for (int index = 0 ; index < attributeList.size() ; index++) {
875                 AttributeHolder attributeHolder = attributeList.get(index);
876 
877                 if (attributeHolder == null) {
878                     continue;
879                 }
880 
881                 String attrName = attributeHolder.getName();
882                 String value = null;
883                 if (set != null) {
884                     value = set.getAttributeValue(
885                             attributeHolder.getNamespace().getXmlNamespaceUri(), attrName);
886 
887                     // if this is an app attribute, and the first get fails, try with the
888                     // new res-auto namespace as well
889                     if (attributeHolder.getNamespace() != ResourceNamespace.ANDROID && value == null) {
890                         value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
891                     }
892                 }
893 
894                 // Calculate the default value from the Theme in two cases:
895                 //   - If defaultPropMap is not null, get the default value to add it to the list
896                 //   of default values of properties.
897                 //   - If value is null, it means that the attribute is not directly set as an
898                 //   attribute in the XML so try to get the default value.
899                 ResourceValue defaultValue = null;
900                 if (defaultPropMap != null || value == null) {
901                     // look for the value in the custom style first (and its parent if needed)
902                     ResourceReference attrRef = attributeHolder.asReference();
903                     if (customStyleValues != null) {
904                         defaultValue =
905                                 mRenderResources.findItemInStyle(customStyleValues, attrRef);
906                     }
907 
908                     // then look for the value in the default Style (and its parent if needed)
909                     if (defaultValue == null && defStyleValues != null) {
910                         defaultValue =
911                                 mRenderResources.findItemInStyle(defStyleValues, attrRef);
912                     }
913 
914                     // if the item is not present in the defStyle, we look in the main theme (and
915                     // its parent themes)
916                     if (defaultValue == null) {
917                         defaultValue =
918                                 mRenderResources.findItemInTheme(attrRef);
919                     }
920 
921                     // if we found a value, we make sure this doesn't reference another value.
922                     // So we resolve it.
923                     if (defaultValue != null) {
924                         if (defaultPropMap != null) {
925                             defaultPropMap.put(attrRef, defaultValue);
926                         }
927 
928                         defaultValue = mRenderResources.resolveResValue(defaultValue);
929                     }
930                 }
931                 // Done calculating the defaultValue.
932 
933                 // If there's no direct value for this attribute in the XML, we look for default
934                 // values in the widget defStyle, and then in the theme.
935                 if (value == null) {
936                     if (attributeHolder.getNamespace() == ResourceNamespace.ANDROID) {
937                         // For some framework values, layoutlib patches the actual value in the
938                         // theme when it helps to improve the final preview. In most cases
939                         // we just disable animations.
940                         ResourceValue patchedValue = FRAMEWORK_PATCHED_VALUES.get(attrName);
941                         if (patchedValue != null) {
942                             defaultValue = patchedValue;
943                         }
944                     }
945 
946                     // If we found a value, we make sure this doesn't reference another value.
947                     // So we resolve it.
948                     if (defaultValue != null) {
949                         // If the value is a reference to another theme attribute that doesn't
950                         // exist, we should log a warning and omit it.
951                         String val = defaultValue.getValue();
952                         if (val != null && val.startsWith(SdkConstants.PREFIX_THEME_REF)) {
953                             // Because we always use the latest framework code, some resources might
954                             // fail to resolve when using old themes (they haven't been backported).
955                             // Since this is an artifact caused by us using always the latest
956                             // code, we check for some of those values and replace them here.
957                             ResourceReference reference = defaultValue.getReference();
958                             defaultValue = FRAMEWORK_REPLACE_VALUES.get(attrName);
959 
960                             // Only log a warning if the referenced value isn't one of the RTL
961                             // attributes, or the app targets old API.
962                             if (defaultValue == null &&
963                                     (getApplicationInfo().targetSdkVersion < JELLY_BEAN_MR1 ||
964                                     !attrName.equals(RTL_ATTRS.get(val)))) {
965                                 if (reference != null) {
966                                     val = reference.getResourceUrl().toString();
967                                 }
968                                 Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
969                                         String.format("Failed to find '%s' in current theme.", val),
970                                         null, val);
971                             }
972                         }
973                     }
974 
975                     ta.bridgeSetValue(
976                             index,
977                             attrName, attributeHolder.getNamespace(),
978                             attributeHolder.getResourceId(),
979                             defaultValue);
980                 } else {
981                     // There is a value in the XML, but we need to resolve it in case it's
982                     // referencing another resource or a theme value.
983                     ta.bridgeSetValue(
984                             index,
985                             attrName, attributeHolder.getNamespace(),
986                             attributeHolder.getResourceId(),
987                             mRenderResources.resolveResValue(
988                                     new UnresolvedResourceValue(
989                                             value, currentFileNamespace, resolver)));
990                 }
991             }
992         }
993 
994         ta.sealArray();
995 
996         return ta;
997     }
998 
999     @Override
getMainLooper()1000     public Looper getMainLooper() {
1001         return Looper.myLooper();
1002     }
1003 
1004 
1005     @Override
getPackageName()1006     public String getPackageName() {
1007         if (mApplicationInfo.packageName == null) {
1008             mApplicationInfo.packageName = mLayoutlibCallback.getFlag(FLAG_KEY_APPLICATION_PACKAGE);
1009         }
1010         return mApplicationInfo.packageName;
1011     }
1012 
1013     @Override
getPackageManager()1014     public PackageManager getPackageManager() {
1015         if (mPackageManager == null) {
1016             mPackageManager = new BridgePackageManager();
1017         }
1018         return mPackageManager;
1019     }
1020 
1021     @Override
registerComponentCallbacks(ComponentCallbacks callback)1022     public void registerComponentCallbacks(ComponentCallbacks callback) {}
1023 
1024     @Override
unregisterComponentCallbacks(ComponentCallbacks callback)1025     public void unregisterComponentCallbacks(ComponentCallbacks callback) {}
1026 
1027     // ------------- private new methods
1028 
1029     /**
1030      * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
1031      * values found in the given style. If no style is specified, the default theme, along with the
1032      * styles applied to it are used.
1033      *
1034      * @see #obtainStyledAttributes(int, int[])
1035      */
createStyleBasedTypedArray( @ullable StyleResourceValue style, int[] attrs)1036     private Pair<BridgeTypedArray, Map<ResourceReference, ResourceValue>> createStyleBasedTypedArray(
1037             @Nullable StyleResourceValue style, int[] attrs) throws Resources.NotFoundException {
1038         List<AttributeHolder> attributes = searchAttrs(attrs);
1039 
1040         BridgeTypedArray ta =
1041                 Resources_Delegate.newTypeArray(mSystemResources, attrs.length);
1042 
1043         Map<ResourceReference, ResourceValue> defaultPropMap = new HashMap<>();
1044         // for each attribute, get its name so that we can search it in the style
1045         for (int i = 0; i < attrs.length; i++) {
1046             AttributeHolder attrHolder = attributes.get(i);
1047 
1048             if (attrHolder != null) {
1049                 // look for the value in the given style
1050                 ResourceValue resValue;
1051                 if (style != null) {
1052                     resValue = mRenderResources.findItemInStyle(style, attrHolder.asReference());
1053                 } else {
1054                     resValue = mRenderResources.findItemInTheme(attrHolder.asReference());
1055                 }
1056 
1057                 if (resValue != null) {
1058                     defaultPropMap.put(attrHolder.asReference(), resValue);
1059                     // resolve it to make sure there are no references left.
1060                     resValue = mRenderResources.resolveResValue(resValue);
1061                     ta.bridgeSetValue(
1062                             i, attrHolder.getName(), attrHolder.getNamespace(),
1063                             attrHolder.getResourceId(),
1064                             resValue);
1065                 }
1066             }
1067         }
1068 
1069         ta.sealArray();
1070 
1071         return Pair.of(ta, defaultPropMap);
1072     }
1073 
1074     /**
1075      * The input int[] attributeIds is a list of attributes. The returns a list of information about
1076      * each attributes. The information is (name, isFramework)
1077      * <p/>
1078      *
1079      * @param attributeIds An attribute array reference given to obtainStyledAttributes.
1080      * @return List of attribute information.
1081      */
searchAttrs(int[] attributeIds)1082     private List<AttributeHolder> searchAttrs(int[] attributeIds) {
1083         List<AttributeHolder> results = new ArrayList<>(attributeIds.length);
1084 
1085         // for each attribute, get its name so that we can search it in the style
1086         for (int id : attributeIds) {
1087             ResourceReference refForId = Bridge.resolveResourceId(id);
1088             if (refForId == null) {
1089                 refForId = mLayoutlibCallback.resolveResourceId(id);
1090             }
1091 
1092             if (refForId != null) {
1093                 results.add(new AttributeHolder(id, refForId));
1094             } else {
1095                 results.add(null);
1096             }
1097         }
1098 
1099         return results;
1100     }
1101 
1102     /**
1103      * Searches for the attribute referenced by its internal id.
1104      */
searchAttr(int attrId)1105     private ResourceReference searchAttr(int attrId) {
1106         ResourceReference attr = Bridge.resolveResourceId(attrId);
1107         if (attr == null) {
1108             attr = mLayoutlibCallback.resolveResourceId(attrId);
1109         }
1110 
1111         return attr;
1112     }
1113 
1114     /**
1115      * Maps a given style to a numeric id.
1116      *
1117      * <p>For now Bridge handles numeric ids (both fixed and dynamic) for framework and the callback
1118      * for non-framework. TODO(b/156609434): teach the IDE about fixed framework ids and handle this
1119      * all in the callback.
1120      */
getDynamicIdByStyle(StyleResourceValue resValue)1121     public int getDynamicIdByStyle(StyleResourceValue resValue) {
1122         if (resValue.isFramework()) {
1123             return Bridge.getResourceId(resValue.getResourceType(), resValue.getName());
1124         } else {
1125             return mLayoutlibCallback.getOrGenerateResourceId(resValue.asReference());
1126         }
1127     }
1128 
1129     /**
1130      * Maps a numeric id back to {@link StyleResourceValue}.
1131      *
1132      * <p>For now framework numeric ids are handled by Bridge, so try there first and fall back to
1133      * the callback, which manages ids for non-framework resources. TODO(b/156609434): manage all
1134      * ids in the IDE.
1135      *
1136      * <p>Once we the resource for the given id, we ask the IDE to get the
1137      * {@link StyleResourceValue} for it.
1138      */
1139     @Nullable
getStyleByDynamicId(int id)1140     private StyleResourceValue getStyleByDynamicId(int id) {
1141         ResourceReference reference = Bridge.resolveResourceId(id);
1142         if (reference == null) {
1143             reference = mLayoutlibCallback.resolveResourceId(id);
1144         }
1145 
1146         if (reference == null) {
1147             return null;
1148         }
1149 
1150         return mRenderResources.getStyle(reference);
1151     }
1152 
getResourceId(@onNull ResourceReference resource, int defValue)1153     public int getResourceId(@NonNull ResourceReference resource, int defValue) {
1154         if (getRenderResources().getUnresolvedResource(resource) != null) {
1155             if (resource.getNamespace().equals(ResourceNamespace.ANDROID)) {
1156                 return Bridge.getResourceId(resource.getResourceType(), resource.getName());
1157             } else if (mLayoutlibCallback != null) {
1158                 return mLayoutlibCallback.getOrGenerateResourceId(resource);
1159             }
1160         }
1161 
1162         return defValue;
1163     }
1164 
getBaseContext(Context context)1165     public static Context getBaseContext(Context context) {
1166         while (context instanceof ContextWrapper) {
1167             context = ((ContextWrapper) context).getBaseContext();
1168         }
1169         return context;
1170     }
1171 
1172     /**
1173      * Returns the Framework attr resource reference with the given name.
1174      */
1175     @NonNull
createFrameworkAttrReference(@onNull String name)1176     public static ResourceReference createFrameworkAttrReference(@NonNull String name) {
1177         return createFrameworkResourceReference(ResourceType.ATTR, name);
1178     }
1179 
1180     /**
1181      * Returns the Framework resource reference with the given type and name.
1182      */
1183     @NonNull
createFrameworkResourceReference(@onNull ResourceType type, @NonNull String name)1184     public static ResourceReference createFrameworkResourceReference(@NonNull ResourceType type,
1185             @NonNull String name) {
1186         return new ResourceReference(ResourceNamespace.ANDROID, type, name);
1187     }
1188 
1189     /**
1190      * Returns the AppCompat attr resource reference with the given name.
1191      */
1192     @NonNull
createAppCompatAttrReference(@onNull String name)1193     public ResourceReference createAppCompatAttrReference(@NonNull String name) {
1194         return createAppCompatResourceReference(ResourceType.ATTR, name);
1195     }
1196 
1197     /**
1198      * Returns the AppCompat resource reference with the given type and name.
1199      */
1200     @NonNull
createAppCompatResourceReference(@onNull ResourceType type, @NonNull String name)1201     public ResourceReference createAppCompatResourceReference(@NonNull ResourceType type,
1202             @NonNull String name) {
1203         return new ResourceReference(mAppCompatNamespace, type, name);
1204     }
1205 
getBinder()1206     public IBinder getBinder() {
1207         if (mBinder == null) {
1208             // create a no-op binder. We only need it be not null.
1209             mBinder = new IBinder() {
1210                 @Override
1211                 public String getInterfaceDescriptor() throws RemoteException {
1212                     return null;
1213                 }
1214 
1215                 @Override
1216                 public boolean pingBinder() {
1217                     return false;
1218                 }
1219 
1220                 @Override
1221                 public boolean isBinderAlive() {
1222                     return false;
1223                 }
1224 
1225                 @Override
1226                 public IInterface queryLocalInterface(String descriptor) {
1227                     return null;
1228                 }
1229 
1230                 @Override
1231                 public void dump(FileDescriptor fd, String[] args) throws RemoteException {
1232 
1233                 }
1234 
1235                 @Override
1236                 public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
1237 
1238                 }
1239 
1240                 @Override
1241                 public boolean transact(int code, Parcel data, Parcel reply, int flags)
1242                         throws RemoteException {
1243                     return false;
1244                 }
1245 
1246                 @Override
1247                 public void linkToDeath(DeathRecipient recipient, int flags)
1248                         throws RemoteException {
1249 
1250                 }
1251 
1252                 @Override
1253                 public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
1254                     return false;
1255                 }
1256 
1257                 @Override
1258                 public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
1259                   String[] args, ShellCallback shellCallback, ResultReceiver resultReceiver) {
1260                 }
1261             };
1262         }
1263         return mBinder;
1264     }
1265 
1266     //------------ NOT OVERRIDEN --------------------
1267 
1268     @Override
bindService(Intent arg0, ServiceConnection arg1, int arg2)1269     public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
1270         // pass
1271         return false;
1272     }
1273 
1274     @Override
bindService(Intent arg0, int arg1, Executor arg2, ServiceConnection arg3)1275     public boolean bindService(Intent arg0, int arg1, Executor arg2, ServiceConnection arg3) {
1276         return false;
1277     }
1278 
1279     @Override
bindIsolatedService(Intent arg0, int arg1, String arg2, Executor arg3, ServiceConnection arg4)1280     public boolean bindIsolatedService(Intent arg0,
1281             int arg1, String arg2, Executor arg3, ServiceConnection arg4) {
1282         return false;
1283     }
1284 
1285     @Override
checkCallingOrSelfPermission(String arg0)1286     public int checkCallingOrSelfPermission(String arg0) {
1287         // pass
1288         return 0;
1289     }
1290 
1291     @Override
checkCallingOrSelfUriPermission(Uri arg0, int arg1)1292     public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
1293         // pass
1294         return 0;
1295     }
1296 
1297     @Override
checkCallingPermission(String arg0)1298     public int checkCallingPermission(String arg0) {
1299         // pass
1300         return 0;
1301     }
1302 
1303     @Override
checkCallingUriPermission(Uri arg0, int arg1)1304     public int checkCallingUriPermission(Uri arg0, int arg1) {
1305         // pass
1306         return 0;
1307     }
1308 
1309     @Override
checkPermission(String arg0, int arg1, int arg2)1310     public int checkPermission(String arg0, int arg1, int arg2) {
1311         // pass
1312         return 0;
1313     }
1314 
1315     @Override
checkSelfPermission(String arg0)1316     public int checkSelfPermission(String arg0) {
1317         // pass
1318         return 0;
1319     }
1320 
1321     @Override
checkPermission(String arg0, int arg1, int arg2, IBinder arg3)1322     public int checkPermission(String arg0, int arg1, int arg2, IBinder arg3) {
1323         // pass
1324         return 0;
1325     }
1326 
1327     @Override
checkUriPermission(Uri arg0, int arg1, int arg2, int arg3)1328     public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
1329         // pass
1330         return 0;
1331     }
1332 
1333     @Override
checkUriPermission(Uri arg0, int arg1, int arg2, int arg3, IBinder arg4)1334     public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3, IBinder arg4) {
1335         // pass
1336         return 0;
1337     }
1338 
1339     @Override
checkUriPermission(Uri arg0, String arg1, String arg2, int arg3, int arg4, int arg5)1340     public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
1341             int arg4, int arg5) {
1342         // pass
1343         return 0;
1344     }
1345 
1346     @Override
clearWallpaper()1347     public void clearWallpaper() {
1348         // pass
1349 
1350     }
1351 
1352     @Override
createPackageContext(String arg0, int arg1)1353     public Context createPackageContext(String arg0, int arg1) {
1354         // pass
1355         return null;
1356     }
1357 
1358     @Override
createPackageContextAsUser(String arg0, int arg1, UserHandle user)1359     public Context createPackageContextAsUser(String arg0, int arg1, UserHandle user) {
1360         // pass
1361         return null;
1362     }
1363 
1364     @Override
createConfigurationContext(Configuration overrideConfiguration)1365     public Context createConfigurationContext(Configuration overrideConfiguration) {
1366         // pass
1367         return null;
1368     }
1369 
1370     @Override
createDisplayContext(Display display)1371     public Context createDisplayContext(Display display) {
1372         // pass
1373         return null;
1374     }
1375 
1376     @Override
createContextForSplit(String splitName)1377     public Context createContextForSplit(String splitName) {
1378         // pass
1379         return null;
1380     }
1381 
1382     @Override
databaseList()1383     public String[] databaseList() {
1384         // pass
1385         return null;
1386     }
1387 
1388     @Override
createApplicationContext(ApplicationInfo application, int flags)1389     public Context createApplicationContext(ApplicationInfo application, int flags)
1390             throws PackageManager.NameNotFoundException {
1391         return null;
1392     }
1393 
1394     @Override
moveDatabaseFrom(Context sourceContext, String name)1395     public boolean moveDatabaseFrom(Context sourceContext, String name) {
1396         // pass
1397         return false;
1398     }
1399 
1400     @Override
deleteDatabase(String arg0)1401     public boolean deleteDatabase(String arg0) {
1402         // pass
1403         return false;
1404     }
1405 
1406     @Override
deleteFile(String arg0)1407     public boolean deleteFile(String arg0) {
1408         // pass
1409         return false;
1410     }
1411 
1412     @Override
enforceCallingOrSelfPermission(String arg0, String arg1)1413     public void enforceCallingOrSelfPermission(String arg0, String arg1) {
1414         // pass
1415 
1416     }
1417 
1418     @Override
enforceCallingOrSelfUriPermission(Uri arg0, int arg1, String arg2)1419     public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
1420             String arg2) {
1421         // pass
1422 
1423     }
1424 
1425     @Override
enforceCallingPermission(String arg0, String arg1)1426     public void enforceCallingPermission(String arg0, String arg1) {
1427         // pass
1428 
1429     }
1430 
1431     @Override
enforceCallingUriPermission(Uri arg0, int arg1, String arg2)1432     public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
1433         // pass
1434 
1435     }
1436 
1437     @Override
enforcePermission(String arg0, int arg1, int arg2, String arg3)1438     public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
1439         // pass
1440 
1441     }
1442 
1443     @Override
enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3, String arg4)1444     public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
1445             String arg4) {
1446         // pass
1447 
1448     }
1449 
1450     @Override
enforceUriPermission(Uri arg0, String arg1, String arg2, int arg3, int arg4, int arg5, String arg6)1451     public void enforceUriPermission(Uri arg0, String arg1, String arg2,
1452             int arg3, int arg4, int arg5, String arg6) {
1453         // pass
1454 
1455     }
1456 
1457     @Override
fileList()1458     public String[] fileList() {
1459         // pass
1460         return null;
1461     }
1462 
1463     @Override
getAssets()1464     public BridgeAssetManager getAssets() {
1465         return mAssets;
1466     }
1467 
1468     @Override
getCacheDir()1469     public File getCacheDir() {
1470         // pass
1471         return null;
1472     }
1473 
1474     @Override
getCodeCacheDir()1475     public File getCodeCacheDir() {
1476         // pass
1477         return null;
1478     }
1479 
1480     @Override
getExternalCacheDir()1481     public File getExternalCacheDir() {
1482         // pass
1483         return null;
1484     }
1485 
1486     @Override
getPreloadsFileCache()1487     public File getPreloadsFileCache() {
1488         // pass
1489         return null;
1490     }
1491 
1492     @Override
getContentResolver()1493     public ContentResolver getContentResolver() {
1494         if (mContentResolver == null) {
1495             mContentResolver = new BridgeContentResolver(this);
1496         }
1497         return mContentResolver;
1498     }
1499 
1500     @Override
getDatabasePath(String arg0)1501     public File getDatabasePath(String arg0) {
1502         // pass
1503         return null;
1504     }
1505 
1506     @Override
getDir(String arg0, int arg1)1507     public File getDir(String arg0, int arg1) {
1508         // pass
1509         return null;
1510     }
1511 
1512     @Override
getFileStreamPath(String arg0)1513     public File getFileStreamPath(String arg0) {
1514         // pass
1515         return null;
1516     }
1517 
1518     @Override
getSharedPreferencesPath(String name)1519     public File getSharedPreferencesPath(String name) {
1520         // pass
1521         return null;
1522     }
1523 
1524     @Override
getDataDir()1525     public File getDataDir() {
1526         // pass
1527         return null;
1528     }
1529 
1530     @Override
getFilesDir()1531     public File getFilesDir() {
1532         // pass
1533         return null;
1534     }
1535 
1536     @Override
getNoBackupFilesDir()1537     public File getNoBackupFilesDir() {
1538         // pass
1539         return null;
1540     }
1541 
1542     @Override
getExternalFilesDir(String type)1543     public File getExternalFilesDir(String type) {
1544         // pass
1545         return null;
1546     }
1547 
1548     @Override
getPackageCodePath()1549     public String getPackageCodePath() {
1550         // pass
1551         return null;
1552     }
1553 
1554     @Override
getBasePackageName()1555     public String getBasePackageName() {
1556         // pass
1557         return null;
1558     }
1559 
1560     @Override
getOpPackageName()1561     public String getOpPackageName() {
1562         // pass
1563         return null;
1564     }
1565 
1566     @Override
getApplicationInfo()1567     public ApplicationInfo getApplicationInfo() {
1568         return mApplicationInfo;
1569     }
1570 
1571     @Override
getPackageResourcePath()1572     public String getPackageResourcePath() {
1573         // pass
1574         return null;
1575     }
1576 
1577     @Override
getSharedPreferences(String arg0, int arg1)1578     public SharedPreferences getSharedPreferences(String arg0, int arg1) {
1579         if (mSharedPreferences == null) {
1580             mSharedPreferences = new BridgeSharedPreferences();
1581         }
1582         return mSharedPreferences;
1583     }
1584 
1585     @Override
getSharedPreferences(File arg0, int arg1)1586     public SharedPreferences getSharedPreferences(File arg0, int arg1) {
1587         if (mSharedPreferences == null) {
1588             mSharedPreferences = new BridgeSharedPreferences();
1589         }
1590         return mSharedPreferences;
1591     }
1592 
1593     @Override
reloadSharedPreferences()1594     public void reloadSharedPreferences() {
1595         // intentional noop
1596     }
1597 
1598     @Override
moveSharedPreferencesFrom(Context sourceContext, String name)1599     public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
1600         // pass
1601         return false;
1602     }
1603 
1604     @Override
deleteSharedPreferences(String name)1605     public boolean deleteSharedPreferences(String name) {
1606         // pass
1607         return false;
1608     }
1609 
1610     @Override
getWallpaper()1611     public Drawable getWallpaper() {
1612         // pass
1613         return null;
1614     }
1615 
1616     @Override
getWallpaperDesiredMinimumWidth()1617     public int getWallpaperDesiredMinimumWidth() {
1618         return -1;
1619     }
1620 
1621     @Override
getWallpaperDesiredMinimumHeight()1622     public int getWallpaperDesiredMinimumHeight() {
1623         return -1;
1624     }
1625 
1626     @Override
grantUriPermission(String arg0, Uri arg1, int arg2)1627     public void grantUriPermission(String arg0, Uri arg1, int arg2) {
1628         // pass
1629 
1630     }
1631 
1632     @Override
openFileInput(String arg0)1633     public FileInputStream openFileInput(String arg0) throws FileNotFoundException {
1634         // pass
1635         return null;
1636     }
1637 
1638     @Override
openFileOutput(String arg0, int arg1)1639     public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException {
1640         // pass
1641         return null;
1642     }
1643 
1644     @Override
openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2)1645     public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) {
1646         // pass
1647         return null;
1648     }
1649 
1650     @Override
openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2, DatabaseErrorHandler arg3)1651     public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
1652             CursorFactory arg2, DatabaseErrorHandler arg3) {
1653         // pass
1654         return null;
1655     }
1656 
1657     @Override
peekWallpaper()1658     public Drawable peekWallpaper() {
1659         // pass
1660         return null;
1661     }
1662 
1663     @Override
registerReceiver(BroadcastReceiver arg0, IntentFilter arg1)1664     public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
1665         // pass
1666         return null;
1667     }
1668 
1669     @Override
registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, int arg2)1670     public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, int arg2) {
1671         // pass
1672         return null;
1673     }
1674 
1675     @Override
registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, String arg2, Handler arg3)1676     public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
1677             String arg2, Handler arg3) {
1678         // pass
1679         return null;
1680     }
1681 
1682     @Override
registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, String arg2, Handler arg3, int arg4)1683     public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
1684             String arg2, Handler arg3, int arg4) {
1685         // pass
1686         return null;
1687     }
1688 
1689     @Override
registerReceiverAsUser(BroadcastReceiver arg0, UserHandle arg0p5, IntentFilter arg1, String arg2, Handler arg3)1690     public Intent registerReceiverAsUser(BroadcastReceiver arg0, UserHandle arg0p5,
1691             IntentFilter arg1, String arg2, Handler arg3) {
1692         // pass
1693         return null;
1694     }
1695 
1696     @Override
removeStickyBroadcast(Intent arg0)1697     public void removeStickyBroadcast(Intent arg0) {
1698         // pass
1699 
1700     }
1701 
1702     @Override
revokeUriPermission(Uri arg0, int arg1)1703     public void revokeUriPermission(Uri arg0, int arg1) {
1704         // pass
1705 
1706     }
1707 
1708     @Override
revokeUriPermission(String arg0, Uri arg1, int arg2)1709     public void revokeUriPermission(String arg0, Uri arg1, int arg2) {
1710         // pass
1711 
1712     }
1713 
1714     @Override
sendBroadcast(Intent arg0)1715     public void sendBroadcast(Intent arg0) {
1716         // pass
1717 
1718     }
1719 
1720     @Override
sendBroadcast(Intent arg0, String arg1)1721     public void sendBroadcast(Intent arg0, String arg1) {
1722         // pass
1723 
1724     }
1725 
1726     @Override
sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions)1727     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
1728         // pass
1729 
1730     }
1731 
1732     @Override
sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, String[] receiverPermissions)1733     public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
1734             String[] receiverPermissions) {
1735         // pass
1736 
1737     }
1738 
1739     @Override
sendBroadcast(Intent arg0, String arg1, Bundle arg2)1740     public void sendBroadcast(Intent arg0, String arg1, Bundle arg2) {
1741         // pass
1742 
1743     }
1744 
1745     @Override
sendBroadcast(Intent intent, String receiverPermission, int appOp)1746     public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
1747         // pass
1748     }
1749 
1750     @Override
sendOrderedBroadcast(Intent arg0, String arg1)1751     public void sendOrderedBroadcast(Intent arg0, String arg1) {
1752         // pass
1753 
1754     }
1755 
1756     @Override
sendOrderedBroadcast(Intent arg0, String arg1, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5, Bundle arg6)1757     public void sendOrderedBroadcast(Intent arg0, String arg1,
1758             BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
1759             Bundle arg6) {
1760         // pass
1761 
1762     }
1763 
1764     @Override
sendOrderedBroadcast(Intent arg0, String arg1, Bundle arg7, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5, Bundle arg6)1765     public void sendOrderedBroadcast(Intent arg0, String arg1,
1766             Bundle arg7, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
1767             Bundle arg6) {
1768         // pass
1769 
1770     }
1771 
1772     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1773     public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
1774             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
1775             String initialData, Bundle initialExtras) {
1776         // pass
1777     }
1778 
1779     @Override
sendBroadcastAsUser(Intent intent, UserHandle user)1780     public void sendBroadcastAsUser(Intent intent, UserHandle user) {
1781         // pass
1782     }
1783 
1784     @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)1785     public void sendBroadcastAsUser(Intent intent, UserHandle user,
1786             String receiverPermission) {
1787         // pass
1788     }
1789 
1790     @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, Bundle options)1791     public void sendBroadcastAsUser(Intent intent, UserHandle user,
1792             String receiverPermission, Bundle options) {
1793         // pass
1794     }
1795 
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp)1796     public void sendBroadcastAsUser(Intent intent, UserHandle user,
1797             String receiverPermission, int appOp) {
1798         // pass
1799     }
1800 
1801     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1802     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1803             String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
1804             int initialCode, String initialData, Bundle initialExtras) {
1805         // pass
1806     }
1807 
1808     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1809     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1810             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
1811             Handler scheduler,
1812             int initialCode, String initialData, Bundle initialExtras) {
1813         // pass
1814     }
1815 
1816     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1817     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1818             String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
1819             Handler scheduler,
1820             int initialCode, String initialData, Bundle initialExtras) {
1821         // pass
1822     }
1823 
1824     @Override
sendStickyBroadcast(Intent arg0)1825     public void sendStickyBroadcast(Intent arg0) {
1826         // pass
1827 
1828     }
1829 
1830     @Override
sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1831     public void sendStickyOrderedBroadcast(Intent intent,
1832             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
1833            Bundle initialExtras) {
1834         // pass
1835     }
1836 
1837     @Override
sendStickyBroadcastAsUser(Intent intent, UserHandle user)1838     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
1839         // pass
1840     }
1841 
1842     @Override
sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options)1843     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
1844         // pass
1845     }
1846 
1847     @Override
sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1848     public void sendStickyOrderedBroadcastAsUser(Intent intent,
1849             UserHandle user, BroadcastReceiver resultReceiver,
1850             Handler scheduler, int initialCode, String initialData,
1851             Bundle initialExtras) {
1852         // pass
1853     }
1854 
1855     @Override
removeStickyBroadcastAsUser(Intent intent, UserHandle user)1856     public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
1857         // pass
1858     }
1859 
1860     @Override
setTheme(int arg0)1861     public void setTheme(int arg0) {
1862         // pass
1863 
1864     }
1865 
1866     @Override
setWallpaper(Bitmap arg0)1867     public void setWallpaper(Bitmap arg0) throws IOException {
1868         // pass
1869 
1870     }
1871 
1872     @Override
setWallpaper(InputStream arg0)1873     public void setWallpaper(InputStream arg0) throws IOException {
1874         // pass
1875 
1876     }
1877 
1878     @Override
startActivity(Intent arg0)1879     public void startActivity(Intent arg0) {
1880         // pass
1881     }
1882 
1883     @Override
startActivity(Intent arg0, Bundle arg1)1884     public void startActivity(Intent arg0, Bundle arg1) {
1885         // pass
1886     }
1887 
1888     @Override
startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)1889     public void startIntentSender(IntentSender intent,
1890             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
1891             throws IntentSender.SendIntentException {
1892         // pass
1893     }
1894 
1895     @Override
startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options)1896     public void startIntentSender(IntentSender intent,
1897             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
1898             Bundle options) throws IntentSender.SendIntentException {
1899         // pass
1900     }
1901 
1902     @Override
startInstrumentation(ComponentName arg0, String arg1, Bundle arg2)1903     public boolean startInstrumentation(ComponentName arg0, String arg1,
1904             Bundle arg2) {
1905         // pass
1906         return false;
1907     }
1908 
1909     @Override
startService(Intent arg0)1910     public ComponentName startService(Intent arg0) {
1911         // pass
1912         return null;
1913     }
1914 
1915     @Override
startForegroundService(Intent service)1916     public ComponentName startForegroundService(Intent service) {
1917         // pass
1918         return null;
1919     }
1920 
1921     @Override
startForegroundServiceAsUser(Intent service, UserHandle user)1922     public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
1923         // pass
1924         return null;
1925     }
1926 
1927     @Override
stopService(Intent arg0)1928     public boolean stopService(Intent arg0) {
1929         // pass
1930         return false;
1931     }
1932 
1933     @Override
startServiceAsUser(Intent arg0, UserHandle arg1)1934     public ComponentName startServiceAsUser(Intent arg0, UserHandle arg1) {
1935         // pass
1936         return null;
1937     }
1938 
1939     @Override
stopServiceAsUser(Intent arg0, UserHandle arg1)1940     public boolean stopServiceAsUser(Intent arg0, UserHandle arg1) {
1941         // pass
1942         return false;
1943     }
1944 
1945     @Override
updateServiceGroup(@onNull ServiceConnection conn, int group, int importance)1946     public void updateServiceGroup(@NonNull ServiceConnection conn, int group,
1947             int importance) {
1948         // pass
1949     }
1950 
1951     @Override
unbindService(ServiceConnection arg0)1952     public void unbindService(ServiceConnection arg0) {
1953         // pass
1954 
1955     }
1956 
1957     @Override
unregisterReceiver(BroadcastReceiver arg0)1958     public void unregisterReceiver(BroadcastReceiver arg0) {
1959         // pass
1960 
1961     }
1962 
1963     @Override
getApplicationContext()1964     public Context getApplicationContext() {
1965         return this;
1966     }
1967 
1968     @Override
startActivities(Intent[] arg0)1969     public void startActivities(Intent[] arg0) {
1970         // pass
1971 
1972     }
1973 
1974     @Override
startActivities(Intent[] arg0, Bundle arg1)1975     public void startActivities(Intent[] arg0, Bundle arg1) {
1976         // pass
1977 
1978     }
1979 
1980     @Override
isRestricted()1981     public boolean isRestricted() {
1982         return false;
1983     }
1984 
1985     @Override
getObbDir()1986     public File getObbDir() {
1987         Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "OBB not supported", null, null);
1988         return null;
1989     }
1990 
1991     @Override
getDisplayAdjustments(int displayId)1992     public DisplayAdjustments getDisplayAdjustments(int displayId) {
1993         // pass
1994         return null;
1995     }
1996 
1997     @Override
getDisplay()1998     public Display getDisplay() {
1999         // pass
2000         return null;
2001     }
2002 
2003     @Override
getDisplayId()2004     public int getDisplayId() {
2005         // pass
2006         return 0;
2007     }
2008 
2009     @Override
updateDisplay(int displayId)2010     public void updateDisplay(int displayId) {
2011         // pass
2012     }
2013 
2014     @Override
getUserId()2015     public int getUserId() {
2016         return 0; // not used
2017     }
2018 
2019     @Override
getExternalFilesDirs(String type)2020     public File[] getExternalFilesDirs(String type) {
2021         // pass
2022         return new File[0];
2023     }
2024 
2025     @Override
getObbDirs()2026     public File[] getObbDirs() {
2027         // pass
2028         return new File[0];
2029     }
2030 
2031     @Override
getExternalCacheDirs()2032     public File[] getExternalCacheDirs() {
2033         // pass
2034         return new File[0];
2035     }
2036 
2037     @Override
getExternalMediaDirs()2038     public File[] getExternalMediaDirs() {
2039         // pass
2040         return new File[0];
2041     }
2042 
setScrollYPos(@onNull View view, int scrollPos)2043     public void setScrollYPos(@NonNull View view, int scrollPos) {
2044         mScrollYPos.put(view, scrollPos);
2045     }
2046 
getScrollYPos(@onNull View view)2047     public int getScrollYPos(@NonNull View view) {
2048         Integer pos = mScrollYPos.get(view);
2049         return pos != null ? pos : 0;
2050     }
2051 
setScrollXPos(@onNull View view, int scrollPos)2052     public void setScrollXPos(@NonNull View view, int scrollPos) {
2053         mScrollXPos.put(view, scrollPos);
2054     }
2055 
getScrollXPos(@onNull View view)2056     public int getScrollXPos(@NonNull View view) {
2057         Integer pos = mScrollXPos.get(view);
2058         return pos != null ? pos : 0;
2059     }
2060 
2061     @Override
createDeviceProtectedStorageContext()2062     public Context createDeviceProtectedStorageContext() {
2063         // pass
2064         return null;
2065     }
2066 
2067     @Override
createCredentialProtectedStorageContext()2068     public Context createCredentialProtectedStorageContext() {
2069         // pass
2070         return null;
2071     }
2072 
2073     @Override
isDeviceProtectedStorage()2074     public boolean isDeviceProtectedStorage() {
2075         return false;
2076     }
2077 
2078     @Override
isCredentialProtectedStorage()2079     public boolean isCredentialProtectedStorage() {
2080         return false;
2081     }
2082 
2083     @Override
canLoadUnsafeResources()2084     public boolean canLoadUnsafeResources() {
2085         return true;
2086     }
2087 
2088     @Override
isUiContext()2089     public boolean isUiContext() {
2090         return true;
2091     }
2092 
2093     /**
2094      * Returns whether shadows should be rendered or not
2095      */
isShadowsEnabled()2096     public boolean isShadowsEnabled() {
2097         return mShadowsEnabled;
2098     }
2099 
2100     /**
2101      * Returns whether high quality shadows should be used
2102      */
isHighQualityShadows()2103     public boolean isHighQualityShadows() {
2104         return mHighQualityShadows;
2105     }
2106 
putUserData(@onNull Key<T> key, @Nullable T data)2107     public <T> void putUserData(@NonNull Key<T> key, @Nullable T data) {
2108         mUserData.put(key, data);
2109     }
2110 
2111     @SuppressWarnings("unchecked")
2112     @Nullable
getUserData(@onNull Key<T> key)2113     public <T> T getUserData(@NonNull Key<T> key) {
2114         return (T) mUserData.get(key);
2115     }
2116 
2117     /** Logs an error message to the error log of the host application. */
error(@onNull String message, @NonNull String... details)2118     public void error(@NonNull String message, @NonNull String... details) {
2119         mLayoutlibCallback.error(message, details);
2120     }
2121 
2122     /** Logs an error message to the error log of the host application. */
error(@onNull String message, @Nullable Throwable t)2123     public void error(@NonNull String message, @Nullable Throwable t) {
2124         mLayoutlibCallback.error(message, t);
2125     }
2126 
2127     /** Logs an error message to the error log of the host application. */
error(@onNull Throwable t)2128     public void error(@NonNull Throwable t) {
2129         mLayoutlibCallback.error(t);
2130     }
2131 
2132     /** Logs a warning to the log of the host application. */
warn(@onNull String message, @Nullable Throwable t)2133     public void warn(@NonNull String message, @Nullable Throwable t) {
2134         mLayoutlibCallback.warn(message, t);
2135     }
2136 
2137     /** Logs a warning to the log of the host application. */
warn(@onNull Throwable t)2138     public void warn(@NonNull Throwable t) {
2139         mLayoutlibCallback.warn(t);
2140     }
2141 
2142     /**
2143      * No two Key instances are considered equal.
2144      *
2145      * @param <T> the type of values associated with the key
2146      */
2147     public static final class Key<T> {
2148         private final String name;
2149 
2150         @NonNull
create(@onNull String name)2151         public static <T> Key<T> create(@NonNull String name) {
2152             return new Key<T>(name);
2153         }
2154 
Key(@onNull String name)2155         private Key(@NonNull String name) {
2156             this.name = name;
2157         }
2158 
2159         /** For debugging only. */
2160         @Override
toString()2161         public String toString() {
2162             return name;
2163         }
2164     }
2165 
2166     private class AttributeHolder {
2167         private final int resourceId;
2168         @NonNull private final ResourceReference reference;
2169 
AttributeHolder(int resourceId, @NonNull ResourceReference reference)2170         private AttributeHolder(int resourceId, @NonNull ResourceReference reference) {
2171             this.resourceId = resourceId;
2172             this.reference = reference;
2173         }
2174 
2175         @NonNull
asReference()2176         private ResourceReference asReference() {
2177             return reference;
2178         }
2179 
getResourceId()2180         private int getResourceId() {
2181             return resourceId;
2182         }
2183 
2184         @NonNull
getName()2185         private String getName() {
2186             return reference.getName();
2187         }
2188 
2189         @NonNull
getNamespace()2190         private ResourceNamespace getNamespace() {
2191             return reference.getNamespace();
2192         }
2193     }
2194 
2195     /**
2196      * The cached value depends on
2197      * <ol>
2198      * <li>{@code int[]}: the attributes for which TypedArray is created </li>
2199      * <li>{@code List<StyleResourceValue>}: the themes set on the context at the time of
2200      * creation of the TypedArray</li>
2201      * <li>{@code Integer}: the default style used at the time of creation</li>
2202      * </ol>
2203      *
2204      * The class is created by using nested maps resolving one dependency at a time.
2205      * <p/>
2206      * The final value of the nested maps is a pair of the typed array and a map of properties
2207      * that should be added to {@link #mDefaultPropMaps}, if needed.
2208      */
2209     private static class TypedArrayCache {
2210 
2211         private Map<int[],
2212                 Map<List<StyleResourceValue>,
2213                         Map<Integer, Pair<BridgeTypedArray,
2214                                 Map<ResourceReference, ResourceValue>>>>> mCache;
2215 
TypedArrayCache()2216         private TypedArrayCache() {
2217             mCache = new IdentityHashMap<>();
2218         }
2219 
get(int[] attrs, List<StyleResourceValue> themes, int resId)2220         public Pair<BridgeTypedArray, Map<ResourceReference, ResourceValue>> get(int[] attrs,
2221                 List<StyleResourceValue> themes, int resId) {
2222             Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, Map<ResourceReference,
2223                     ResourceValue>>>>
2224                     cacheFromThemes = mCache.get(attrs);
2225             if (cacheFromThemes != null) {
2226                 Map<Integer, Pair<BridgeTypedArray, Map<ResourceReference, ResourceValue>>> cacheFromResId =
2227                         cacheFromThemes.get(themes);
2228                 if (cacheFromResId != null) {
2229                     return cacheFromResId.get(resId);
2230                 }
2231             }
2232             return null;
2233         }
2234 
put(int[] attrs, List<StyleResourceValue> themes, int resId, Pair<BridgeTypedArray, Map<ResourceReference, ResourceValue>> value)2235         public void put(int[] attrs, List<StyleResourceValue> themes, int resId,
2236                 Pair<BridgeTypedArray, Map<ResourceReference, ResourceValue>> value) {
2237             Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, Map<ResourceReference,
2238                     ResourceValue>>>>
2239                     cacheFromThemes = mCache.computeIfAbsent(attrs, k -> new HashMap<>());
2240             Map<Integer, Pair<BridgeTypedArray, Map<ResourceReference, ResourceValue>>> cacheFromResId =
2241                     cacheFromThemes.computeIfAbsent(themes, k -> new HashMap<>());
2242             cacheFromResId.put(resId, value);
2243         }
2244 
2245     }
2246 }
2247