BridgeContext.java revision 74f170f9468d3cf6d7d0ef453320141a3e63571b
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; 18 19import com.android.layoutlib.api.ILayoutLog; 20import com.android.layoutlib.api.IProjectCallback; 21import com.android.layoutlib.api.IResourceValue; 22import com.android.layoutlib.api.IStyleResourceValue; 23 24import android.content.BroadcastReceiver; 25import android.content.ComponentName; 26import android.content.ContentResolver; 27import android.content.Context; 28import android.content.Intent; 29import android.content.IntentFilter; 30import android.content.IntentSender; 31import android.content.ServiceConnection; 32import android.content.SharedPreferences; 33import android.content.pm.ApplicationInfo; 34import android.content.pm.PackageManager; 35import android.content.res.AssetManager; 36import android.content.res.Configuration; 37import android.content.res.Resources; 38import android.content.res.TypedArray; 39import android.content.res.Resources.Theme; 40import android.database.DatabaseErrorHandler; 41import android.database.sqlite.SQLiteDatabase; 42import android.database.sqlite.SQLiteDatabase.CursorFactory; 43import android.graphics.Bitmap; 44import android.graphics.drawable.Drawable; 45import android.net.Uri; 46import android.os.Bundle; 47import android.os.Handler; 48import android.os.Looper; 49import android.util.AttributeSet; 50import android.util.DisplayMetrics; 51import android.view.BridgeInflater; 52import android.view.View; 53 54import java.io.File; 55import java.io.FileInputStream; 56import java.io.FileNotFoundException; 57import java.io.FileOutputStream; 58import java.io.IOException; 59import java.io.InputStream; 60import java.util.HashMap; 61import java.util.Map; 62import java.util.TreeMap; 63import java.util.Map.Entry; 64 65/** 66 * Custom implementation of Context to handle non compiled resources. 67 */ 68public final class BridgeContext extends Context { 69 70 private final Resources mResources; 71 private final Theme mTheme; 72 private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>(); 73 private final IStyleResourceValue mThemeValues; 74 private final Object mProjectKey; 75 private final Map<String, Map<String, IResourceValue>> mProjectResources; 76 private final Map<String, Map<String, IResourceValue>> mFrameworkResources; 77 private final Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap; 78 79 // maps for dynamically generated id representing style objects (IStyleResourceValue) 80 private Map<Integer, IStyleResourceValue> mDynamicIdToStyleMap; 81 private Map<IStyleResourceValue, Integer> mStyleToDynamicIdMap; 82 private int mDynamicIdGenerator = 0x01030000; // Base id for framework R.style 83 84 // cache for TypedArray generated from IStyleResourceValue object 85 private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache; 86 private BridgeInflater mInflater; 87 88 private final IProjectCallback mProjectCallback; 89 private final ILayoutLog mLogger; 90 private BridgeContentResolver mContentResolver; 91 92 /** 93 * @param projectKey An Object identifying the project. This is used for the cache mechanism. 94 * @param metrics the {@link DisplayMetrics}. 95 * @param themeName The name of the theme to use. 96 * @param projectResources the resources of the project. The map contains (String, map) pairs 97 * where the string is the type of the resource reference used in the layout file, and the 98 * map contains (String, {@link IResourceValue}) pairs where the key is the resource name, 99 * and the value is the resource value. 100 * @param frameworkResources the framework resources. The map contains (String, map) pairs 101 * where the string is the type of the resource reference used in the layout file, and the map 102 * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the 103 * value is the resource value. 104 * @param styleInheritanceMap 105 * @param customViewLoader 106 */ 107 public BridgeContext(Object projectKey, DisplayMetrics metrics, 108 IStyleResourceValue currentTheme, 109 Map<String, Map<String, IResourceValue>> projectResources, 110 Map<String, Map<String, IResourceValue>> frameworkResources, 111 Map<IStyleResourceValue, IStyleResourceValue> styleInheritanceMap, 112 IProjectCallback customViewLoader, ILayoutLog logger) { 113 mProjectKey = projectKey; 114 mProjectCallback = customViewLoader; 115 mLogger = logger; 116 Configuration config = new Configuration(); 117 118 AssetManager assetManager = BridgeAssetManager.initSystem(); 119 mResources = BridgeResources.initSystem( 120 this, 121 assetManager, 122 metrics, 123 config, 124 customViewLoader); 125 126 mTheme = mResources.newTheme(); 127 128 mThemeValues = currentTheme; 129 mProjectResources = projectResources; 130 mFrameworkResources = frameworkResources; 131 mStyleInheritanceMap = styleInheritanceMap; 132 } 133 134 public void setBridgeInflater(BridgeInflater inflater) { 135 mInflater = inflater; 136 } 137 138 public void addViewKey(View view, Object viewKey) { 139 mViewKeyMap.put(view, viewKey); 140 } 141 142 public Object getViewKey(View view) { 143 return mViewKeyMap.get(view); 144 } 145 146 public Object getProjectKey() { 147 return mProjectKey; 148 } 149 150 public IProjectCallback getProjectCallback() { 151 return mProjectCallback; 152 } 153 154 public ILayoutLog getLogger() { 155 return mLogger; 156 } 157 158 // ------------ Context methods 159 160 @Override 161 public Resources getResources() { 162 return mResources; 163 } 164 165 @Override 166 public Theme getTheme() { 167 return mTheme; 168 } 169 170 @Override 171 public ClassLoader getClassLoader() { 172 return this.getClass().getClassLoader(); 173 } 174 175 @Override 176 public Object getSystemService(String service) { 177 if (LAYOUT_INFLATER_SERVICE.equals(service)) { 178 return mInflater; 179 } 180 181 // AutoCompleteTextView and MultiAutoCompleteTextView want a window 182 // service. We don't have any but it's not worth an exception. 183 if (WINDOW_SERVICE.equals(service)) { 184 return null; 185 } 186 187 throw new UnsupportedOperationException("Unsupported Service: " + service); 188 } 189 190 191 @Override 192 public final TypedArray obtainStyledAttributes(int[] attrs) { 193 return createStyleBasedTypedArray(mThemeValues, attrs); 194 } 195 196 @Override 197 public final TypedArray obtainStyledAttributes(int resid, int[] attrs) 198 throws Resources.NotFoundException { 199 // get the IStyleResourceValue based on the resId; 200 IStyleResourceValue style = getStyleByDynamicId(resid); 201 202 if (style == null) { 203 throw new Resources.NotFoundException(); 204 } 205 206 if (mTypedArrayCache == null) { 207 mTypedArrayCache = new HashMap<int[], Map<Integer,TypedArray>>(); 208 209 Map<Integer, TypedArray> map = new HashMap<Integer, TypedArray>(); 210 mTypedArrayCache.put(attrs, map); 211 212 BridgeTypedArray ta = createStyleBasedTypedArray(style, attrs); 213 map.put(resid, ta); 214 215 return ta; 216 } 217 218 // get the 2nd map 219 Map<Integer, TypedArray> map = mTypedArrayCache.get(attrs); 220 if (map == null) { 221 map = new HashMap<Integer, TypedArray>(); 222 mTypedArrayCache.put(attrs, map); 223 } 224 225 // get the array from the 2nd map 226 TypedArray ta = map.get(resid); 227 228 if (ta == null) { 229 ta = createStyleBasedTypedArray(style, attrs); 230 map.put(resid, ta); 231 } 232 233 return ta; 234 } 235 236 @Override 237 public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) { 238 return obtainStyledAttributes(set, attrs, 0, 0); 239 } 240 241 @Override 242 public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, 243 int defStyleAttr, int defStyleRes) { 244 245 // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java 246 BridgeXmlBlockParser parser = null; 247 if (set instanceof BridgeXmlBlockParser) { 248 parser = (BridgeXmlBlockParser)set; 249 } else { 250 // reall this should not be happening since its instantiated in Bridge 251 mLogger.error("Parser is not a BridgeXmlBlockParser!"); 252 return null; 253 } 254 255 boolean[] frameworkAttributes = new boolean[1]; 256 TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes); 257 258 BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length, 259 parser.isPlatformFile()); 260 261 // resolve the defStyleAttr value into a IStyleResourceValue 262 IStyleResourceValue defStyleValues = null; 263 264 // look for a custom style. 265 String customStyle = parser.getAttributeValue(null /* namespace*/, "style"); 266 if (customStyle != null) { 267 IResourceValue item = findResValue(customStyle); 268 269 if (item instanceof IStyleResourceValue) { 270 defStyleValues = (IStyleResourceValue)item; 271 } 272 } 273 274 if (defStyleValues == null && defStyleAttr != 0) { 275 // get the name from the int. 276 String defStyleName = searchAttr(defStyleAttr); 277 278 // look for the style in the current theme, and its parent: 279 if (mThemeValues != null) { 280 IResourceValue item = findItemInStyle(mThemeValues, defStyleName); 281 282 if (item != null) { 283 // item is a reference to a style entry. Search for it. 284 item = findResValue(item.getValue()); 285 286 if (item instanceof IStyleResourceValue) { 287 defStyleValues = (IStyleResourceValue)item; 288 } 289 } else { 290 // TODO: log the error properly 291 System.out.println("Failed to find defStyle: " + defStyleName); 292 } 293 } 294 } 295 296 if (defStyleRes != 0) { 297 // FIXME: See what we need to do with this. 298 throw new UnsupportedOperationException(); 299 } 300 301 String namespace = BridgeConstants.NS_RESOURCES; 302 if (frameworkAttributes[0] == false) { 303 // need to use the application namespace 304 namespace = mProjectCallback.getNamespace(); 305 } 306 307 if (styleNameMap != null) { 308 for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) { 309 int index = styleAttribute.getKey().intValue(); 310 311 String name = styleAttribute.getValue(); 312 String value = parser.getAttributeValue(namespace, name); 313 314 // if there's no direct value for this attribute in the XML, we look for default 315 // values in the widget defStyle, and then in the theme. 316 if (value == null) { 317 IResourceValue resValue = null; 318 319 // look for the value in the defStyle first (and its parent if needed) 320 if (defStyleValues != null) { 321 resValue = findItemInStyle(defStyleValues, name); 322 } 323 324 // if the item is not present in the defStyle, we look in the main theme (and 325 // its parent themes) 326 if (resValue == null && mThemeValues != null) { 327 resValue = findItemInStyle(mThemeValues, name); 328 } 329 330 // if we found a value, we make sure this doesn't reference another value. 331 // So we resolve it. 332 if (resValue != null) { 333 resValue = resolveResValue(resValue); 334 } 335 336 ta.bridgeSetValue(index, name, resValue); 337 } else { 338 // there is a value in the XML, but we need to resolve it in case it's 339 // referencing another resource or a theme value. 340 ta.bridgeSetValue(index, name, resolveValue(null, name, value)); 341 } 342 } 343 } 344 345 ta.sealArray(); 346 347 return ta; 348 } 349 350 @Override 351 public Looper getMainLooper() { 352 return Looper.myLooper(); 353 } 354 355 356 // ------------- private new methods 357 358 /** 359 * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the 360 * values found in the given style. 361 * @see #obtainStyledAttributes(int, int[]) 362 */ 363 private BridgeTypedArray createStyleBasedTypedArray(IStyleResourceValue style, int[] attrs) 364 throws Resources.NotFoundException { 365 TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, null); 366 367 BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length, 368 false /* platformResourceFlag */); 369 370 // loop through all the values in the style map, and init the TypedArray with 371 // the style we got from the dynamic id 372 for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) { 373 int index = styleAttribute.getKey().intValue(); 374 375 String name = styleAttribute.getValue(); 376 377 // get the value from the style, or its parent styles. 378 IResourceValue resValue = findItemInStyle(style, name); 379 380 // resolve it to make sure there are no references left. 381 ta.bridgeSetValue(index, name, resolveResValue(resValue)); 382 } 383 384 ta.sealArray(); 385 386 return ta; 387 } 388 389 390 /** 391 * Resolves the value of a resource, if the value references a theme or resource value. 392 * <p/> 393 * This method ensures that it returns a {@link IResourceValue} object that does not 394 * reference another resource. 395 * If the resource cannot be resolved, it returns <code>null</code>. 396 * <p/> 397 * If a value that does not need to be resolved is given, the method will return a new 398 * instance of IResourceValue that contains the input value. 399 * 400 * @param type the type of the resource 401 * @param name the name of the attribute containing this value. 402 * @param value the resource value, or reference to resolve 403 * @return the resolved resource value or <code>null</code> if it failed to resolve it. 404 */ 405 private IResourceValue resolveValue(String type, String name, String value) { 406 if (value == null) { 407 return null; 408 } 409 410 // get the IResourceValue referenced by this value 411 IResourceValue resValue = findResValue(value); 412 413 // if resValue is null, but value is not null, this means it was not a reference. 414 // we return the name/value wrapper in a IResourceValue 415 if (resValue == null) { 416 return new ResourceValue(type, name, value); 417 } 418 419 // we resolved a first reference, but we need to make sure this isn't a reference also. 420 return resolveResValue(resValue); 421 } 422 423 /** 424 * Returns the {@link IResourceValue} referenced by the value of <var>value</var>. 425 * <p/> 426 * This method ensures that it returns a {@link IResourceValue} object that does not 427 * reference another resource. 428 * If the resource cannot be resolved, it returns <code>null</code>. 429 * <p/> 430 * If a value that does not need to be resolved is given, the method will return the input 431 * value. 432 * 433 * @param value the value containing the reference to resolve. 434 * @return a {@link IResourceValue} object or <code>null</code> 435 */ 436 IResourceValue resolveResValue(IResourceValue value) { 437 if (value == null) { 438 return null; 439 } 440 441 // if the resource value is a style, we simply return it. 442 if (value instanceof IStyleResourceValue) { 443 return value; 444 } 445 446 // else attempt to find another IResourceValue referenced by this one. 447 IResourceValue resolvedValue = findResValue(value.getValue()); 448 449 // if the value did not reference anything, then we simply return the input value 450 if (resolvedValue == null) { 451 return value; 452 } 453 454 // otherwise, we attempt to resolve this new value as well 455 return resolveResValue(resolvedValue); 456 } 457 458 /** 459 * Searches for, and returns a {@link IResourceValue} by its reference. 460 * <p/> 461 * The reference format can be: 462 * <pre>@resType/resName</pre> 463 * <pre>@android:resType/resName</pre> 464 * <pre>@resType/android:resName</pre> 465 * <pre>?resType/resName</pre> 466 * <pre>?android:resType/resName</pre> 467 * <pre>?resType/android:resName</pre> 468 * Any other string format will return <code>null</code>. 469 * <p/> 470 * The actual format of a reference is <pre>@[namespace:]resType/resName</pre> but this method 471 * only support the android namespace. 472 * 473 * @param reference the resource reference to search for. 474 * @return a {@link IResourceValue} or <code>null</code>. 475 */ 476 IResourceValue findResValue(String reference) { 477 if (reference == null) { 478 return null; 479 } 480 if (reference.startsWith(BridgeConstants.PREFIX_THEME_REF)) { 481 // no theme? no need to go further! 482 if (mThemeValues == null) { 483 return null; 484 } 485 486 boolean frameworkOnly = false; 487 488 // eleminate the prefix from the string 489 if (reference.startsWith(BridgeConstants.PREFIX_ANDROID_THEME_REF)) { 490 frameworkOnly = true; 491 reference = reference.substring(BridgeConstants.PREFIX_ANDROID_THEME_REF.length()); 492 } else { 493 reference = reference.substring(BridgeConstants.PREFIX_THEME_REF.length()); 494 } 495 496 // at this point, value can contain type/name (drawable/foo for instance). 497 // split it to make sure. 498 String[] segments = reference.split("\\/"); 499 500 // we look for the referenced item name. 501 String referenceName = null; 502 503 if (segments.length == 2) { 504 // there was a resType in the reference. If it's attr, we ignore it 505 // else, we assert for now. 506 if (BridgeConstants.RES_ATTR.equals(segments[0])) { 507 referenceName = segments[1]; 508 } else { 509 // At this time, no support for ?type/name where type is not "attr" 510 return null; 511 } 512 } else { 513 // it's just an item name. 514 referenceName = segments[0]; 515 } 516 517 // now we look for android: in the referenceName in order to support format 518 // such as: ?attr/android:name 519 if (referenceName.startsWith(BridgeConstants.PREFIX_ANDROID)) { 520 frameworkOnly = true; 521 referenceName = referenceName.substring(BridgeConstants.PREFIX_ANDROID.length()); 522 } 523 524 // Now look for the item in the theme, starting with the current one. 525 if (frameworkOnly) { 526 // FIXME for now we do the same as if it didn't specify android: 527 return findItemInStyle(mThemeValues, referenceName); 528 } 529 530 return findItemInStyle(mThemeValues, referenceName); 531 } else if (reference.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) { 532 boolean frameworkOnly = false; 533 534 // check for the specific null reference value. 535 if (BridgeConstants.REFERENCE_NULL.equals(reference)) { 536 return null; 537 } 538 539 // Eliminate the prefix from the string. 540 if (reference.startsWith(BridgeConstants.PREFIX_ANDROID_RESOURCE_REF)) { 541 frameworkOnly = true; 542 reference = reference.substring( 543 BridgeConstants.PREFIX_ANDROID_RESOURCE_REF.length()); 544 } else { 545 reference = reference.substring(BridgeConstants.PREFIX_RESOURCE_REF.length()); 546 } 547 548 // at this point, value contains type/[android:]name (drawable/foo for instance) 549 String[] segments = reference.split("\\/"); 550 551 // now we look for android: in the resource name in order to support format 552 // such as: @drawable/android:name 553 if (segments[1].startsWith(BridgeConstants.PREFIX_ANDROID)) { 554 frameworkOnly = true; 555 segments[1] = segments[1].substring(BridgeConstants.PREFIX_ANDROID.length()); 556 } 557 558 return findResValue(segments[0], segments[1], frameworkOnly); 559 } 560 561 // Looks like the value didn't reference anything. Return null. 562 return null; 563 } 564 565 /** 566 * Searches for, and returns a {@link IResourceValue} by its name, and type. 567 * @param resType the type of the resource 568 * @param resName the name of the resource 569 * @param frameworkOnly if <code>true</code>, the method does not search in the 570 * project resources 571 */ 572 private IResourceValue findResValue(String resType, String resName, boolean frameworkOnly) { 573 // map of IResouceValue for the given type 574 Map<String, IResourceValue> typeMap; 575 576 // if allowed, search in the project resources first. 577 if (frameworkOnly == false) { 578 typeMap = mProjectResources.get(resType); 579 if (typeMap != null) { 580 IResourceValue item = typeMap.get(resName); 581 if (item != null) { 582 return item; 583 } 584 } 585 } 586 587 // now search in the framework resources. 588 typeMap = mFrameworkResources.get(resType); 589 if (typeMap != null) { 590 IResourceValue item = typeMap.get(resName); 591 if (item != null) { 592 return item; 593 } 594 } 595 596 // didn't find the resource anywhere. 597 return null; 598 } 599 600 /** 601 * Returns a framework resource by type and name. The returned resource is resolved. 602 * @param resourceType the type of the resource 603 * @param resourceName the name of the resource 604 */ 605 public IResourceValue getFrameworkResource(String resourceType, String resourceName) { 606 return getResource(resourceType, resourceName, mFrameworkResources); 607 } 608 609 /** 610 * Returns a project resource by type and name. The returned resource is resolved. 611 * @param resourceType the type of the resource 612 * @param resourceName the name of the resource 613 */ 614 public IResourceValue getProjectResource(String resourceType, String resourceName) { 615 return getResource(resourceType, resourceName, mProjectResources); 616 } 617 618 IResourceValue getResource(String resourceType, String resourceName, 619 Map<String, Map<String, IResourceValue>> resourceRepository) { 620 Map<String, IResourceValue> typeMap = resourceRepository.get(resourceType); 621 if (typeMap != null) { 622 IResourceValue item = typeMap.get(resourceName); 623 if (item != null) { 624 item = resolveResValue(item); 625 return item; 626 } 627 } 628 629 // didn't find the resource anywhere. 630 return null; 631 632 } 633 634 /** 635 * Returns the {@link IResourceValue} matching a given name in a given style. If the 636 * item is not directly available in the style, the method looks in its parent style. 637 * @param style the style to search in 638 * @param itemName the name of the item to search for. 639 * @return the {@link IResourceValue} object or <code>null</code> 640 */ 641 IResourceValue findItemInStyle(IStyleResourceValue style, String itemName) { 642 IResourceValue item = style.findItem(itemName); 643 644 // if we didn't find it, we look in the parent style (if applicable) 645 if (item == null && mStyleInheritanceMap != null) { 646 IStyleResourceValue parentStyle = mStyleInheritanceMap.get(style); 647 if (parentStyle != null) { 648 return findItemInStyle(parentStyle, itemName); 649 } 650 } 651 652 return item; 653 } 654 655 /** 656 * The input int[] attrs is one of com.android.internal.R.styleable fields where the name 657 * of the field is the style being referenced and the array contains one index per attribute. 658 * <p/> 659 * searchAttrs() finds all the names of the attributes referenced so for example if 660 * attrs == com.android.internal.R.styleable.View, this returns the list of the "xyz" where 661 * there's a field com.android.internal.R.styleable.View_xyz and the field value is the index 662 * that is used to reference the attribute later in the TypedArray. 663 * 664 * @param attrs An attribute array reference given to obtainStyledAttributes. 665 * @return A sorted map Attribute-Value to Attribute-Name for all attributes declared by the 666 * attribute array. Returns null if nothing is found. 667 */ 668 private TreeMap<Integer,String> searchAttrs(int[] attrs, boolean[] outFrameworkFlag) { 669 // get the name of the array from the framework resources 670 String arrayName = Bridge.resolveResourceValue(attrs); 671 if (arrayName != null) { 672 // if we found it, get the name of each of the int in the array. 673 TreeMap<Integer,String> attributes = new TreeMap<Integer, String>(); 674 for (int i = 0 ; i < attrs.length ; i++) { 675 String[] info = Bridge.resolveResourceValue(attrs[i]); 676 if (info != null) { 677 attributes.put(i, info[0]); 678 } else { 679 // FIXME Not sure what we should be doing here... 680 attributes.put(i, null); 681 } 682 } 683 684 if (outFrameworkFlag != null) { 685 outFrameworkFlag[0] = true; 686 } 687 688 return attributes; 689 } 690 691 // if the name was not found in the framework resources, look in the project 692 // resources 693 arrayName = mProjectCallback.resolveResourceValue(attrs); 694 if (arrayName != null) { 695 TreeMap<Integer,String> attributes = new TreeMap<Integer, String>(); 696 for (int i = 0 ; i < attrs.length ; i++) { 697 String[] info = mProjectCallback.resolveResourceValue(attrs[i]); 698 if (info != null) { 699 attributes.put(i, info[0]); 700 } else { 701 // FIXME Not sure what we should be doing here... 702 attributes.put(i, null); 703 } 704 } 705 706 if (outFrameworkFlag != null) { 707 outFrameworkFlag[0] = false; 708 } 709 710 return attributes; 711 } 712 713 return null; 714 } 715 716 /** 717 * Searches for the attribute referenced by its internal id. 718 * 719 * @param attr An attribute reference given to obtainStyledAttributes such as defStyle. 720 * @return The unique name of the attribute, if found, e.g. "buttonStyle". Returns null 721 * if nothing is found. 722 */ 723 public String searchAttr(int attr) { 724 String[] info = Bridge.resolveResourceValue(attr); 725 if (info != null) { 726 return info[0]; 727 } 728 729 info = mProjectCallback.resolveResourceValue(attr); 730 if (info != null) { 731 return info[0]; 732 } 733 734 return null; 735 } 736 737 int getDynamicIdByStyle(IStyleResourceValue resValue) { 738 if (mDynamicIdToStyleMap == null) { 739 // create the maps. 740 mDynamicIdToStyleMap = new HashMap<Integer, IStyleResourceValue>(); 741 mStyleToDynamicIdMap = new HashMap<IStyleResourceValue, Integer>(); 742 } 743 744 // look for an existing id 745 Integer id = mStyleToDynamicIdMap.get(resValue); 746 747 if (id == null) { 748 // generate a new id 749 id = Integer.valueOf(++mDynamicIdGenerator); 750 751 // and add it to the maps. 752 mDynamicIdToStyleMap.put(id, resValue); 753 mStyleToDynamicIdMap.put(resValue, id); 754 } 755 756 return id; 757 } 758 759 private IStyleResourceValue getStyleByDynamicId(int i) { 760 if (mDynamicIdToStyleMap != null) { 761 return mDynamicIdToStyleMap.get(i); 762 } 763 764 return null; 765 } 766 767 int getFrameworkIdValue(String idName, int defValue) { 768 Integer value = Bridge.getResourceValue(BridgeConstants.RES_ID, idName); 769 if (value != null) { 770 return value.intValue(); 771 } 772 773 return defValue; 774 } 775 776 int getProjectIdValue(String idName, int defValue) { 777 if (mProjectCallback != null) { 778 Integer value = mProjectCallback.getResourceValue(BridgeConstants.RES_ID, idName); 779 if (value != null) { 780 return value.intValue(); 781 } 782 } 783 784 return defValue; 785 } 786 787 //------------ NOT OVERRIDEN -------------------- 788 789 @Override 790 public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) { 791 // TODO Auto-generated method stub 792 return false; 793 } 794 795 @Override 796 public int checkCallingOrSelfPermission(String arg0) { 797 // TODO Auto-generated method stub 798 return 0; 799 } 800 801 @Override 802 public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) { 803 // TODO Auto-generated method stub 804 return 0; 805 } 806 807 @Override 808 public int checkCallingPermission(String arg0) { 809 // TODO Auto-generated method stub 810 return 0; 811 } 812 813 @Override 814 public int checkCallingUriPermission(Uri arg0, int arg1) { 815 // TODO Auto-generated method stub 816 return 0; 817 } 818 819 @Override 820 public int checkPermission(String arg0, int arg1, int arg2) { 821 // TODO Auto-generated method stub 822 return 0; 823 } 824 825 @Override 826 public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) { 827 // TODO Auto-generated method stub 828 return 0; 829 } 830 831 @Override 832 public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3, 833 int arg4, int arg5) { 834 // TODO Auto-generated method stub 835 return 0; 836 } 837 838 @Override 839 public void clearWallpaper() { 840 // TODO Auto-generated method stub 841 842 } 843 844 @Override 845 public Context createPackageContext(String arg0, int arg1) { 846 // TODO Auto-generated method stub 847 return null; 848 } 849 850 @Override 851 public String[] databaseList() { 852 // TODO Auto-generated method stub 853 return null; 854 } 855 856 @Override 857 public boolean deleteDatabase(String arg0) { 858 // TODO Auto-generated method stub 859 return false; 860 } 861 862 @Override 863 public boolean deleteFile(String arg0) { 864 // TODO Auto-generated method stub 865 return false; 866 } 867 868 @Override 869 public void enforceCallingOrSelfPermission(String arg0, String arg1) { 870 // TODO Auto-generated method stub 871 872 } 873 874 @Override 875 public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1, 876 String arg2) { 877 // TODO Auto-generated method stub 878 879 } 880 881 @Override 882 public void enforceCallingPermission(String arg0, String arg1) { 883 // TODO Auto-generated method stub 884 885 } 886 887 @Override 888 public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) { 889 // TODO Auto-generated method stub 890 891 } 892 893 @Override 894 public void enforcePermission(String arg0, int arg1, int arg2, String arg3) { 895 // TODO Auto-generated method stub 896 897 } 898 899 @Override 900 public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3, 901 String arg4) { 902 // TODO Auto-generated method stub 903 904 } 905 906 @Override 907 public void enforceUriPermission(Uri arg0, String arg1, String arg2, 908 int arg3, int arg4, int arg5, String arg6) { 909 // TODO Auto-generated method stub 910 911 } 912 913 @Override 914 public String[] fileList() { 915 // TODO Auto-generated method stub 916 return null; 917 } 918 919 @Override 920 public AssetManager getAssets() { 921 // TODO Auto-generated method stub 922 return null; 923 } 924 925 @Override 926 public File getCacheDir() { 927 // TODO Auto-generated method stub 928 return null; 929 } 930 931 @Override 932 public File getExternalCacheDir() { 933 // TODO Auto-generated method stub 934 return null; 935 } 936 937 @Override 938 public ContentResolver getContentResolver() { 939 if (mContentResolver == null) { 940 mContentResolver = new BridgeContentResolver(this); 941 } 942 return mContentResolver; 943 } 944 945 @Override 946 public File getDatabasePath(String arg0) { 947 // TODO Auto-generated method stub 948 return null; 949 } 950 951 @Override 952 public File getDir(String arg0, int arg1) { 953 // TODO Auto-generated method stub 954 return null; 955 } 956 957 @Override 958 public File getFileStreamPath(String arg0) { 959 // TODO Auto-generated method stub 960 return null; 961 } 962 963 @Override 964 public File getFilesDir() { 965 // TODO Auto-generated method stub 966 return null; 967 } 968 969 @Override 970 public File getExternalFilesDir(String type) { 971 // TODO Auto-generated method stub 972 return null; 973 } 974 975 @Override 976 public String getPackageCodePath() { 977 // TODO Auto-generated method stub 978 return null; 979 } 980 981 @Override 982 public PackageManager getPackageManager() { 983 // TODO Auto-generated method stub 984 return null; 985 } 986 987 @Override 988 public String getPackageName() { 989 // TODO Auto-generated method stub 990 return null; 991 } 992 993 @Override 994 public ApplicationInfo getApplicationInfo() { 995 // TODO Auto-generated method stub 996 return null; 997 } 998 999 @Override 1000 public String getPackageResourcePath() { 1001 // TODO Auto-generated method stub 1002 return null; 1003 } 1004 1005 @Override 1006 public File getSharedPrefsFile(String name) { 1007 // TODO Auto-generated method stub 1008 return null; 1009 } 1010 1011 @Override 1012 public SharedPreferences getSharedPreferences(String arg0, int arg1) { 1013 // TODO Auto-generated method stub 1014 return null; 1015 } 1016 1017 @Override 1018 public Drawable getWallpaper() { 1019 // TODO Auto-generated method stub 1020 return null; 1021 } 1022 1023 @Override 1024 public int getWallpaperDesiredMinimumWidth() { 1025 return -1; 1026 } 1027 1028 @Override 1029 public int getWallpaperDesiredMinimumHeight() { 1030 return -1; 1031 } 1032 1033 @Override 1034 public void grantUriPermission(String arg0, Uri arg1, int arg2) { 1035 // TODO Auto-generated method stub 1036 1037 } 1038 1039 @SuppressWarnings("unused") 1040 @Override 1041 public FileInputStream openFileInput(String arg0) 1042 throws FileNotFoundException { 1043 // TODO Auto-generated method stub 1044 return null; 1045 } 1046 1047 @SuppressWarnings("unused") 1048 @Override 1049 public FileOutputStream openFileOutput(String arg0, int arg1) 1050 throws FileNotFoundException { 1051 // TODO Auto-generated method stub 1052 return null; 1053 } 1054 1055 @Override 1056 public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, 1057 CursorFactory arg2) { 1058 // TODO Auto-generated method stub 1059 return null; 1060 } 1061 1062 @Override 1063 public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, 1064 CursorFactory arg2, DatabaseErrorHandler arg3) { 1065 // TODO Auto-generated method stub 1066 return null; 1067 } 1068 1069 @Override 1070 public Drawable peekWallpaper() { 1071 // TODO Auto-generated method stub 1072 return null; 1073 } 1074 1075 @Override 1076 public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) { 1077 // TODO Auto-generated method stub 1078 return null; 1079 } 1080 1081 @Override 1082 public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, 1083 String arg2, Handler arg3) { 1084 // TODO Auto-generated method stub 1085 return null; 1086 } 1087 1088 @Override 1089 public void removeStickyBroadcast(Intent arg0) { 1090 // TODO Auto-generated method stub 1091 1092 } 1093 1094 @Override 1095 public void revokeUriPermission(Uri arg0, int arg1) { 1096 // TODO Auto-generated method stub 1097 1098 } 1099 1100 @Override 1101 public void sendBroadcast(Intent arg0) { 1102 // TODO Auto-generated method stub 1103 1104 } 1105 1106 @Override 1107 public void sendBroadcast(Intent arg0, String arg1) { 1108 // TODO Auto-generated method stub 1109 1110 } 1111 1112 @Override 1113 public void sendOrderedBroadcast(Intent arg0, String arg1) { 1114 // TODO Auto-generated method stub 1115 1116 } 1117 1118 @Override 1119 public void sendOrderedBroadcast(Intent arg0, String arg1, 1120 BroadcastReceiver arg2, Handler arg3, int arg4, String arg5, 1121 Bundle arg6) { 1122 // TODO Auto-generated method stub 1123 1124 } 1125 1126 @Override 1127 public void sendStickyBroadcast(Intent arg0) { 1128 // TODO Auto-generated method stub 1129 1130 } 1131 1132 @Override 1133 public void sendStickyOrderedBroadcast(Intent intent, 1134 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, 1135 Bundle initialExtras) { 1136 // TODO Auto-generated method stub 1137 } 1138 1139 @Override 1140 public void setTheme(int arg0) { 1141 // TODO Auto-generated method stub 1142 1143 } 1144 1145 @SuppressWarnings("unused") 1146 @Override 1147 public void setWallpaper(Bitmap arg0) throws IOException { 1148 // TODO Auto-generated method stub 1149 1150 } 1151 1152 @SuppressWarnings("unused") 1153 @Override 1154 public void setWallpaper(InputStream arg0) throws IOException { 1155 // TODO Auto-generated method stub 1156 1157 } 1158 1159 @Override 1160 public void startActivity(Intent arg0) { 1161 // TODO Auto-generated method stub 1162 1163 } 1164 1165 @Override 1166 public void startIntentSender(IntentSender intent, 1167 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 1168 throws IntentSender.SendIntentException { 1169 // TODO Auto-generated method stub 1170 } 1171 1172 @Override 1173 public boolean startInstrumentation(ComponentName arg0, String arg1, 1174 Bundle arg2) { 1175 // TODO Auto-generated method stub 1176 return false; 1177 } 1178 1179 @Override 1180 public ComponentName startService(Intent arg0) { 1181 // TODO Auto-generated method stub 1182 return null; 1183 } 1184 1185 @Override 1186 public boolean stopService(Intent arg0) { 1187 // TODO Auto-generated method stub 1188 return false; 1189 } 1190 1191 @Override 1192 public void unbindService(ServiceConnection arg0) { 1193 // TODO Auto-generated method stub 1194 1195 } 1196 1197 @Override 1198 public void unregisterReceiver(BroadcastReceiver arg0) { 1199 // TODO Auto-generated method stub 1200 1201 } 1202 1203 @Override 1204 public Context getApplicationContext() { 1205 throw new UnsupportedOperationException(); 1206 } 1207} 1208