113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include "idmap.h" 213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <androidfw/AssetManager.h> 413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <androidfw/ResourceTypes.h> 5ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <utils/ByteOrder.h> 613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <utils/String8.h> 713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <fcntl.h> 913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <sys/mman.h> 1013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross#include <sys/stat.h> 1113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 1213221c9cffdb289851411bdc73a9a5236fcb9291Colin Crossusing namespace android; 1313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 1413221c9cffdb289851411bdc73a9a5236fcb9291Colin Crossnamespace { 15f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski static const uint32_t IDMAP_MAGIC = 0x504D4449; 1613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross static const size_t PATH_LENGTH = 256; 1713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 1813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross void printe(const char *fmt, ...); 1913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 2013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross class IdmapBuffer { 2113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross private: 22f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski const char* buf_; 2313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross size_t len_; 24f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski size_t pos_; 2513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross public: 26f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski IdmapBuffer() : buf_((const char *)MAP_FAILED), len_(0), pos_(0) {} 2713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 2813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross ~IdmapBuffer() { 2913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (buf_ != MAP_FAILED) { 30f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski munmap(const_cast<char*>(buf_), len_); 3113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 3213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 3313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 34f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t init(const char *idmap_path) { 3513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross struct stat st; 3613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross int fd; 3713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 3813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (stat(idmap_path, &st) < 0) { 3913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to stat idmap '%s': %s\n", idmap_path, strerror(errno)); 40f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 4113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 4213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross len_ = st.st_size; 4313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if ((fd = TEMP_FAILURE_RETRY(open(idmap_path, O_RDONLY))) < 0) { 4413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to open idmap '%s': %s\n", idmap_path, strerror(errno)); 45f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 4613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 47f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if ((buf_ = (const char*)mmap(NULL, len_, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) { 4813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross close(fd); 4913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to mmap idmap: %s\n", strerror(errno)); 50f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 5113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 5213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross close(fd); 53f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return NO_ERROR; 5413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 5513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 56f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t nextUint32(uint32_t* i) { 5713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!buf_) { 5813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to read next uint32_t: buffer not initialized\n"); 59f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 6013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 61f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 62f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (pos_ + sizeof(uint32_t) > len_) { 6313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to read next uint32_t: end of buffer reached at pos=0x%08x\n", 6413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross pos_); 65f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 66f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 67f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 68f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if ((reinterpret_cast<uintptr_t>(buf_ + pos_) & 0x3) != 0) { 69f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski printe("failed to read next uint32_t: not aligned on 4-byte boundary\n"); 70f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 7113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 72f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 73f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski *i = dtohl(*reinterpret_cast<const uint32_t*>(buf_ + pos_)); 74f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski pos_ += sizeof(uint32_t); 75f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return NO_ERROR; 7613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 7713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 78f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t nextUint16(uint16_t* i) { 79f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (!buf_) { 80f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski printe("failed to read next uint16_t: buffer not initialized\n"); 81f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 82f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 83f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 84f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (pos_ + sizeof(uint16_t) > len_) { 85f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski printe("failed to read next uint16_t: end of buffer reached at pos=0x%08x\n", 86f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski pos_); 87f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 88f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 89f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 90f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if ((reinterpret_cast<uintptr_t>(buf_ + pos_) & 0x1) != 0) { 91f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski printe("failed to read next uint32_t: not aligned on 2-byte boundary\n"); 92f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 93f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 94f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 95f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski *i = dtohs(*reinterpret_cast<const uint16_t*>(buf_ + pos_)); 96f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski pos_ += sizeof(uint16_t); 97f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return NO_ERROR; 98f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 99f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 100f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t nextPath(char *b) { 10113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!buf_) { 10213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to read next path: buffer not initialized\n"); 103f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 10413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 10513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (pos_ + PATH_LENGTH > len_) { 10613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to read next path: end of buffer reached at pos=0x%08x\n", pos_); 107f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 10813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 10913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross memcpy(b, buf_ + pos_, PATH_LENGTH); 11013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross pos_ += PATH_LENGTH; 111f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return NO_ERROR; 11213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 11313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross }; 11413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 115f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski void printe(const char *fmt, ...) { 11613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_list ap; 11713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 11813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_start(ap, fmt); 11913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross fprintf(stderr, "error: "); 12013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross vfprintf(stderr, fmt, ap); 12113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_end(ap); 12213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 12313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 124f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski void print_header() { 125f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski printf("SECTION ENTRY VALUE COMMENT\n"); 12613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 12713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 128f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski void print(const char *section, const char *subsection, uint32_t value, const char *fmt, ...) { 12913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_list ap; 13013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 13113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_start(ap, fmt); 132f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski printf("%-12s %-12s 0x%08x ", section, subsection, value); 13313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross vprintf(fmt, ap); 13413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printf("\n"); 13513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_end(ap); 13613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 13713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 138f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski void print_path(const char *section, const char *subsection, const char *fmt, ...) { 13913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_list ap; 14013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 14113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_start(ap, fmt); 142f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski printf("%-12s %-12s .......... ", section, subsection); 14313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross vprintf(fmt, ap); 14413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printf("\n"); 14513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross va_end(ap); 14613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 14713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 148f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t resource_metadata(const AssetManager& am, uint32_t res_id, 149f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String8 *package, String8 *type, String8 *name) { 15013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross const ResTable& rt = am.getResources(); 15113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross struct ResTable::resource_name data; 15213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!rt.getResourceName(res_id, false, &data)) { 15313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to get resource name id=0x%08x\n", res_id); 154f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 15513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 156cfedceb8c180a2e176154d461659e0c3569dc931Andreas Gampe if (package != NULL) { 15713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross *package = String8(String16(data.package, data.packageLen)); 15813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 159cfedceb8c180a2e176154d461659e0c3569dc931Andreas Gampe if (type != NULL) { 16013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross *type = String8(String16(data.type, data.typeLen)); 16113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 162cfedceb8c180a2e176154d461659e0c3569dc931Andreas Gampe if (name != NULL) { 16313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross *name = String8(String16(data.name, data.nameLen)); 16413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 165f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return NO_ERROR; 16613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 16713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 168f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t parse_idmap_header(IdmapBuffer& buf, AssetManager& am) { 169f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski uint32_t i; 17013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross char path[PATH_LENGTH]; 17113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 172f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t err = buf.nextUint32(&i); 173f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 174f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 175f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 176f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 17713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (i != IDMAP_MAGIC) { 17813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("not an idmap file: actual magic constant 0x%08x does not match expected magic " 17913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross "constant 0x%08x\n", i, IDMAP_MAGIC); 180f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 18113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 182f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 18313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross print_header(); 184f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("IDMAP HEADER", "magic", i, ""); 185f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 186f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint32(&i); 187f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 188f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 189f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 190f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("", "version", i, ""); 19113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 192f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint32(&i); 193f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 194f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 195f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 196f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("", "base crc", i, ""); 19713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 198f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint32(&i); 199f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 200f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 201f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 202f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("", "overlay crc", i, ""); 20313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 204f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextPath(path); 205f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 20613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // printe done from IdmapBuffer::nextPath 207f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 20813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 209f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print_path("", "base path", "%s", path); 210f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 21113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (!am.addAssetPath(String8(path), NULL)) { 21213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross printe("failed to add '%s' as asset path\n", path); 213f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return UNKNOWN_ERROR; 21413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 21513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 216f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextPath(path); 217f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 21813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // printe done from IdmapBuffer::nextPath 219f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 22013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 221f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print_path("", "overlay path", "%s", path); 22213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 223f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return NO_ERROR; 22413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 22513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 226f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t parse_data(IdmapBuffer& buf, const AssetManager& am) { 227f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski const uint32_t packageId = am.getResources().getBasePackageId(0); 22813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 229f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski uint16_t data16; 230f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski status_t err = buf.nextUint16(&data16); 231f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 232f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 233f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 234f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("DATA HEADER", "target pkg", static_cast<uint32_t>(data16), ""); 23513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 236f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint16(&data16); 237f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 238f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 23913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 240f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("", "types count", static_cast<uint32_t>(data16), ""); 24113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 242f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski uint32_t typeCount = static_cast<uint32_t>(data16); 243f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski while (typeCount > 0) { 244f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski typeCount--; 245f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 246f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint16(&data16); 247f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 248f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 249f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 250f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski const uint32_t targetTypeId = static_cast<uint32_t>(data16); 251f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("DATA BLOCK", "target type", targetTypeId, ""); 25213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 253f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint16(&data16); 254f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 255f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 256f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 257f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("", "overlay type", static_cast<uint32_t>(data16), ""); 258f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 259f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint16(&data16); 260f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 261f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 262f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 263f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski const uint32_t entryCount = static_cast<uint32_t>(data16); 264f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("", "entry count", entryCount, ""); 265f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 266f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint16(&data16); 267f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 268f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 269f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 270f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski const uint32_t entryOffset = static_cast<uint32_t>(data16); 271f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("", "entry offset", entryOffset, ""); 272f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 273f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski for (uint32_t i = 0; i < entryCount; i++) { 274f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski uint32_t data32; 275f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = buf.nextUint32(&data32); 276f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 277f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 27813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 279f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 280f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski uint32_t resID = (packageId << 24) | (targetTypeId << 16) | (entryOffset + i); 281f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String8 type; 282f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski String8 name; 283f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski err = resource_metadata(am, resID, NULL, &type, &name); 284f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (err != NO_ERROR) { 285f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return err; 286f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski } 287f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski print("", "entry", data32, "%s/%s", type.string(), name.string()); 28813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 28913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 29013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 291f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski return NO_ERROR; 29213221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 29313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross} 29413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross 295f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinskiint idmap_inspect(const char *idmap_path) { 29613221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross IdmapBuffer buf; 29713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross if (buf.init(idmap_path) < 0) { 29813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // printe done from IdmapBuffer::init 29913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return EXIT_FAILURE; 30013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 30113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross AssetManager am; 302f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (parse_idmap_header(buf, am) != NO_ERROR) { 30313221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // printe done from parse_idmap_header 30413221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return EXIT_FAILURE; 30513221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 306f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski if (parse_data(buf, am) != NO_ERROR) { 30713221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross // printe done from parse_data_header 30813221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return EXIT_FAILURE; 30913221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross } 31013221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross return EXIT_SUCCESS; 31113221c9cffdb289851411bdc73a9a5236fcb9291Colin Cross} 312