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