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