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

Commit 7317cb6f authored by Steve Kondik's avatar Steve Kondik
Browse files

Perform zipalign-on-install of applications.

This change has a few components.

1. Build zipalign for the target.
2. Don't start the AppDirObservers until after scanDirLI completes
3. Execute zipalign from installd before performing a dexopt.
parent 2ab6a019
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ int install(const char *pkgname, uid_t uid, gid_t gid)
    char pkgdir[PKG_PATH_MAX];
    char libdir[PKG_PATH_MAX];

    LOGI("installer: dir: %s pkg: %s", pkgdir, pkgname);
    if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
        LOGE("invalid uid/gid: %d %d\n", uid, gid);
        return -1;
@@ -429,6 +430,45 @@ static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name,
    LOGE("execl(%s) failed: %s\n", DEX_OPT_BIN, strerror(errno));
}

static void run_zipalign(const char* input_file, const char* output_file)
{
    static const char* ZIPALIGN_BIN = "/system/bin/zipalign";
    execl(ZIPALIGN_BIN, ZIPALIGN_BIN, "4", input_file, output_file, (char*) NULL);
    LOGE("execl(%s) failed: %s\n", ZIPALIGN_BIN, strerror(errno));
}

static int wait_zipalign(pid_t pid, const char* apk_path)
{
    int status;
    pid_t got_pid;

    /*
     * Wait for the zipalign process to finish.
     */
    while (1) {
        got_pid = waitpid(pid, &status, 0);
        if (got_pid == -1 && errno == EINTR) {
            printf("waitpid interrupted, retrying\n");
        } else {
            break;
        }
    }
    if (got_pid != pid) {
        LOGW("waitpid failed: wanted %d, got %d: %s\n",
            (int) pid, (int) got_pid, strerror(errno));
        return 1;
    }

    if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
        LOGD("ZipAlign: --- END '%s' (success) ---\n", apk_path);
        return 0;
    } else {
        LOGW("ZipAlign: --- END '%s' --- status=0x%04x, process failed\n",
            apk_path, status);
        return status;      /* always nonzero */
    }
}

static int wait_dexopt(pid_t pid, const char* apk_path)
{
    int status;
@@ -461,6 +501,58 @@ static int wait_dexopt(pid_t pid, const char* apk_path)
    }
}

int zipalign(const char *apk_path, uid_t uid, int is_public)
{
    char za_path[PKG_PATH_MAX];
    struct utimbuf ut;
    struct stat za_stat, apk_stat;
    int res;
    
    memset(&apk_stat, 0, sizeof(apk_stat));
    stat(apk_path, &apk_stat);

    strcpy(za_path, apk_path);
    strcat(za_path, ".tmp");
    LOGD("ZipAlign: --- BEGIN '%s' ---\n", apk_path);
    
    pid_t pid;
    pid = fork();
    if (pid == 0) {
        run_zipalign(apk_path, za_path);
        exit(67);
    } else {
        res = wait_zipalign(pid, za_path);
        if (res != 0) {
            LOGE("zipalign failed on '%s' res = %d\n", za_path, res);
            goto fail;
        }
   }
    
    if (chown(za_path, apk_stat.st_uid, apk_stat.st_gid) < 0) {
        LOGE("zipalign cannot chown '%s'", apk_path);
        goto fail;
    }
    if (chmod(za_path, S_IRUSR|S_IWUSR|S_IRGRP |
        (is_public ? S_IROTH : 0)) < 0) {
	    LOGE("zipalign cannot chmod '%s'\n", apk_path);
	    goto fail;
    }

    ut.actime = apk_stat.st_atime;
    ut.modtime = apk_stat.st_mtime;
    utime(za_path, &ut);

    unlink(apk_path);
    rename(za_path, apk_path);

    return 0;

fail:
    unlink(za_path);
    return -1;

}

int dexopt(const char *apk_path, uid_t uid, int is_public)
{
    struct utimbuf ut;
@@ -477,6 +569,10 @@ int dexopt(const char *apk_path, uid_t uid, int is_public)
        return -1;
    }
    
    if (strncmp(apk_path, "/system", 7) != 0) {
        zipalign(apk_path, uid, is_public);
    }

    /* platform-specific flags affecting optimization and verification */
    property_get("dalvik.vm.dexopt-flags", dexopt_flags, "");

+25 −0
Original line number Diff line number Diff line
# 
# Copyright 2008 The Android Open Source Project
#
# Zip alignment tool
#

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
	../../../../build/tools/zipalign/ZipFile.cpp \
	../../../../build/tools/zipalign/ZipEntry.cpp \
	../../../../build/tools/zipalign/ZipAlign.cpp

LOCAL_C_INCLUDES := external/zlib build/tools/zipalign

LOCAL_SHARED_LIBRARIES := \
	libz \
	libutils \
	libcutils 

LOCAL_MODULE := zipalign

include $(BUILD_EXECUTABLE)
+2 −2
Original line number Diff line number Diff line
@@ -574,13 +574,13 @@ class PackageManagerService extends IPackageManager.Stub {
                    SystemClock.uptimeMillis());
            mAppInstallObserver = new AppDirObserver(
                mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
            mAppInstallObserver.startWatching();
            scanDirLI(mAppInstallDir, 0, scanMode);
            mAppInstallObserver.startWatching();

            mDrmAppInstallObserver = new AppDirObserver(
                mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
            mDrmAppInstallObserver.startWatching();
            scanDirLI(mDrmAppPrivateInstallDir, 0, scanMode | SCAN_FORWARD_LOCKED);
            mDrmAppInstallObserver.startWatching();

            EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());