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