Home | History | Annotate | Download | only in setup
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_INSTALLER_SETUP_ARCHIVE_PATCH_HELPER_H_
      6 #define CHROME_INSTALLER_SETUP_ARCHIVE_PATCH_HELPER_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/files/file_path.h"
     10 
     11 namespace installer {
     12 
     13 // A helper class that facilitates uncompressing and patching the chrome archive
     14 // and installer.
     15 //
     16 // Chrome's installer is deployed along with a compressed archive containing
     17 // either 1) an uncompressd archive of the product binaries or 2) a patch file
     18 // to be applied to the uncompressed archive of the version being updated. To
     19 // obtain the uncompressed archive, the contents of the compressed archive are
     20 // uncompressed and extracted. Installation proceeds directly if the
     21 // uncompressed archive is found after this step. Otherwise, the patch is
     22 // applied to the previous version's uncompressed archive using either
     23 // Courgette's ensemble patching or bspatch.
     24 //
     25 // Chrome's installer itself may also be deployed as a patch against the
     26 // previous version's saved installer binary. The same process is followed to
     27 // obtain the new installer. The compressed archive unconditionally contains a
     28 // patch file in this case.
     29 class ArchivePatchHelper {
     30  public:
     31   // Constructs an instance that can uncompress |compressed_archive| into
     32   // |working_directory| and optionally apply the extracted patch file to
     33   // |patch_source|, writing the result to |target|.
     34   ArchivePatchHelper(const base::FilePath& working_directory,
     35                      const base::FilePath& compressed_archive,
     36                      const base::FilePath& patch_source,
     37                      const base::FilePath& target);
     38 
     39   ~ArchivePatchHelper();
     40 
     41   // Uncompresses |compressed_archive| in |working_directory| then applies the
     42   // extracted patch file to |patch_source|, writing the result to |target|.
     43   // Ensemble patching via Courgette is attempted first. If that fails, bspatch
     44   // is attempted. Returns false if uncompression or both patching steps fail.
     45   static bool UncompressAndPatch(const base::FilePath& working_directory,
     46                                  const base::FilePath& compressed_archive,
     47                                  const base::FilePath& patch_source,
     48                                  const base::FilePath& target);
     49 
     50   // Uncompresses compressed_archive() into the working directory. On success,
     51   // last_uncompressed_file (if not NULL) is populated with the path to the last
     52   // file extracted from the archive.
     53   bool Uncompress(base::FilePath* last_uncompressed_file);
     54 
     55   // Attempts to use courgette to apply last_uncompressed_file() to
     56   // patch_source() to generate target(). Returns false if patching fails.
     57   bool EnsemblePatch();
     58 
     59   // Attempts to use bspatch to apply last_uncompressed_file() to patch_source()
     60   // to generate target(). Returns false if patching fails.
     61   bool BinaryPatch();
     62 
     63   const base::FilePath& compressed_archive() const {
     64     return compressed_archive_;
     65   }
     66   void set_patch_source(const base::FilePath& patch_source) {
     67     patch_source_ = patch_source;
     68   }
     69   const base::FilePath& patch_source() const {
     70     return patch_source_;
     71   }
     72   const base::FilePath& target() const {
     73     return target_;
     74   }
     75 
     76   // Returns the path of the last file extracted by Uncompress().
     77   const base::FilePath& last_uncompressed_file() const {
     78     return last_uncompressed_file_;
     79   }
     80   void set_last_uncompressed_file(
     81       const base::FilePath& last_uncompressed_file) {
     82     last_uncompressed_file_ = last_uncompressed_file;
     83   }
     84 
     85  private:
     86   base::FilePath working_directory_;
     87   base::FilePath compressed_archive_;
     88   base::FilePath patch_source_;
     89   base::FilePath target_;
     90   base::FilePath last_uncompressed_file_;
     91 
     92   DISALLOW_COPY_AND_ASSIGN(ArchivePatchHelper);
     93 };
     94 
     95 }  // namespace installer
     96 
     97 #endif  // CHROME_INSTALLER_SETUP_ARCHIVE_PATCH_HELPER_H_
     98