// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_ #define CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_ #include #include "base/basictypes.h" #include "base/callback.h" #include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "chrome/browser/component_updater/component_patcher.h" #include "chrome/browser/component_updater/component_unpacker.h" #include "content/public/browser/utility_process_host_client.h" namespace base { class DictionaryValue; } // namespace base namespace component_updater { class ComponentInstaller; class DeltaUpdateOp : public base::RefCountedThreadSafe { public: DeltaUpdateOp(); // Parses, runs, and verifies the operation. Calls |callback| with the // result of the operation. The callback is called using |task_runner|. void Run(const base::DictionaryValue* command_args, const base::FilePath& input_dir, const base::FilePath& unpack_dir, ComponentInstaller* installer, bool in_process, const ComponentUnpacker::Callback& callback, scoped_refptr task_runner); protected: virtual ~DeltaUpdateOp(); bool InProcess(); scoped_refptr GetTaskRunner(); std::string output_sha256_; base::FilePath output_abs_path_; private: friend class base::RefCountedThreadSafe; ComponentUnpacker::Error CheckHash(); // Subclasses must override DoParseArguments to parse operation-specific // arguments. DoParseArguments returns DELTA_OK on success; any other code // represents failure. virtual ComponentUnpacker::Error DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, ComponentInstaller* installer) = 0; // Subclasses must override DoRun to actually perform the patching operation. // They must call the provided callback when they have completed their // operations. In practice, the provided callback is always for "DoneRunning". virtual void DoRun(const ComponentUnpacker::Callback& callback) = 0; // Callback given to subclasses for when they complete their operation. // Validates the output, and posts a task to the patching operation's // callback. void DoneRunning(ComponentUnpacker::Error error, int extended_error); bool in_process_; ComponentUnpacker::Callback callback_; scoped_refptr task_runner_; DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOp); }; // A 'copy' operation takes a file currently residing on the disk and moves it // into the unpacking directory: this represents "no change" in the file being // installed. class DeltaUpdateOpCopy : public DeltaUpdateOp { public: DeltaUpdateOpCopy(); private: virtual ~DeltaUpdateOpCopy(); // Overrides of DeltaUpdateOp. virtual ComponentUnpacker::Error DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, ComponentInstaller* installer) OVERRIDE; virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE; base::FilePath input_abs_path_; DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpCopy); }; // A 'create' operation takes a full file that was sent in the delta update // archive and moves it into the unpacking directory: this represents the // addition of a new file, or a file so different that no bandwidth could be // saved by transmitting a differential update. class DeltaUpdateOpCreate : public DeltaUpdateOp { public: DeltaUpdateOpCreate(); private: virtual ~DeltaUpdateOpCreate(); // Overrides of DeltaUpdateOp. virtual ComponentUnpacker::Error DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, ComponentInstaller* installer) OVERRIDE; virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE; base::FilePath patch_abs_path_; DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpCreate); }; class DeltaUpdateOpPatchStrategy { public: virtual ~DeltaUpdateOpPatchStrategy(); // Returns an integer to add to error codes to disambiguate their source. virtual int GetErrorOffset() const = 0; // Returns the "error code" that is expected in the successful install case. virtual int GetSuccessCode() const = 0; // Returns an IPC message that will start patching if it is sent to a // UtilityProcessClient. virtual scoped_ptr GetPatchMessage( base::FilePath input_abs_path, base::FilePath patch_abs_path, base::FilePath output_abs_path) = 0; // Does the actual patching operation, and returns an error code. virtual int Patch(base::FilePath input_abs_path, base::FilePath patch_abs_path, base::FilePath output_abs_path) = 0; }; class DeltaUpdateOpPatch; class DeltaUpdateOpPatchHost : public content::UtilityProcessHostClient { public: DeltaUpdateOpPatchHost(scoped_refptr patcher, scoped_refptr task_runner); void StartProcess(scoped_ptr message); private: virtual ~DeltaUpdateOpPatchHost(); void OnPatchSucceeded(); void OnPatchFailed(int error_code); // Overrides of content::UtilityProcessHostClient. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual void OnProcessCrashed(int exit_code) OVERRIDE; scoped_refptr patcher_; scoped_refptr task_runner_; }; // Both 'bsdiff' and 'courgette' operations take an existing file on disk, // and a bsdiff- or Courgette-format patch file provided in the delta update // package, and run bsdiff or Courgette to construct an output file in the // unpacking directory. class DeltaUpdateOpPatch : public DeltaUpdateOp { public: explicit DeltaUpdateOpPatch(scoped_ptr strategy); void DonePatching(ComponentUnpacker::Error error, int error_code); private: virtual ~DeltaUpdateOpPatch(); // Overrides of DeltaUpdateOp. virtual ComponentUnpacker::Error DoParseArguments( const base::DictionaryValue* command_args, const base::FilePath& input_dir, ComponentInstaller* installer) OVERRIDE; virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE; ComponentUnpacker::Callback callback_; base::FilePath patch_abs_path_; base::FilePath input_abs_path_; scoped_ptr strategy_; scoped_refptr host_; DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpPatch); }; // Factory functions to create DeltaUpdateOp instances. DeltaUpdateOp* CreateDeltaUpdateOp(const base::DictionaryValue& command); DeltaUpdateOp* CreateDeltaUpdateOp(const std::string& operation); } // namespace component_updater #endif // CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_