17de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <dirent.h> 27de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <inttypes.h> 37de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <sys/file.h> 47de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <sys/stat.h> 57de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 67de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include "idmap.h" 77de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 87de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <memory> 97de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <androidfw/ResourceTypes.h> 107de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <androidfw/StreamingZipInflater.h> 117de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <androidfw/ZipFileRO.h> 120434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok#include <cutils/jstring.h> 13d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee#include <cutils/properties.h> 147de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <private/android_filesystem_config.h> // for AID_SYSTEM 157de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <utils/SortedVector.h> 167de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <utils/String16.h> 177de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#include <utils/String8.h> 187de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 197de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok#define NO_OVERLAY_TAG (-1000) 207de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 217de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seokusing namespace android; 227de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 237de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seoknamespace { 247de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok struct Overlay { 257de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok Overlay() {} 267de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok Overlay(const String8& a, const String8& i, int p) : 277de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok apk_path(a), idmap_path(i), priority(p) {} 287de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 297de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok bool operator<(Overlay const& rhs) const 307de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok { 317de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return rhs.priority > priority; 327de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 337de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 347de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String8 apk_path; 357de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String8 idmap_path; 367de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok int priority; 377de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok }; 387de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 397de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector) 407de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok { 417de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok // the file is opened for appending so that it doesn't get truncated 427de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok // before we can guarantee mutual exclusion via the flock 437de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok FILE* fout = fopen(filename, "a"); 447de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (fout == NULL) { 457de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return false; 467de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 477de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 487de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) { 497de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok fclose(fout); 507de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return false; 517de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 527de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 537de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) { 547de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN)); 557de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok fclose(fout); 567de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return false; 577de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 587de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 597de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok for (size_t i = 0; i < overlayVector.size(); ++i) { 607de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok const Overlay& overlay = overlayVector[i]; 617de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string()); 627de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 637de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 647de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok TEMP_FAILURE_RETRY(fflush(fout)); 657de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN)); 667de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok fclose(fout); 677de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 687de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok // Make file world readable since Zygote (running as root) will read 697de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok // it when creating the initial AssetManger object 707de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644 717de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (chmod(filename, mode) == -1) { 727de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok unlink(filename); 737de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return false; 747de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 757de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 767de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return true; 777de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 787de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 797de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String8 flatten_path(const char *path) 807de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok { 817de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String16 tmp(path); 827de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok tmp.replaceAll('/', '@'); 837de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return String8(tmp); 847de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 857de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 86d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee bool check_property(String16 property, String16 value) { 87d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee const char *prop; 88d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee const char *val; 89d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee 90d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee prop = strndup16to8(property.string(), property.size()); 91d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee char propBuf[PROPERTY_VALUE_MAX]; 92d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee property_get(prop, propBuf, NULL); 93d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee val = strndup16to8(value.string(), value.size()); 94d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee 95d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee return (strcmp(propBuf, val) == 0); 96d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee } 97d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee 980434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name, 990434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok bool* is_static_overlay) 1007de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok { 1017de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok const size_t N = parser.getAttributeCount(); 1027de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String16 target; 1037de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok int priority = -1; 104d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee String16 propName = String16(); 105d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee String16 propValue = String16(); 1067de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok for (size_t i = 0; i < N; ++i) { 1077de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok size_t len; 1087de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String16 key(parser.getAttributeName(i, &len)); 1097de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (key == String16("targetPackage")) { 1107de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok const char16_t *p = parser.getAttributeStringValue(i, &len); 1117de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (p != NULL) { 1127de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok target = String16(p, len); 1137de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1147de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } else if (key == String16("priority")) { 1157de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok Res_value v; 1167de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { 1177de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok priority = v.data; 1187de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (priority < 0 || priority > 9999) { 1197de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 1207de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1217de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1220434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } else if (key == String16("isStatic")) { 1230434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok Res_value v; 1240434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { 1250434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok *is_static_overlay = (v.data != 0); 1260434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 127d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee } else if (key == String16("requiredSystemPropertyName")) { 1280434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok const char16_t *p = parser.getAttributeStringValue(i, &len); 1290434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok if (p != NULL) { 130d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee propName = String16(p, len); 131d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee } 132d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee } else if (key == String16("requiredSystemPropertyValue")) { 133d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee const char16_t *p = parser.getAttributeStringValue(i, &len); 134d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee if (p != NULL) { 135d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee propValue = String16(p, len); 1360434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 1370434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 1380434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 1390434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok 140d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee // Note that conditional property enablement/exclusion only applies if 141d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee // the attribute is present. In its absence, all overlays are presumed enabled. 142d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee if (propName.size() > 0 && propValue.size() > 0) { 143d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee // if property set & equal to value, then include overlay - otherwise skip 144d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee if (!check_property(propName, propValue)) { 145d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee return NO_OVERLAY_TAG; 146d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee } 147d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee } 148d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee 149d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee if (target == String16(target_package_name)) { 150d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee return priority; 151d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee } 152d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee return NO_OVERLAY_TAG; 1530434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 1540434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok 1557de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok int parse_manifest(const void *data, size_t size, const char *target_package_name) 1567de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok { 1577de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ResXMLTree parser; 1587de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok parser.setTo(data, size); 1597de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (parser.getError() != NO_ERROR) { 1607de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError()); 1617de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 1627de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1637de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 1647de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ResXMLParser::event_code_t type; 1650434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok bool is_static_overlay = false; 1660434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok int priority = NO_OVERLAY_TAG; 1677de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok do { 1687de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok type = parser.next(); 1697de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (type == ResXMLParser::START_TAG) { 1707de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok size_t len; 1717de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String16 tag(parser.getElementName(&len)); 172d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee if (tag == String16("overlay")) { 1730434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok priority = parse_overlay_tag(parser, target_package_name, &is_static_overlay); 1740434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok break; 1757de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1767de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1777de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT); 1787de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 179d5566c6c47faa6b9dda282741e25ac78c9487d58Todd Lee if (is_static_overlay) { 1800434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return priority; 1810434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 1827de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return NO_OVERLAY_TAG; 1837de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1847de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 1857de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok int parse_apk(const char *path, const char *target_package_name) 1867de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok { 1877de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(path)); 1887de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (zip.get() == NULL) { 1897de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path); 1907de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 1917de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1927de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ZipEntryRO entry; 1937de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if ((entry = zip->findEntryByName("AndroidManifest.xml")) == NULL) { 1947de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__); 1957de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 1967de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 1977de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok uint32_t uncompLen = 0; 1987de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok uint16_t method; 1997de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) { 2007de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGW("%s: failed to read entry info\n", __FUNCTION__); 2017de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 2027de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2037de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (method != ZipFileRO::kCompressDeflated) { 2047de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGW("%s: cannot handle zip compression method %" PRIu16 "\n", __FUNCTION__, method); 2057de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 2067de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2077de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok FileMap *dataMap = zip->createEntryFileMap(entry); 2087de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (dataMap == NULL) { 2097de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGW("%s: failed to create FileMap\n", __FUNCTION__); 2107de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 2117de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2127de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok char *buf = new char[uncompLen]; 2137de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (NULL == buf) { 2147de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGW("%s: failed to allocate %" PRIu32 " byte\n", __FUNCTION__, uncompLen); 2157de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok delete dataMap; 2167de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 2177de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2187de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok StreamingZipInflater inflater(dataMap, uncompLen); 2197de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (inflater.read(buf, uncompLen) < 0) { 2207de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGW("%s: failed to inflate %" PRIu32 " byte\n", __FUNCTION__, uncompLen); 2217de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok delete[] buf; 2227de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok delete dataMap; 2237de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return -1; 2247de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2257de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2267de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok int priority = parse_manifest(buf, static_cast<size_t>(uncompLen), target_package_name); 2277de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok delete[] buf; 2287de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok delete dataMap; 2297de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return priority; 2307de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2317de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok} 2327de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2337de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seokint idmap_scan(const char *target_package_name, const char *target_apk_path, 2347de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok const char *idmap_dir, const android::Vector<const char *> *overlay_dirs) 2357de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok{ 2367de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String8 filename = String8(idmap_dir); 2377de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok filename.appendPath("overlays.list"); 2387de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2397de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok SortedVector<Overlay> overlayVector; 2407de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok const size_t N = overlay_dirs->size(); 2417de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok for (size_t i = 0; i < N; ++i) { 2427de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok const char *overlay_dir = overlay_dirs->itemAt(i); 2437de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok DIR *dir = opendir(overlay_dir); 2447de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (dir == NULL) { 2457de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return EXIT_FAILURE; 2467de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2477de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2487de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok struct dirent *dirent; 2497de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok while ((dirent = readdir(dir)) != NULL) { 2507de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok struct stat st; 2517de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok char overlay_apk_path[PATH_MAX + 1]; 2527de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name); 2537de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (stat(overlay_apk_path, &st) < 0) { 2547de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok continue; 2557de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2567de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (!S_ISREG(st.st_mode)) { 2577de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok continue; 2587de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2597de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2607de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok int priority = parse_apk(overlay_apk_path, target_package_name); 2617de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (priority < 0) { 2627de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok continue; 2637de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2647de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2657de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok String8 idmap_path(idmap_dir); 2667de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok idmap_path.appendPath(flatten_path(overlay_apk_path + 1)); 2677de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok idmap_path.append("@idmap"); 2687de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2697de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) { 2707de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n", 2717de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok target_apk_path, overlay_apk_path, idmap_path.string()); 2727de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok continue; 2737de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2747de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2757de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok Overlay overlay(String8(overlay_apk_path), idmap_path, priority); 2767de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok overlayVector.add(overlay); 2777de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2787de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2797de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok closedir(dir); 2807de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2817de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2827de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok if (!writePackagesList(filename.string(), overlayVector)) { 2837de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return EXIT_FAILURE; 2847de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok } 2857de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 2867de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok return EXIT_SUCCESS; 2877de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok} 2887de2f9c73fbe93bfb7dff3c046cf7a3137599f6cJaekyun Seok 289