103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#ifndef COMPONENTS_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_ 603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define COMPONENTS_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_ 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string> 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/callback.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/compiler_specific.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file_path.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/macros.h" 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/memory/ref_counted.h" 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_unpacker.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace base { 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass DictionaryValue; 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace base 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace component_updater { 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern const char kOp[]; 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern const char kBsdiff[]; 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern const char kCourgette[]; 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern const char kInput[]; 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern const char kPatch[]; 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ComponentInstaller; 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass DeltaUpdateOp : public base::RefCountedThreadSafe<DeltaUpdateOp> { 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeltaUpdateOp(); 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Parses, runs, and verifies the operation. Calls |callback| with the 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // result of the operation. The callback is called using |task_runner|. 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void Run(const base::DictionaryValue* command_args, 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::FilePath& input_dir, 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::FilePath& unpack_dir, 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ComponentInstaller* installer, 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const ComponentUnpacker::Callback& callback, 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<base::SequencedTaskRunner> task_runner); 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected: 45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual ~DeltaUpdateOp(); 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch scoped_refptr<base::SequencedTaskRunner> GetTaskRunner(); 48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string output_sha256_; 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath output_abs_path_; 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch friend class base::RefCountedThreadSafe<DeltaUpdateOp>; 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentUnpacker::Error CheckHash(); 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Subclasses must override DoParseArguments to parse operation-specific 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // arguments. DoParseArguments returns DELTA_OK on success; any other code 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // represents failure. 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ComponentUnpacker::Error DoParseArguments( 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* command_args, 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::FilePath& input_dir, 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentInstaller* installer) = 0; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Subclasses must override DoRun to actually perform the patching operation. 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // They must call the provided callback when they have completed their 67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // operations. In practice, the provided callback is always for "DoneRunning". 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual void DoRun(const ComponentUnpacker::Callback& callback) = 0; 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Callback given to subclasses for when they complete their operation. 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Validates the output, and posts a task to the patching operation's 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // callback. 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void DoneRunning(ComponentUnpacker::Error error, int extended_error); 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ComponentUnpacker::Callback callback_; 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<base::SequencedTaskRunner> task_runner_; 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOp); 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A 'copy' operation takes a file currently residing on the disk and moves it 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// into the unpacking directory: this represents "no change" in the file being 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// installed. 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass DeltaUpdateOpCopy : public DeltaUpdateOp { 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeltaUpdateOpCopy(); 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual ~DeltaUpdateOpCopy(); 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Overrides of DeltaUpdateOp. 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ComponentUnpacker::Error DoParseArguments( 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* command_args, 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::FilePath& input_dir, 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentInstaller* installer) OVERRIDE; 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE; 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath input_abs_path_; 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpCopy); 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A 'create' operation takes a full file that was sent in the delta update 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// archive and moves it into the unpacking directory: this represents the 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// addition of a new file, or a file so different that no bandwidth could be 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// saved by transmitting a differential update. 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass DeltaUpdateOpCreate : public DeltaUpdateOp { 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DeltaUpdateOpCreate(); 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual ~DeltaUpdateOpCreate(); 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Overrides of DeltaUpdateOp. 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ComponentUnpacker::Error DoParseArguments( 117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* command_args, 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::FilePath& input_dir, 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentInstaller* installer) OVERRIDE; 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE; 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath patch_abs_path_; 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpCreate); 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// An interface an embedder may fulfill to enable out-of-process patching. 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class OutOfProcessPatcher 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : public base::RefCountedThreadSafe<OutOfProcessPatcher> { 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public: 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void Patch(const std::string& operation, 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner, 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::FilePath& input_abs_path, 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::FilePath& patch_abs_path, 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::FilePath& output_abs_path, 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Callback<void(int result)> callback) = 0; 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected: 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) friend class base::RefCountedThreadSafe<OutOfProcessPatcher>; 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual ~OutOfProcessPatcher() {} 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Both 'bsdiff' and 'courgette' operations take an existing file on disk, 146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// and a bsdiff- or Courgette-format patch file provided in the delta update 147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// package, and run bsdiff or Courgette to construct an output file in the 148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// unpacking directory. 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass DeltaUpdateOpPatch : public DeltaUpdateOp { 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |out_of_process_patcher| may be NULL. 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DeltaUpdateOpPatch(const std::string& operation, 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<OutOfProcessPatcher> out_of_process_patcher); 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual ~DeltaUpdateOpPatch(); 157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Overrides of DeltaUpdateOp. 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ComponentUnpacker::Error DoParseArguments( 160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* command_args, 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::FilePath& input_dir, 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentInstaller* installer) OVERRIDE; 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual void DoRun(const ComponentUnpacker::Callback& callback) OVERRIDE; 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |success_code| is the code that indicates a successful patch. 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |result| is the code the patching operation returned. 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void DonePatching(const ComponentUnpacker::Callback& callback, int result); 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string operation_; 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<OutOfProcessPatcher> out_of_process_patcher_; 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath patch_abs_path_; 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath input_abs_path_; 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpPatch); 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DeltaUpdateOp* CreateDeltaUpdateOp( 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& operation, 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<OutOfProcessPatcher> out_of_process_patcher); 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace component_updater 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif // COMPONENTS_COMPONENT_UPDATER_COMPONENT_PATCHER_OPERATION_H_ 185