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