diff options
author | 2016-06-02 09:35:31 +0200 | |
---|---|---|
committer | 2017-02-23 14:01:38 -0800 | |
commit | 2e0d0f311100d8e0bb40d7d60b8498237f011f0c (patch) | |
tree | 00377afd35d28d384d4ad735b250051481debe31 /cmds/idmap/scan.cpp | |
parent | 8716ef94194ad715ef596de4a38abb5b2a5c8186 (diff) |
OMS: integrate OverlayManagerService into framework
Hand over ownership of overlays to OverlayManagerService.
Changes to a package's overlays are propagated using the activity life
cycle. Affected activities will be recreated as needed. This provides a
well-defined point to modify an application's assets while the
application is paused.
Consolidate how overlays targeting the system and overlays targeting
regular applications are handled. Previously, system overlays were
handled as a special case. Now, everything is handled identically. As a
side effect, the call to idmap --scan during Zygote boot has become
obsolete and is removed.
Information on what overlays to use is recorded in
ApplicationInfo.resourceDirs. The PackageManagerService is responsible
for the creation of ApplicationInfo objects. The OverlayManagerService
is responsible for informing the PackageManagerService in advance about
what resourceDirs to use.
When launching an application, the ApplicationInfo is already populated
with up-to-date information about overlays.
When enabling or disabling an overlay for a running application, the
OverlayManagerService first notifies the PackageManagerService about the
updated resourceDirs. It then tells the ActivityManagerService to push
the new ApplicationInfo object to the application's ActivityThread.
Finally the application requests its ResourcesManager to create new
ResourcesImpl objects based on the updated paths.
Change-Id: Ib8afa05ccab4e2db558f89ce4423983c086bb61a
Co-authored-by: Martin Wallgren <martin.wallgren@sonymobile.com>
Signed-off-by: Zoran Jovanovic <zoran.jovanovic@sonymobile.com>
Bug: 31052947
Test: run tests from 'OMS: tests for OverlayManagerService'
Diffstat (limited to 'cmds/idmap/scan.cpp')
-rw-r--r-- | cmds/idmap/scan.cpp | 239 |
1 files changed, 0 insertions, 239 deletions
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp deleted file mode 100644 index ab6adfb9475f..000000000000 --- a/cmds/idmap/scan.cpp +++ /dev/null @@ -1,239 +0,0 @@ -#include <dirent.h> -#include <inttypes.h> -#include <sys/file.h> -#include <sys/stat.h> - -#include "idmap.h" - -#include <memory> -#include <androidfw/ResourceTypes.h> -#include <androidfw/StreamingZipInflater.h> -#include <androidfw/ZipFileRO.h> -#include <private/android_filesystem_config.h> // for AID_SYSTEM -#include <utils/SortedVector.h> -#include <utils/String16.h> -#include <utils/String8.h> - -#define NO_OVERLAY_TAG (-1000) - -using namespace android; - -namespace { - struct Overlay { - Overlay() {} - Overlay(const String8& a, const String8& i, int p) : - apk_path(a), idmap_path(i), priority(p) {} - - bool operator<(Overlay const& rhs) const - { - return rhs.priority > priority; - } - - String8 apk_path; - String8 idmap_path; - int priority; - }; - - bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector) - { - // the file is opened for appending so that it doesn't get truncated - // before we can guarantee mutual exclusion via the flock - FILE* fout = fopen(filename, "a"); - if (fout == NULL) { - return false; - } - - if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) { - fclose(fout); - return false; - } - - if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) { - TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN)); - fclose(fout); - return false; - } - - for (size_t i = 0; i < overlayVector.size(); ++i) { - const Overlay& overlay = overlayVector[i]; - fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string()); - } - - TEMP_FAILURE_RETRY(fflush(fout)); - TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN)); - fclose(fout); - - // Make file world readable since Zygote (running as root) will read - // it when creating the initial AssetManger object - const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644 - if (chmod(filename, mode) == -1) { - unlink(filename); - return false; - } - - return true; - } - - String8 flatten_path(const char *path) - { - String16 tmp(path); - tmp.replaceAll('/', '@'); - return String8(tmp); - } - - int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name) - { - const size_t N = parser.getAttributeCount(); - String16 target; - int priority = -1; - for (size_t i = 0; i < N; ++i) { - size_t len; - String16 key(parser.getAttributeName(i, &len)); - if (key == String16("targetPackage")) { - const char16_t *p = parser.getAttributeStringValue(i, &len); - if (p != NULL) { - target = String16(p, len); - } - } else if (key == String16("priority")) { - Res_value v; - if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { - priority = v.data; - if (priority < 0 || priority > 9999) { - return -1; - } - } - } - } - if (target == String16(target_package_name)) { - return priority; - } - return NO_OVERLAY_TAG; - } - - int parse_manifest(const void *data, size_t size, const char *target_package_name) - { - ResXMLTree parser; - parser.setTo(data, size); - if (parser.getError() != NO_ERROR) { - ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError()); - return -1; - } - - ResXMLParser::event_code_t type; - do { - type = parser.next(); - if (type == ResXMLParser::START_TAG) { - size_t len; - String16 tag(parser.getElementName(&len)); - if (tag == String16("overlay")) { - return parse_overlay_tag(parser, target_package_name); - } - } - } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT); - - return NO_OVERLAY_TAG; - } - - int parse_apk(const char *path, const char *target_package_name) - { - std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(path)); - if (zip.get() == NULL) { - ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path); - return -1; - } - ZipEntryRO entry; - if ((entry = zip->findEntryByName("AndroidManifest.xml")) == NULL) { - ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__); - return -1; - } - uint32_t uncompLen = 0; - uint16_t method; - if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) { - ALOGW("%s: failed to read entry info\n", __FUNCTION__); - return -1; - } - if (method != ZipFileRO::kCompressDeflated) { - ALOGW("%s: cannot handle zip compression method %" PRIu16 "\n", __FUNCTION__, method); - return -1; - } - FileMap *dataMap = zip->createEntryFileMap(entry); - if (dataMap == NULL) { - ALOGW("%s: failed to create FileMap\n", __FUNCTION__); - return -1; - } - char *buf = new char[uncompLen]; - if (NULL == buf) { - ALOGW("%s: failed to allocate %" PRIu32 " byte\n", __FUNCTION__, uncompLen); - delete dataMap; - return -1; - } - StreamingZipInflater inflater(dataMap, uncompLen); - if (inflater.read(buf, uncompLen) < 0) { - ALOGW("%s: failed to inflate %" PRIu32 " byte\n", __FUNCTION__, uncompLen); - delete[] buf; - delete dataMap; - return -1; - } - - int priority = parse_manifest(buf, static_cast<size_t>(uncompLen), target_package_name); - delete[] buf; - delete dataMap; - return priority; - } -} - -int idmap_scan(const char *target_package_name, const char *target_apk_path, - const char *idmap_dir, const android::Vector<const char *> *overlay_dirs) -{ - String8 filename = String8(idmap_dir); - filename.appendPath("overlays.list"); - - SortedVector<Overlay> overlayVector; - const size_t N = overlay_dirs->size(); - for (size_t i = 0; i < N; ++i) { - const char *overlay_dir = overlay_dirs->itemAt(i); - DIR *dir = opendir(overlay_dir); - if (dir == NULL) { - return EXIT_FAILURE; - } - - struct dirent *dirent; - while ((dirent = readdir(dir)) != NULL) { - struct stat st; - char overlay_apk_path[PATH_MAX + 1]; - snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name); - if (stat(overlay_apk_path, &st) < 0) { - continue; - } - if (!S_ISREG(st.st_mode)) { - continue; - } - - int priority = parse_apk(overlay_apk_path, target_package_name); - if (priority < 0) { - continue; - } - - String8 idmap_path(idmap_dir); - idmap_path.appendPath(flatten_path(overlay_apk_path + 1)); - idmap_path.append("@idmap"); - - if (idmap_create_path(target_apk_path, overlay_apk_path, 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; - } - - Overlay overlay(String8(overlay_apk_path), idmap_path, priority); - overlayVector.add(overlay); - } - - closedir(dir); - } - - if (!writePackagesList(filename.string(), overlayVector)) { - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} |