Android OTA Upgrade Package Production script detailed (five, upgrade script Updater-script <1>)

Source: Internet
Author: User
Tags strtok ziparchive

Write in front:

First, when we execute the upgrade script updater-script, it means that we have entered the upgrade installation state. So let's start with the actual installation as a portal. That is to say, we start with the Install_package function in install.cpp to analyze it step-by-step.

Here is the main analysis of the script-related sections, others please refer to this friend's blog http://blog.chinaunix.net/uid-22028566-id-3533856.html, I am also very inspired. A diagram is also borrowed to help with the analysis on the process.


Here is the process of the invocation: Install_package ()-->really_install_package (), then the logic to actually start the installation in the Really_install_package () function is as follows:

    /* Verify and install the contents of the package.     *    /Ui->print ("Installing update...\n");    Err = try_update_binary (path, &zip, Wipe_cache);    if (err! = install_success)        return err;
Try_update_binary is a real implementation of reading the script files in the upgrade package and executing the corresponding functions. In this function, a child process is created by calling the fork function to begin reading and executing the upgrade script file in the child process. Note Here is the use of function fork, Fork is called once, will do two returns, the process ID of the child process is returned in the parent process, is a positive number, and in the child process, 0 is returned. The EXECV (binary, args) that is performed in the child process. After the child process is successfully created, the upgrade code is started and the process interacts with the parent (creating the pipeline and passing pipefd[1] as a parameter to the child process, and the child process writes the relevant information to the pipeline descriptor), while the parent process updates the UI by reading the information passed by the child process.

So let's take a concrete look at the specific logic of this method.

Static inttry_update_binary (const char *path, ziparchive *zip, int* wipe_cache) {//defines a constant used to encapsulate the results of finding the zip-off information such as "Meta-inf/co M/google/android/update-binary "To facilitate subsequent decompression, since the Mzopenziparchive function did not decompress the update package, * Zip is a Ziparchive object returned by the Mzopenziparchive method. Mzopenziparchive is to open the upgrade package and copy the relevant information into a temporary ziparchinve variable. Assumed_update_binary_name= "meta-inf/com/google/android/update-binary" Const zipentry* binary_entry = MzFi    Ndzipentry (Zip, assumed_update_binary_name);        if (binary_entry = = NULL) {mzcloseziparchive (Zip);    return install_corrupt;    } const char* binary = "/tmp/update_binary";    unlink (binary);//create "/tmp/update_binary" file int fd = creat (binary, 0755);        if (FD < 0) {mzcloseziparchive (Zip);        LOGE ("Can ' t make%s\n", binary);    return install_error; }//Extract the contents of the meta-inf/com/google/android/update-binary to "/tmp/update_binary".    In fact, this method is mainly for update_binary operations, such as decompression and execution.    bool OK = mzextractzipentrytofile (zip, binary_entry, FD);    Close (FD); MzCloseziparchive (Zip);        if (!ok) {LOGE ("Can ' t copy%s\n", Assumed_update_binary_name);    return install_error;    } int pipefd[2];//creates a pipeline for communication between the following child process and the parent process pipe (PIPEFD); When executing the update binary contained in the package, the//arguments passed is:////-The version Number for this interface////-a FD to which the program can write on order to update the//progress B  Ar.  The program can write Single-line commands:////Progress <frac> <secs>//fill up  The next <frac> part's of the progress bar//over <secs> seconds. If <secs> is zero, use//set_progress commands to manually control the//progress of T His segment of the bar////Set_progress <frac>//<frac> should is between 0.0 an d 1.0;       Sets the//progress bar within the segment defined by the most//     Recent Progress command. Firmware < "Hboot" | " Radio "> <filename>//Arrange to install the contents of <filename> in the//g    Iven partition on reboot. (API v2: <filename> may start with ' package: ' to//indicate taking a file from th    e OTA package.)    (API v3:this command no longer exists.)    Ui_print <string>//Display <string> on the screen.    -The name of the package zip file.    Const char** args = (const char**) malloc (sizeof (char*) * 5);    Args[0] = binary;   ARGS[1] = EXPAND (recovery_api_version);    defined in android.mk char* temp = (char*) malloc (10);    sprintf (temp, "%d", pipefd[1]);    ARGS[2] = temp;    ARGS[3] = (char*) path; ARGS[4] = null;//Create child process. The child process is primarily responsible for executing binary (EXECV (Binary,args), which is executing our installation command script), and the parent process is responsible for accepting commands sent by the child process to update the UI display (showing the current progress).    Child parent interprocess communication relies on pipelines.    pid_t pid = fork (); If(PID = = 0) {Close (pipefd[0]);//execute <span style= "font-family:arial, Helvetica, Sans-serif;" >update-binary</span><span style= "font-family:arial, Helvetica, Sans-serif;" The essence of this program is to parse the commands in the Updater-script script in the Update.zip package and execute them. As a result, the recovery service enters the process of actually installing the Update.zip package. </span><span style= "font-family:arial, Helvetica, Sans-serif;" > When executing the EXECV function, Execv stops executing the current process and replaces the stopped process with the Progname application process, and the process ID does not change. The progname here refers to </span><span style= "font-family:arial, Helvetica, Sans-serif;" >update-binary</span><span style= "font-family:arial, Helvetica, Sans-serif;" The application that is executed. The second parameter, argv, refers to running </span><span style= "font-family:arial, Helvetica, Sans-serif;" >update-binary</span><span style= "font-family:arial, Helvetica, Sans-serif;" >t The argument list passed to the executing program, note that the first parameter of the array should be the application name itself, and the last parameter should be null, not arguments multiple parameters into an array. </span><span style= "font-family:arial, Helvetica, Sans-serif;" ></span> In addition, if the application finishes properly, then EXECV is never returned, and when Execv returns in the calling processBack, then this application should be wrong (perhaps the program itself is not found, not enough permissions ...), at this time its return value should be 1, the specific error code can be viewed through the global variable errno, you can also get a specific error description string through stderr. EXECV (binary, (char* const*) args);//actually my understanding is <span style= "font-family:arial, Helvetica, Sans-serif;" >update-binary quite an EXE executable, here is a double-click on the Executables </span> fprintf (stdout, "E:can ' t run%s (%s) \ n", binary, Strerr        or (errno));    _exit (-1);    } close (pipefd[1]);    *wipe_cache = 0;    Char buffer[1024];    file* from_child = Fdopen (Pipefd[0], "R");        while (fgets (buffer, sizeof (buffer), from_child) = NULL) {char* command = strtok (buffer, "\ n");        if (Command = = NULL) {continue;            } else if (strcmp (Command, "progress") = = 0) {char* fraction_s = strtok (NULL, "\ n");            char* seconds_s = strtok (NULL, "\ n");            float fraction = Strtof (fraction_s, NULL);            int seconds = Strtol (seconds_s, NULL, 10);        Ui->showprogress (fraction * (1-verification_progress_fraction), seconds); } else IF (strcmp (Command, "set_progress") = = 0) {char* fraction_s = strtok (NULL, "\ n");            float fraction = Strtof (fraction_s, NULL);        Ui->setprogress (fraction);            } else if (strcmp (command, "ui_print") = = 0) {char* str = strtok (NULL, "\ n");            if (str) {ui->print ("%s", str);            } else {ui->print ("\ n");        } fflush (stdout); } else if (strcmp (command, "wipe_cache") = = 0) {*wipe_cache = 1; #if 1//wschen 2012-07-25} else if (St RCMP (Command, "special_factory_reset") = = 0) {*wipe_cache = 2; #endif} else if (strcmp command, "Clear_        Display ") = = 0) {ui->setbackground (recoveryui::none);        } else {LOGE ("Unknown command [%s]\n", command);    }} fclose (From_child);    int status;    Waitpid (PID, &status, 0); if (! wifexited (status) | | Wexitstatus (status)! = 0) {LOGE ("Error in%s\n (Status%d) \ n ", Path, Wexitstatus (status));    return install_error; } #ifdef support_data_backup_restore//wschen 2011-03-09//skip userdata RESTORE if updating from/data with No/data layou T Changeif (!usrdata_changed && update_from_data) {ui->print ("/data offset remains the same no need to restor e usrdata\n ");} else{if (part_size_changed) {if (ensure_path_mounted ("/sdcard")! = 0) {LOGE ("Can ' t Mount%s\n", PA            TH);        return install_no_sdcard;        } if (Userdata_restore (Backup_path, 1)) {return install_file_system_error;        }}} #endif//support_data_backup_restore/*-----------------------------*/* SECURE BOOT UPDATE */ /*-----------------------------*/#ifdef support_sboot_update sec_update (false); #endif return in stall_success;}

Android OTA Upgrade Package Production script detailed (five, upgrade script Updater-script <1>)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.