1b62286e60c079936a5f1e5b0befd32d2d9bf1b3fMark Salyzyn#include <dirent.h>
24600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath#include <inttypes.h>
30fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren#include <sys/file.h>
4b62286e60c079936a5f1e5b0befd32d2d9bf1b3fMark Salyzyn#include <sys/stat.h>
5b62286e60c079936a5f1e5b0befd32d2d9bf1b3fMark Salyzyn
613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include "idmap.h"
713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
80881a7445f9106e835486c5a697c01f4f18e619bDan Albert#include <memory>
913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <androidfw/ResourceTypes.h>
1013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <androidfw/StreamingZipInflater.h>
1113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <androidfw/ZipFileRO.h>
1213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <private/android_filesystem_config.h> // for AID_SYSTEM
1313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <utils/SortedVector.h>
1413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <utils/String16.h>
1513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <utils/String8.h>
1613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
1713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#define NO_OVERLAY_TAG (-1000)
1813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
1913221c9cffdb289851411bdc73a9a5236fcb9291Colin Crossusing namespace android;
2013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
2113221c9cffdb289851411bdc73a9a5236fcb9291Colin Crossnamespace {
2213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    struct Overlay {
2313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        Overlay() {}
2413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        Overlay(const String8& a, const String8& i, int p) :
2513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            apk_path(a), idmap_path(i), priority(p) {}
2613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
2713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        bool operator<(Overlay const& rhs) const
2813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        {
297197d91eb7dfbd0f5b065b56d4f391019e71d03aMårten Kongstad            return rhs.priority > priority;
3013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
3113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
3213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        String8 apk_path;
3313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        String8 idmap_path;
3413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        int priority;
3513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    };
3613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
3713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector)
3813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    {
390fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        // the file is opened for appending so that it doesn't get truncated
400fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        // before we can guarantee mutual exclusion via the flock
410fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        FILE* fout = fopen(filename, "a");
4213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (fout == NULL) {
4313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return false;
4413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
4513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
460fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) {
470fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren            fclose(fout);
480fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren            return false;
490fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        }
500fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren
510fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) {
520fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren            TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
530fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren            fclose(fout);
540fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren            return false;
550fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        }
560fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren
5713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        for (size_t i = 0; i < overlayVector.size(); ++i) {
5813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            const Overlay& overlay = overlayVector[i];
5913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string());
6013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
6113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
620fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        TEMP_FAILURE_RETRY(fflush(fout));
630fbb60811076e6fcfd576287b6e6a16ac1a69c44Martin Wallgren        TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
6413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        fclose(fout);
6513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
6613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        // Make file world readable since Zygote (running as root) will read
6713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        // it when creating the initial AssetManger object
6813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644
6913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (chmod(filename, mode) == -1) {
7013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            unlink(filename);
7113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return false;
7213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
7313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
7413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        return true;
7513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    }
7613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
7713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    String8 flatten_path(const char *path)
7813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    {
7913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        String16 tmp(path);
8013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        tmp.replaceAll('/', '@');
8113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        return String8(tmp);
8213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    }
8313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
8413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name)
8513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    {
8613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        const size_t N = parser.getAttributeCount();
8713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        String16 target;
8813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        int priority = -1;
8913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        for (size_t i = 0; i < N; ++i) {
9013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            size_t len;
9113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            String16 key(parser.getAttributeName(i, &len));
9213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            if (key == String16("targetPackage")) {
936698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                const char16_t *p = parser.getAttributeStringValue(i, &len);
94cfedceb8c180a2e176154d461659e0c3569dc931Andreas Gampe                if (p != NULL) {
9513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                    target = String16(p, len);
9613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                }
9713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            } else if (key == String16("priority")) {
9813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                Res_value v;
9913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) {
10013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                    priority = v.data;
10113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                    if (priority < 0 || priority > 9999) {
10213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                        return -1;
10313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                    }
10413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                }
10513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            }
10613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
10713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (target == String16(target_package_name)) {
10813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return priority;
10913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
11013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        return NO_OVERLAY_TAG;
11113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    }
11213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
11313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    int parse_manifest(const void *data, size_t size, const char *target_package_name)
11413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    {
115de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski        ResXMLTree parser;
116de898ff42912bd7ca1bfb099cd439562496765a4Adam Lesinski        parser.setTo(data, size);
11713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (parser.getError() != NO_ERROR) {
11813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError());
11913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return -1;
12013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
12113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
12213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        ResXMLParser::event_code_t type;
12313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        do {
12413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            type = parser.next();
12513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            if (type == ResXMLParser::START_TAG) {
12613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                size_t len;
12713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                String16 tag(parser.getElementName(&len));
12813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                if (tag == String16("overlay")) {
12913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                    return parse_overlay_tag(parser, target_package_name);
13013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross                }
13113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            }
13213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT);
13313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
13413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        return NO_OVERLAY_TAG;
13513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    }
13613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
13713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    int parse_apk(const char *path, const char *target_package_name)
13813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    {
1390881a7445f9106e835486c5a697c01f4f18e619bDan Albert        std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(path));
14013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (zip.get() == NULL) {
14113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path);
14213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return -1;
14313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
14413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        ZipEntryRO entry;
14513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if ((entry = zip->findEntryByName("AndroidManifest.xml")) == NULL) {
14613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__);
14713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return -1;
14813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
1494600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath        uint32_t uncompLen = 0;
1504600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath        uint16_t method;
15113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) {
15213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            ALOGW("%s: failed to read entry info\n", __FUNCTION__);
15313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return -1;
15413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
15513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (method != ZipFileRO::kCompressDeflated) {
1564600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath            ALOGW("%s: cannot handle zip compression method %" PRIu16 "\n", __FUNCTION__, method);
15713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return -1;
15813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
15913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        FileMap *dataMap = zip->createEntryFileMap(entry);
160cfedceb8c180a2e176154d461659e0c3569dc931Andreas Gampe        if (dataMap == NULL) {
16113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            ALOGW("%s: failed to create FileMap\n", __FUNCTION__);
16213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return -1;
16313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
16413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        char *buf = new char[uncompLen];
16513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (NULL == buf) {
1664600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath            ALOGW("%s: failed to allocate %" PRIu32 " byte\n", __FUNCTION__, uncompLen);
167688ff4cf0f93d1a886437884f23874e5595d59a3Narayan Kamath            delete dataMap;
16813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return -1;
16913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
17013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        StreamingZipInflater inflater(dataMap, uncompLen);
17113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        if (inflater.read(buf, uncompLen) < 0) {
1724600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath            ALOGW("%s: failed to inflate %" PRIu32 " byte\n", __FUNCTION__, uncompLen);
17313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            delete[] buf;
174688ff4cf0f93d1a886437884f23874e5595d59a3Narayan Kamath            delete dataMap;
17513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross            return -1;
17613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
17713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
1784600dd053dbdbd4b95f3b11057a1cc55b99f9c77Narayan Kamath        int priority = parse_manifest(buf, static_cast<size_t>(uncompLen), target_package_name);
17913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        delete[] buf;
180688ff4cf0f93d1a886437884f23874e5595d59a3Narayan Kamath        delete dataMap;
18113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        return priority;
18213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    }
18313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross}
18413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
18583ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstadint idmap_scan(const char *target_package_name, const char *target_apk_path,
18683ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad        const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
18713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross{
18813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    String8 filename = String8(idmap_dir);
18913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    filename.appendPath("overlays.list");
19013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
19113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    SortedVector<Overlay> overlayVector;
19283ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad    const size_t N = overlay_dirs->size();
19383ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad    for (size_t i = 0; i < N; ++i) {
19483ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad        const char *overlay_dir = overlay_dirs->itemAt(i);
19583ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad        DIR *dir = opendir(overlay_dir);
19683ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad        if (dir == NULL) {
19783ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            return EXIT_FAILURE;
19883ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad        }
19983ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad
20083ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad        struct dirent *dirent;
20183ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad        while ((dirent = readdir(dir)) != NULL) {
20283ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            struct stat st;
20383ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            char overlay_apk_path[PATH_MAX + 1];
20483ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name);
20583ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            if (stat(overlay_apk_path, &st) < 0) {
20683ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad                continue;
20783ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            }
20883ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            if (!S_ISREG(st.st_mode)) {
20983ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad                continue;
21083ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            }
21113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
21283ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            int priority = parse_apk(overlay_apk_path, target_package_name);
21383ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            if (priority < 0) {
21483ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad                continue;
21583ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            }
21613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
21783ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            String8 idmap_path(idmap_dir);
21883ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            idmap_path.appendPath(flatten_path(overlay_apk_path + 1));
21983ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            idmap_path.append("@idmap");
22013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
22183ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) {
22283ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad                ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n",
22383ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad                        target_apk_path, overlay_apk_path, idmap_path.string());
22483ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad                continue;
22583ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            }
22683ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad
22783ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            Overlay overlay(String8(overlay_apk_path), idmap_path, priority);
22883ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad            overlayVector.add(overlay);
22913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        }
23013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
23183ab0d7c1824f3a29e41af8a95a954c73f48c287Mårten Kongstad        closedir(dir);
23213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    }
23313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
23413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    if (!writePackagesList(filename.string(), overlayVector)) {
23513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross        return EXIT_FAILURE;
23613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    }
23713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross
23813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross    return EXIT_SUCCESS;
23913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross}
240