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