Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 249e3ed5 authored by Mårten Kongstad's avatar Mårten Kongstad Committed by Zoran Jovanovic
Browse files

Runtime resource overlay: clean-up.

This is a combination of three minor clean-up tasks:

- Generate correct idmap even if name lookup fails:

  Any resources following a resource with a spec but no actual values
  would receive an incorrect ID in the idmap due to an accumulating offset
  error. To combat this, a dummy value is inserted in the idmap whenever
  a resource with a spec but no values is encountered.

- Optimize pruning of padding zeroes in idmaps:

  Earlier, trailing zeroes were iteratively popped from the end of each
  type block of an idmap. This commit instead tracks where to make the
  cut, and does so with a single function call.

- aapt: warn about resources which lack values:

  The resource framework assumes every resource to have a value for
  at least one valid configuration. However, if multiple resource
  directories are used (several -S options to aapt), the list of
  configurations is limited by dpi (-c option to aapt) and a resource
  is only available in discarded dpi configurations, aapt will create
  a resource entry where each configuration lack an actual value. This
  commit lets aapt emit a warning whenever this has happened.

Change-Id: Ic7451b7f4adfef5bfa6b0d7e64e057f317a2cdaa
parent c761d8b0
Loading
Loading
Loading
Loading
+21 −10
Original line number Diff line number Diff line
@@ -4333,7 +4333,8 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui
    const uint32_t pkg_id = pkg->package->id << 24;

    for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
        ssize_t offset = -1;
        ssize_t first = -1;
        ssize_t last = -1;
        const Type* typeConfigs = pkg->getType(typeIndex);
        ssize_t mapIndex = map.add();
        if (mapIndex < 0) {
@@ -4347,6 +4348,8 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui
            resource_name resName;
            if (!this->getResourceName(resID, &resName)) {
                ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID);
                // add dummy value, or trimming leading/trailing zeroes later will fail
                vector.push(0);
                continue;
            }

@@ -4360,11 +4363,12 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui
                                                              overlayPackage.size());
            if (overlayResID != 0) {
                overlayResID = pkg_id | (0x00ffffff & overlayResID);
                last = Res_GETENTRY(resID);
                if (first == -1) {
                    first = Res_GETENTRY(resID);
                }
            vector.push(overlayResID);
            if (overlayResID != 0 && offset == -1) {
                offset = Res_GETENTRY(resID);
            }
            vector.push(overlayResID);
#if 0
            if (overlayResID != 0) {
                ALOGD("%s/%s 0x%08x -> 0x%08x\n",
@@ -4375,13 +4379,16 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui
#endif
        }

        if (offset != -1) {
            // shave off leading and trailing entries which lack overlay values
            vector.removeItemsAt(0, offset);
            vector.insertAt((uint32_t)offset, 0, 1);
            while (vector.top() == 0) {
                vector.pop();
        if (first != -1) {
            // shave off trailing entries which lack overlay values
            const size_t last_past_one = last + 1;
            if (last_past_one < vector.size()) {
                vector.removeItemsAt(last_past_one, vector.size() - last_past_one);
            }
            // shave off leading entries which lack overlay values
            vector.removeItemsAt(0, first);
            // store offset to first overlaid resource ID of this type
            vector.insertAt((uint32_t)first, 0, 1);
            // reserve space for number and offset of entries, and the actual entries
            *outSize += (2 + vector.size()) * sizeof(uint32_t);
        } else {
@@ -4419,6 +4426,10 @@ status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, ui
        if (N == 0) {
            continue;
        }
        if (N == 1) { // vector expected to hold (offset) + (N > 0 entries)
            ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i);
            return UNKNOWN_ERROR;
        }
        *data++ = htodl(N - 1); // do not count the offset (which is vector's first element)
        for (size_t j = 0; j < N; ++j) {
            const uint32_t& overlayResID = vector.itemAt(j);
+15 −0
Original line number Diff line number Diff line
@@ -2662,6 +2662,12 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)

            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.
            {
@@ -2797,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);
                    }
@@ -2807,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.