]> git.saurik.com Git - android/aapt.git/blobdiff - ResourceTable.cpp
Merge "Runtime resource overlay: clean-up."
[android/aapt.git] / ResourceTable.cpp
index d98b285dd1e3c8be7b16d92886f0704559fc51ca..770b02797cecd0b9aca1f9a4ff362ee48dc8d2d1 100644 (file)
@@ -7,6 +7,7 @@
 #include "ResourceTable.h"
 
 #include "XMLNode.h"
+#include "ResourceFilter.h"
 
 #include <utils/ByteOrder.h>
 #include <utils/ResourceTypes.h>
@@ -695,7 +696,7 @@ status_t parseAndAddEntry(Bundle* bundle,
             if (isInProductList(product, String16(bundleProduct))) {
                 ;
             } else if (strcmp16(String16("default").string(), product.string()) == 0 &&
-                       !outTable->hasBagOrEntry(myPackage, curType, ident)) {
+                       !outTable->hasBagOrEntry(myPackage, curType, ident, config)) {
                 ;
             } else {
                 return NO_ERROR;
@@ -1823,6 +1824,37 @@ bool ResourceTable::hasBagOrEntry(const String16& package,
     return false;
 }
 
+bool ResourceTable::hasBagOrEntry(const String16& package,
+                                  const String16& type,
+                                  const String16& name,
+                                  const ResTable_config& config) const
+{
+    // First look for this in the included resources...
+    uint32_t rid = mAssets->getIncludedResources()
+        .identifierForName(name.string(), name.size(),
+                           type.string(), type.size(),
+                           package.string(), package.size());
+    if (rid != 0) {
+        return true;
+    }
+
+    sp<Package> p = mPackages.valueFor(package);
+    if (p != NULL) {
+        sp<Type> t = p->getTypes().valueFor(type);
+        if (t != NULL) {
+            sp<ConfigList> c =  t->getConfigs().valueFor(name);
+            if (c != NULL) {
+                sp<Entry> e = c->getEntries().valueFor(config);
+                if (e != NULL) {
+                    return true;
+                }
+            }
+        }
+    }
+
+    return false;
+}
+
 bool ResourceTable::hasBagOrEntry(const String16& ref,
                                   const String16* defType,
                                   const String16* defPackage)
@@ -2497,135 +2529,6 @@ ResourceTable::validateLocalizations(void)
     return err;
 }
 
-
-status_t
-ResourceFilter::parse(const char* arg)
-{
-    if (arg == NULL) {
-        return 0;
-    }
-
-    const char* p = arg;
-    const char* q;
-
-    while (true) {
-        q = strchr(p, ',');
-        if (q == NULL) {
-            q = p + strlen(p);
-        }
-
-        String8 part(p, q-p);
-
-        if (part == "zz_ZZ") {
-            mContainsPseudo = true;
-        }
-        int axis;
-        uint32_t value;
-        if (AaptGroupEntry::parseNamePart(part, &axis, &value)) {
-            fprintf(stderr, "Invalid configuration: %s\n", arg);
-            fprintf(stderr, "                       ");
-            for (int i=0; i<p-arg; i++) {
-                fprintf(stderr, " ");
-            }
-            for (int i=0; i<q-p; i++) {
-                fprintf(stderr, "^");
-            }
-            fprintf(stderr, "\n");
-            return 1;
-        }
-
-        ssize_t index = mData.indexOfKey(axis);
-        if (index < 0) {
-            mData.add(axis, SortedVector<uint32_t>());
-        }
-        SortedVector<uint32_t>& sv = mData.editValueFor(axis);
-        sv.add(value);
-        // if it's a locale with a region, also match an unmodified locale of the
-        // same language
-        if (axis == AXIS_LANGUAGE) {
-            if (value & 0xffff0000) {
-                sv.add(value & 0x0000ffff);
-            }
-        }
-        p = q;
-        if (!*p) break;
-        p++;
-    }
-
-    return NO_ERROR;
-}
-
-bool
-ResourceFilter::match(int axis, uint32_t value) const
-{
-    if (value == 0) {
-        // they didn't specify anything so take everything
-        return true;
-    }
-    ssize_t index = mData.indexOfKey(axis);
-    if (index < 0) {
-        // we didn't request anything on this axis so take everything
-        return true;
-    }
-    const SortedVector<uint32_t>& sv = mData.valueAt(index);
-    return sv.indexOf(value) >= 0;
-}
-
-bool
-ResourceFilter::match(const ResTable_config& config) const
-{
-    if (config.locale) {
-        uint32_t locale = (config.country[1] << 24) | (config.country[0] << 16)
-                | (config.language[1] << 8) | (config.language[0]);
-        if (!match(AXIS_LANGUAGE, locale)) {
-            return false;
-        }
-    }
-    if (!match(AXIS_ORIENTATION, config.orientation)) {
-        return false;
-    }
-    if (!match(AXIS_UIMODETYPE, (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE))) {
-        return false;
-    }
-    if (!match(AXIS_UIMODENIGHT, (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT))) {
-        return false;
-    }
-    if (!match(AXIS_DENSITY, config.density)) {
-        return false;
-    }
-    if (!match(AXIS_TOUCHSCREEN, config.touchscreen)) {
-        return false;
-    }
-    if (!match(AXIS_KEYSHIDDEN, config.inputFlags)) {
-        return false;
-    }
-    if (!match(AXIS_KEYBOARD, config.keyboard)) {
-        return false;
-    }
-    if (!match(AXIS_NAVIGATION, config.navigation)) {
-        return false;
-    }
-    if (!match(AXIS_SCREENSIZE, config.screenSize)) {
-        return false;
-    }
-    if (!match(AXIS_SMALLESTSCREENWIDTHDP, config.smallestScreenWidthDp)) {
-        return false;
-    }
-    if (!match(AXIS_SCREENWIDTHDP, config.screenWidthDp)) {
-        return false;
-    }
-    if (!match(AXIS_SCREENHEIGHTDP, config.screenHeightDp)) {
-        return false;
-    }
-    if (!match(AXIS_SCREENLAYOUTSIZE, config.screenLayout&ResTable_config::MASK_SCREENSIZE)) {
-        return false;
-    }
-    if (!match(AXIS_VERSION, config.version)) {
-        return false;
-    }
-    return true;
-}
-
 status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
 {
     ResourceFilter filter;
@@ -2758,6 +2661,12 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
             const bool filterable = (typeName != mipmap16);
 
             const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
+
+            // Until a non-NO_ENTRY value has been written for a resource,
+            // that resource is invalid; validResources[i] represents
+            // the item at t->getOrderedConfigs().itemAt(i).
+            Vector<bool> validResources;
+            validResources.insertAt(false, 0, N);
             
             // First write the typeSpec chunk, containing information about
             // each resource entry in this type.
@@ -2894,6 +2803,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
                         if (amt < 0) {
                             return amt;
                         }
+                        validResources.editItemAt(ei) = true;
                     } else {
                         index[ei] = htodl(ResTable_type::NO_ENTRY);
                     }
@@ -2904,6 +2814,14 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
                     (((uint8_t*)data->editData()) + typeStart);
                 tHeader->header.size = htodl(data->getSize()-typeStart);
             }
+
+            for (size_t i = 0; i < N; ++i) {
+                if (!validResources[i]) {
+                    sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
+                    fprintf(stderr, "warning: no entries written for %s/%s\n",
+                            String8(typeName).string(), String8(c->getName()).string());
+                }
+            }
         }
 
         // Fill in the rest of the package information.