android启动:app_process实现恢复出厂设置可恢复的apk预置


init.zygote64.rc 有如下代码:

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd


app_process启动zygote , zygote启动system-server 。





int main(int argc, char* const argv[])
{

    while (i < argc) {
        const char* arg = argv[i++];
        if (!parentDir) {
            parentDir = arg;
        } else if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = "zygote";
        } else if (strcmp(arg, "--start-system-server") == 0) {

            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName = arg + 12;
        } else {
            className = arg;
            break;
        }
    }


    if (niceName && *niceName) {
        setArgv0(argv0, niceName);
        set_process_name(niceName);
    }


    runtime.mParentDir = parentDir;


    if (zygote) {

        symlink_preload_apps();            //链接预置可卸载运用到data/app,这些应用恢复出厂设置可恢复

        runtime.start("com.android.internal.os.ZygoteInit",
               runtime.start("com.android.internal.os.ZygoteInit", args);    //启动zygote

    } else if (className) {
        // Remainder of args get passed to startup class main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        return 10;
    }
}


symlink_preload_apps实现如下:


void symlink_preload_apps() {
    char linked[128] ={0};
    property_get(PRELOAD_LINKED_PROPERTY, linked, "0");
    if (atoi(linked) && access(PRELOAD_NEED_RESET_MARK, F_OK)!=0 ){
        return;
    }
    for (size_t i = 0; i < sizeof(PRELOAD_DIRS)/sizeof(PRELOAD_DIRS[0]); i++) {
        //const nsecs_t now = systemTime();
        const char *dir = PRELOAD_DIRS[i];
        DIR *preload = opendir(dir);
        if (NULL == preload) {
                ALOGE("fail to open %s", dir);
                continue;
        }
        struct dirent *entry = NULL;


        while (NULL != (entry = readdir(preload))) {
                ALOGI("get entry: %s", entry->d_name);
                if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                        continue;
                symlink_app(dir, entry);
        }
        closedir(preload);
    }


    if( -1 == remove(PRELOAD_NEED_RESET_MARK) ){
        ALOGE("fail to remove %s (%s)", PRELOAD_NEED_RESET_MARK,strerror(errno));
    }
    property_set(PRELOAD_LINKED_PROPERTY, "1");
}



void symlink_app(const char* dir, dirent *entry) {
    if (NULL == entry) {
            return;
    }


    char from[128] = {0};
    char to[128] = {0};


    sprintf(from, "%s/%s", dir , entry->d_name);
    sprintf(to, "%s/%s", DATA_APP_DIR, entry->d_name);




    if (access(to, F_OK) == 0) {
            ALOGI("%s already exist", to);
            return ;
    }


    if (symlink(from, to) != 0) {
            ALOGE("link %s:%s error", from, to);
            return ;
    } 
    ALOGI("link %s:%s finished", from, to);
}


你可能感兴趣的:(android)