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

Commit b302bc3f authored by Clark Scheff's avatar Clark Scheff
Browse files

CM11 Themes: Store hash codes for target and overlay in idmap

Due to some system packages always having the same last modified
time stamp of 08/01/2008 we must use some other unique value to
determine that the contents of either the target or the overlay
have changed.  This unique value will be passed down from the java
layer and written to the idmap header.

This change requires the following patch from frameworks/base
http://review.cyanogenmod.org/62565

Change-Id: I0adcafaca96110268766d6e3349414364ecea4c3
(cherry picked from commit 368dc02f)
parent 702568f2
Loading
Loading
Loading
Loading
+12 −14
Original line number Diff line number Diff line
@@ -147,10 +147,10 @@ fail:
    }

    int create_idmap(const char *target_apk_path, const char *overlay_apk_path,
            Vector<String8>& targets, Vector<String8>& overlays, uint32_t **data, size_t *size)
            uint32_t target_hash, uint32_t overlay_hash, Vector<String8>& targets,
            Vector<String8>& overlays, uint32_t **data, size_t *size)
    {
        uint32_t target_crc, overlay_crc;
        time_t target_mtime, overlay_mtime;

        // In the original implementation, crc of the res tables are generated
        // theme apks however do not need a restable, everything is in assets/
@@ -159,22 +159,15 @@ fail:
        overlay_crc = 0;

        struct stat statbuf;
        if (stat(target_apk_path, &statbuf) != NO_ERROR) {
            return -1;
        }
        target_mtime = statbuf.st_mtime;
        if (stat(overlay_apk_path, &statbuf) != NO_ERROR) {
            return -1;
        }
        overlay_mtime = statbuf.st_mtime;

        AssetManager am;
        bool b = am.createIdmap(target_apk_path, overlay_apk_path, target_crc, overlay_crc,
                target_mtime, overlay_mtime, targets, overlays, data, size);
                target_hash, overlay_hash, targets, overlays, data, size);
        return b ? 0 : -1;
    }

    int create_and_write_idmap(const char *target_apk_path, const char *overlay_apk_path,
            uint32_t target_hash, uint32_t overlay_hash,
            const char *redirections, int fd, bool check_if_stale)
    {
        if (check_if_stale) {
@@ -202,7 +195,8 @@ fail:
        uint32_t *data = NULL;
        size_t size;

        if (create_idmap(target_apk_path, overlay_apk_path, targets, overlays, &data, &size) == -1) {
        if (create_idmap(target_apk_path, overlay_apk_path, target_hash, overlay_hash,
                targets, overlays, &data, &size) == -1) {
            return -1;
        }

@@ -217,6 +211,7 @@ fail:
}

int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path,
        uint32_t target_hash, uint32_t overlay_hash,
        const char *redirections, const char *idmap_path)
{
    if (!is_idmap_stale_path(target_apk_path, overlay_apk_path, idmap_path)) {
@@ -229,7 +224,8 @@ int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path,
        return EXIT_FAILURE;
    }

    int r = create_and_write_idmap(target_apk_path, overlay_apk_path, redirections, fd, false);
    int r = create_and_write_idmap(target_apk_path, overlay_apk_path, target_hash, overlay_hash,
            redirections, fd, false);
    close(fd);
    if (r != 0) {
        unlink(idmap_path);
@@ -238,8 +234,10 @@ int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path,
}

int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path,
        uint32_t target_hash, uint32_t overlay_hash,
        const char *redirections, int fd)
{
    return create_and_write_idmap(target_apk_path, overlay_apk_path, redirections, fd, true) == 0 ?
    return create_and_write_idmap(target_apk_path, overlay_apk_path, target_hash, overlay_hash,
            redirections, fd, true) == 0 ?
        EXIT_SUCCESS : EXIT_FAILURE;
}
+16 −8
Original line number Diff line number Diff line
@@ -114,7 +114,8 @@ NOTES \n\
    }

    int maybe_create_fd(const char *target_apk_path, const char *overlay_apk_path,
            const char *idmap_str, const char *redirections)
            const char *idmap_str, const char *target_hash_str, const char *overlay_hash_str,
            const char *redirections)
    {
        // anyone (not just root or system) may do --fd -- the file has
        // already been opened by someone else on our behalf
@@ -135,12 +136,16 @@ NOTES \n\
            ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno));
            return -1;
        }
        int target_hash = strtol(target_hash_str, 0, 10);
        int overlay_hash = strtol(overlay_hash_str, 0, 10);

        return idmap_create_fd(target_apk_path, overlay_apk_path, redirections, idmap_fd);
        return idmap_create_fd(target_apk_path, overlay_apk_path, target_hash, overlay_hash,
                redirections, idmap_fd);
    }

    int maybe_create_path(const char *target_apk_path, const char *overlay_apk_path,
            const char *idmap_path, const char *redirections)
            const char *idmap_path, const char *target_hash_str, const char *overlay_hash_str,
            const char *redirections)
    {
        if (!verify_root_or_system()) {
            fprintf(stderr, "error: permission denied: not user root or user system\n");
@@ -157,7 +162,10 @@ NOTES \n\
            return -1;
        }

        return idmap_create_path(target_apk_path, overlay_apk_path, redirections, idmap_path);
        int target_hash = strtol(target_hash_str, 0, 10);
        int overlay_hash = strtol(overlay_hash_str, 0, 10);
        return idmap_create_path(target_apk_path, overlay_apk_path, target_hash, overlay_hash,
                redirections, idmap_path);
    }

    int maybe_scan(const char *overlay_dir, const char *target_package_name,
@@ -216,12 +224,12 @@ int main(int argc, char **argv)
        return 0;
    }

    if (argc == 6 && !strcmp(argv[1], "--fd")) {
        return maybe_create_fd(argv[2], argv[3], argv[4], argv[5]);
    if (argc == 8 && !strcmp(argv[1], "--fd")) {
        return maybe_create_fd(argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
    }

    if (argc == 6 && !strcmp(argv[1], "--path")) {
        return maybe_create_path(argv[2], argv[3], argv[4], argv[5]);
    if (argc == 8 && !strcmp(argv[1], "--path")) {
        return maybe_create_path(argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
    }

    if (argc == 6 && !strcmp(argv[1], "--scan")) {
+2 −0
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@
#endif

int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path,
        uint32_t target_hash, uint32_t overlay_hash,
        const char *redirections, const char *idmap_path);

int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path,
        uint32_t target_hash, uint32_t overlay_hash,
        const char *redirections, int fd);

// Regarding target_package_name: the idmap_scan implementation should
+1 −1
Original line number Diff line number Diff line
@@ -223,7 +223,7 @@ int idmap_scan(const char *overlay_dir, const char *target_package_name,
        idmap_path.appendPath(flatten_path(overlay_apk_path + 1));
        idmap_path.append("@idmap");

        if (idmap_create_path(target_apk_path, overlay_apk_path, 0, idmap_path.string()) != 0) {
        if (idmap_create_path(target_apk_path, overlay_apk_path, 0, 0, 0, idmap_path.string()) != 0) {
            ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n",
                    target_apk_path, overlay_apk_path, idmap_path.string());
            continue;
+11 −4
Original line number Diff line number Diff line
@@ -1139,15 +1139,21 @@ int restorecon_data()
    return ret;
}

static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd, const char *redirectionsPath)
static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd,
                      uint32_t target_hash, uint32_t overlay_hash, const char *redirectionsPath)
{
    static const char *IDMAP_BIN = "/system/bin/idmap";
    static const size_t MAX_INT_LEN = 32;
    char idmap_str[MAX_INT_LEN];
    char target_hash_str[MAX_INT_LEN];
    char overlay_hash_str[MAX_INT_LEN];

    snprintf(idmap_str, sizeof(idmap_str), "%d", idmap_fd);
    snprintf(target_hash_str, sizeof(target_hash_str), "%d", target_hash);
    snprintf(overlay_hash_str, sizeof(overlay_hash_str), "%d", overlay_hash);

    execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, idmap_str, redirectionsPath, (char*)NULL);
    execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, idmap_str,
            target_hash_str, overlay_hash_str, redirectionsPath, (char*)NULL);
    ALOGE("execl(%s) failed: %s\n", IDMAP_BIN, strerror(errno));
}

@@ -1195,7 +1201,8 @@ static int flatten_path(const char *prefix, const char *suffix,
    return 0;
}

int idmap(const char *target_apk, const char *overlay_apk, uid_t uid, const char *redirections)
int idmap(const char *target_apk, const char *overlay_apk, uid_t uid,
          uint32_t target_hash, uint32_t overlay_hash, const char *redirections)
{
    ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid);

@@ -1240,7 +1247,7 @@ int idmap(const char *target_apk, const char *overlay_apk, uid_t uid, const char
            exit(1);
        }

        run_idmap(target_apk, overlay_apk, idmap_fd, redirections);
        run_idmap(target_apk, overlay_apk, idmap_fd, target_hash, overlay_hash, redirections);
        exit(1); /* only if exec call to idmap failed */
    } else {
        int status = wait_child(pid);
Loading