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