Home | History | Annotate | Download | only in component_updater
      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_BROWSER_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_
      6 #define CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_
      7 
      8 #include <string>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/callback.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/files/file_path.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "chrome/browser/component_updater/component_patcher.h"
     16 #include "chrome/browser/component_updater/component_unpacker.h"
     17 #include "content/public/browser/utility_process_host_client.h"
     18 
     19 namespace base {
     20 class DictionaryValue;
     21 }  // namespace base
     22 
     23 namespace component_updater {
     24 
     25 class ComponentInstaller;
     26 
     27 class DeltaUpdateOp : public base::RefCountedThreadSafe<DeltaUpdateOp> {
     28  public:
     29   DeltaUpdateOp();
     30 
     31   // Parses, runs, and verifies the operation. Calls |callback| with the
     32   // result of the operation. The callback is called using |task_runner|.
     33   void Run(const base::DictionaryValue* command_args,
     34            const base::FilePath& input_dir,
     35            const base::FilePath& unpack_dir,
     36            ComponentInstaller* installer,
     37            bool in_process,
     38            const ComponentUnpacker::Callback& callback,
     39            scoped_refptr<base::SequencedTaskRunner> task_runner);
     40 
     41  protected:
     42   virtual ~DeltaUpdateOp();
     43 
     44   bool InProcess();
     45 
     46   scoped_refptr<base::SequencedTaskRunner> GetTaskRunner();
     47 
     48   std::string output_sha256_;
     49   base::FilePath output_abs_path_;
     50 
     51  private:
     52   friend class base::RefCountedThreadSafe<DeltaUpdateOp>;
     53 
     54   ComponentUnpacker::Error CheckHash();
     55 
     56   // Subclasses must override DoParseArguments to parse operation-specific
     57   // arguments. DoParseArguments returns DELTA_OK on success; any other code
     58   // represents failure.
     59   virtual ComponentUnpacker::Error DoParseArguments(
     60       const base::DictionaryValue* command_args,
     61       const base::FilePath& input_dir,
     62       ComponentInstaller* installer) = 0;
     63 
     64   // Subclasses must override DoRun to actually perform the patching operation.
     65   // They must call the provided callback when they have completed their
     66   // operations. In practice, the provided callback is always for "DoneRunning".
     67   virtual void DoRun(const ComponentUnpacker::Callback& callback) = 0;
     68 
     69   // Callback given to subclasses for when they complete their operation.
     70   // Validates the output, and posts a task to the patching operation's
     71   // callback.
     72   void DoneRunning(ComponentUnpacker::Error error, int extended_error);
     73 
     74   bool in_process_;
     75   ComponentUnpacker::Callback callback_;
     76   scoped_refptr<base::SequencedTaskRunner> task_runner_;
     77 
     78   DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOp);
     79 };
     80 
     81 // A 'copy' operation takes a file currently residing on the disk and moves it
     82 // into the unpacking directory: this represents "no change" in the file being
     83 // installed.
     84 class DeltaUpdateOpCopy : public DeltaUpdateOp {
     85  public:
     86   DeltaUpdateOpCopy();
     87 
     88  private:
     89   virtual ~DeltaUpdateOpCopy();
     90 
     91   // Overrides of DeltaUpdateOp.
     92   virtual ComponentUnpacker::Error DoParseArguments(
     93       const base::DictionaryValue* command_args,
     94       const base::FilePath& input_dir,
     95       ComponentInstaller* installer) OVERRIDE;
     96 
     97   virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE;
     98 
     99   base::FilePath input_abs_path_;
    100 
    101   DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpCopy);
    102 };
    103 
    104 // A 'create' operation takes a full file that was sent in the delta update
    105 // archive and moves it into the unpacking directory: this represents the
    106 // addition of a new file, or a file so different that no bandwidth could be
    107 // saved by transmitting a differential update.
    108 class DeltaUpdateOpCreate : public DeltaUpdateOp {
    109  public:
    110   DeltaUpdateOpCreate();
    111 
    112  private:
    113   virtual ~DeltaUpdateOpCreate();
    114 
    115   // Overrides of DeltaUpdateOp.
    116   virtual ComponentUnpacker::Error DoParseArguments(
    117       const base::DictionaryValue* command_args,
    118       const base::FilePath& input_dir,
    119       ComponentInstaller* installer) OVERRIDE;
    120 
    121   virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE;
    122 
    123   base::FilePath patch_abs_path_;
    124 
    125   DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpCreate);
    126 };
    127 
    128 class DeltaUpdateOpPatchStrategy {
    129  public:
    130   virtual ~DeltaUpdateOpPatchStrategy();
    131 
    132   // Returns an integer to add to error codes to disambiguate their source.
    133   virtual int GetErrorOffset() const = 0;
    134 
    135   // Returns the "error code" that is expected in the successful install case.
    136   virtual int GetSuccessCode() const = 0;
    137 
    138   // Returns an IPC message that will start patching if it is sent to a
    139   // UtilityProcessClient.
    140   virtual scoped_ptr<IPC::Message> GetPatchMessage(
    141       base::FilePath input_abs_path,
    142       base::FilePath patch_abs_path,
    143       base::FilePath output_abs_path) = 0;
    144 
    145   // Does the actual patching operation, and returns an error code.
    146   virtual int Patch(base::FilePath input_abs_path,
    147                     base::FilePath patch_abs_path,
    148                     base::FilePath output_abs_path) = 0;
    149 };
    150 
    151 class DeltaUpdateOpPatch;
    152 
    153 class DeltaUpdateOpPatchHost : public content::UtilityProcessHostClient {
    154  public:
    155   DeltaUpdateOpPatchHost(scoped_refptr<DeltaUpdateOpPatch> patcher,
    156                          scoped_refptr<base::SequencedTaskRunner> task_runner);
    157 
    158   void StartProcess(scoped_ptr<IPC::Message> message);
    159 
    160  private:
    161   virtual ~DeltaUpdateOpPatchHost();
    162 
    163   void OnPatchSucceeded();
    164 
    165   void OnPatchFailed(int error_code);
    166 
    167   // Overrides of content::UtilityProcessHostClient.
    168   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
    169 
    170   virtual void OnProcessCrashed(int exit_code) OVERRIDE;
    171 
    172   scoped_refptr<DeltaUpdateOpPatch> patcher_;
    173   scoped_refptr<base::SequencedTaskRunner> task_runner_;
    174 };
    175 
    176 // Both 'bsdiff' and 'courgette' operations take an existing file on disk,
    177 // and a bsdiff- or Courgette-format patch file provided in the delta update
    178 // package, and run bsdiff or Courgette to construct an output file in the
    179 // unpacking directory.
    180 class DeltaUpdateOpPatch : public DeltaUpdateOp {
    181  public:
    182   explicit DeltaUpdateOpPatch(scoped_ptr<DeltaUpdateOpPatchStrategy> strategy);
    183 
    184   void DonePatching(ComponentUnpacker::Error error, int error_code);
    185 
    186  private:
    187   virtual ~DeltaUpdateOpPatch();
    188 
    189   // Overrides of DeltaUpdateOp.
    190   virtual ComponentUnpacker::Error DoParseArguments(
    191       const base::DictionaryValue* command_args,
    192       const base::FilePath& input_dir,
    193       ComponentInstaller* installer) OVERRIDE;
    194 
    195   virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE;
    196 
    197   ComponentUnpacker::Callback callback_;
    198   base::FilePath patch_abs_path_;
    199   base::FilePath input_abs_path_;
    200   scoped_ptr<DeltaUpdateOpPatchStrategy> strategy_;
    201   scoped_refptr<DeltaUpdateOpPatchHost> host_;
    202 
    203   DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpPatch);
    204 };
    205 
    206 // Factory functions to create DeltaUpdateOp instances.
    207 DeltaUpdateOp* CreateDeltaUpdateOp(const base::DictionaryValue& command);
    208 
    209 DeltaUpdateOp* CreateDeltaUpdateOp(const std::string& operation);
    210 
    211 }  // namespace component_updater
    212 
    213 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_
    214