Index: chrome/browser/component_updater/component_patcher_operation.cc |
diff --git a/chrome/browser/component_updater/component_patcher_operation.cc b/chrome/browser/component_updater/component_patcher_operation.cc |
index 137d57392a2de0f5cce08e8b76176c35bc669f9f..5fd098663a16a8c86fd6ecb2fd82da707474f78e 100644 |
--- a/chrome/browser/component_updater/component_patcher_operation.cc |
+++ b/chrome/browser/component_updater/component_patcher_operation.cc |
@@ -4,27 +4,21 @@ |
#include "chrome/browser/component_updater/component_patcher_operation.h" |
-#include <string> |
#include <vector> |
#include "base/bind.h" |
#include "base/file_util.h" |
#include "base/files/memory_mapped_file.h" |
-#include "base/json/json_file_value_serializer.h" |
-#include "base/path_service.h" |
+#include "base/location.h" |
#include "base/strings/string_number_conversions.h" |
#include "chrome/browser/component_updater/component_patcher.h" |
#include "chrome/browser/component_updater/component_updater_service.h" |
-#include "chrome/common/chrome_utility_messages.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/utility_process_host.h" |
#include "courgette/courgette.h" |
#include "courgette/third_party/bsdiff.h" |
#include "crypto/secure_hash.h" |
#include "crypto/sha2.h" |
#include "crypto/signature_verifier.h" |
#include "extensions/common/crx_file.h" |
-#include "ipc/ipc_message_macros.h" |
using crypto::SecureHash; |
@@ -32,122 +26,35 @@ namespace component_updater { |
namespace { |
-const char kInput[] = "input"; |
-const char kOp[] = "op"; |
const char kOutput[] = "output"; |
-const char kPatch[] = "patch"; |
const char kSha256[] = "sha256"; |
// The integer offset disambiguates between overlapping error ranges. |
const int kCourgetteErrorOffset = 300; |
const int kBsdiffErrorOffset = 600; |
-class CourgetteTraits : public DeltaUpdateOpPatchStrategy { |
- public: |
- virtual int GetErrorOffset() const OVERRIDE; |
- virtual int GetSuccessCode() const OVERRIDE; |
- virtual scoped_ptr<IPC::Message> GetPatchMessage( |
- base::FilePath input_abs_path, |
- base::FilePath patch_abs_path, |
- base::FilePath output_abs_path) OVERRIDE; |
- virtual int Patch(base::FilePath input_abs_path, |
- base::FilePath patch_abs_path, |
- base::FilePath output_abs_path) OVERRIDE; |
-}; |
- |
-int CourgetteTraits::GetErrorOffset() const { |
- return kCourgetteErrorOffset; |
-} |
- |
-int CourgetteTraits::GetSuccessCode() const { |
- return courgette::C_OK; |
-} |
- |
-scoped_ptr<IPC::Message> CourgetteTraits::GetPatchMessage( |
- base::FilePath input_abs_path, |
- base::FilePath patch_abs_path, |
- base::FilePath output_abs_path) { |
- return scoped_ptr<IPC::Message>( |
- new ChromeUtilityMsg_PatchFileCourgette(input_abs_path, |
- patch_abs_path, |
- output_abs_path)); |
-} |
- |
-int CourgetteTraits::Patch(base::FilePath input_abs_path, |
- base::FilePath patch_abs_path, |
- base::FilePath output_abs_path) { |
- return courgette::ApplyEnsemblePatch(input_abs_path.value().c_str(), |
- patch_abs_path.value().c_str(), |
- output_abs_path.value().c_str()); |
-} |
- |
-class BsdiffTraits : public DeltaUpdateOpPatchStrategy { |
- public: |
- virtual int GetErrorOffset() const OVERRIDE; |
- virtual int GetSuccessCode() const OVERRIDE; |
- virtual scoped_ptr<IPC::Message> GetPatchMessage( |
- base::FilePath input_abs_path, |
- base::FilePath patch_abs_path, |
- base::FilePath output_abs_path) OVERRIDE; |
- virtual int Patch(base::FilePath input_abs_path, |
- base::FilePath patch_abs_path, |
- base::FilePath output_abs_path) OVERRIDE; |
-}; |
- |
-int BsdiffTraits::GetErrorOffset() const { |
- return kBsdiffErrorOffset; |
-} |
- |
-int BsdiffTraits::GetSuccessCode() const { |
- return courgette::OK; |
-} |
- |
-scoped_ptr<IPC::Message> BsdiffTraits::GetPatchMessage( |
- base::FilePath input_abs_path, |
- base::FilePath patch_abs_path, |
- base::FilePath output_abs_path) { |
- return scoped_ptr<IPC::Message>( |
- new ChromeUtilityMsg_PatchFileBsdiff(input_abs_path, |
- patch_abs_path, |
- output_abs_path)); |
-} |
- |
-int BsdiffTraits::Patch(base::FilePath input_abs_path, |
- base::FilePath patch_abs_path, |
- base::FilePath output_abs_path) { |
- return courgette::ApplyBinaryPatch(input_abs_path, |
- patch_abs_path, |
- output_abs_path); |
-} |
- |
} // namespace |
-DeltaUpdateOpPatchStrategy::~DeltaUpdateOpPatchStrategy() { |
-} |
+const char kOp[] = "op"; |
+const char kBsdiff[] = "bsdiff"; |
+const char kCourgette[] = "courgette"; |
+const char kInput[] = "input"; |
+const char kPatch[] = "patch"; |
-DeltaUpdateOp* CreateDeltaUpdateOp(const std::string& operation) { |
+DeltaUpdateOp* CreateDeltaUpdateOp( |
+ const std::string& operation, |
+ scoped_refptr<OutOfProcessPatcher> out_of_process_patcher) { |
if (operation == "copy") { |
return new DeltaUpdateOpCopy(); |
} else if (operation == "create") { |
return new DeltaUpdateOpCreate(); |
- } else if (operation == "bsdiff") { |
- scoped_ptr<DeltaUpdateOpPatchStrategy> strategy(new BsdiffTraits()); |
- return new DeltaUpdateOpPatch(strategy.Pass()); |
- } else if (operation == "courgette") { |
- scoped_ptr<DeltaUpdateOpPatchStrategy> strategy(new CourgetteTraits()); |
- return new DeltaUpdateOpPatch(strategy.Pass()); |
+ } else if (operation == "bsdiff" || operation == "courgette") { |
+ return new DeltaUpdateOpPatch(operation, out_of_process_patcher); |
} |
return NULL; |
} |
-DeltaUpdateOp* CreateDeltaUpdateOp(const base::DictionaryValue& command) { |
- std::string operation; |
- if (!command.GetString(kOp, &operation)) |
- return NULL; |
- return CreateDeltaUpdateOp(operation); |
-} |
- |
-DeltaUpdateOp::DeltaUpdateOp() : in_process_(false) { |
+DeltaUpdateOp::DeltaUpdateOp() { |
} |
DeltaUpdateOp::~DeltaUpdateOp() { |
@@ -157,11 +64,9 @@ void DeltaUpdateOp::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<base::SequencedTaskRunner> task_runner) { |
callback_ = callback; |
- in_process_ = in_process; |
task_runner_ = task_runner; |
std::string output_rel_path; |
if (!command_args->GetString(kOutput, &output_rel_path) || |
@@ -222,10 +127,6 @@ ComponentUnpacker::Error DeltaUpdateOp::CheckHash() { |
return ComponentUnpacker::kNone; |
} |
-bool DeltaUpdateOp::InProcess() { |
- return in_process_; |
-} |
- |
scoped_refptr<base::SequencedTaskRunner> DeltaUpdateOp::GetTaskRunner() { |
return task_runner_; |
} |
@@ -284,70 +185,11 @@ void DeltaUpdateOpCreate::DoRun(const ComponentUnpacker::Callback& callback) { |
callback.Run(ComponentUnpacker::kNone, 0); |
} |
-DeltaUpdateOpPatchHost::DeltaUpdateOpPatchHost( |
- scoped_refptr<DeltaUpdateOpPatch> patcher, |
- scoped_refptr<base::SequencedTaskRunner> task_runner) |
- : patcher_(patcher), task_runner_(task_runner) { |
-} |
- |
-DeltaUpdateOpPatchHost::~DeltaUpdateOpPatchHost() { |
-} |
- |
-void DeltaUpdateOpPatchHost::StartProcess(scoped_ptr<IPC::Message> message) { |
- // The DeltaUpdateOpPatchHost is not responsible for deleting the |
- // UtilityProcessHost object. |
- content::UtilityProcessHost* host = content::UtilityProcessHost::Create( |
- this, base::MessageLoopProxy::current().get()); |
- host->DisableSandbox(); |
- host->Send(message.release()); |
-} |
- |
-bool DeltaUpdateOpPatchHost::OnMessageReceived(const IPC::Message& message) { |
- bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP(DeltaUpdateOpPatchHost, message) |
- IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PatchFile_Succeeded, |
- OnPatchSucceeded) |
- IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PatchFile_Failed, |
- OnPatchFailed) |
- IPC_MESSAGE_UNHANDLED(handled = false) |
- IPC_END_MESSAGE_MAP() |
- return handled; |
-} |
- |
-void DeltaUpdateOpPatchHost::OnPatchSucceeded() { |
- task_runner_->PostTask(FROM_HERE, |
- base::Bind(&DeltaUpdateOpPatch::DonePatching, |
- patcher_, |
- ComponentUnpacker::kNone, |
- 0)); |
- task_runner_ = NULL; |
- patcher_ = NULL; |
-} |
- |
-void DeltaUpdateOpPatchHost::OnPatchFailed(int error_code) { |
- task_runner_->PostTask(FROM_HERE, |
- base::Bind(&DeltaUpdateOpPatch::DonePatching, |
- patcher_, |
- ComponentUnpacker::kDeltaOperationFailure, |
- error_code)); |
- task_runner_ = NULL; |
- patcher_ = NULL; |
-} |
- |
-void DeltaUpdateOpPatchHost::OnProcessCrashed(int exit_code) { |
- task_runner_->PostTask( |
- FROM_HERE, |
- base::Bind(&DeltaUpdateOpPatch::DonePatching, |
- patcher_, |
- ComponentUnpacker::kDeltaPatchProcessFailure, |
- exit_code)); |
- task_runner_ = NULL; |
- patcher_ = NULL; |
-} |
- |
DeltaUpdateOpPatch::DeltaUpdateOpPatch( |
- scoped_ptr<DeltaUpdateOpPatchStrategy> strategy) { |
- strategy_ = strategy.Pass(); |
+ const std::string& operation, |
+ scoped_refptr<OutOfProcessPatcher> out_of_process_patcher) |
+ : operation_(operation), out_of_process_patcher_(out_of_process_patcher) { |
+ DCHECK(operation == kBsdiff || operation == kCourgette); |
} |
DeltaUpdateOpPatch::~DeltaUpdateOpPatch() { |
@@ -373,39 +215,52 @@ ComponentUnpacker::Error DeltaUpdateOpPatch::DoParseArguments( |
} |
void DeltaUpdateOpPatch::DoRun(const ComponentUnpacker::Callback& callback) { |
- callback_ = callback; |
- if (!InProcess()) { |
- host_ = new DeltaUpdateOpPatchHost(scoped_refptr<DeltaUpdateOpPatch>(this), |
- GetTaskRunner()); |
- content::BrowserThread::PostTask( |
- content::BrowserThread::IO, |
- FROM_HERE, |
- base::Bind(&DeltaUpdateOpPatchHost::StartProcess, |
- host_, |
- base::Passed(strategy_->GetPatchMessage(input_abs_path_, |
- patch_abs_path_, |
- output_abs_path_)))); |
+ if (out_of_process_patcher_.get()) { |
+ out_of_process_patcher_->Patch( |
+ operation_, |
+ GetTaskRunner(), |
+ input_abs_path_, |
+ patch_abs_path_, |
+ output_abs_path_, |
+ base::Bind(&DeltaUpdateOpPatch::DonePatching, this, callback)); |
return; |
} |
- const int result = strategy_->Patch(input_abs_path_, |
- patch_abs_path_, |
- output_abs_path_); |
- if (result == strategy_->GetSuccessCode()) |
- DonePatching(ComponentUnpacker::kNone, 0); |
- else |
- DonePatching(ComponentUnpacker::kDeltaOperationFailure, result); |
+ |
+ if (operation_ == kBsdiff) { |
+ DonePatching(callback, |
+ courgette::ApplyBinaryPatch( |
+ input_abs_path_, patch_abs_path_, output_abs_path_)); |
+ } else if (operation_ == kCourgette) { |
+ DonePatching( |
+ callback, |
+ courgette::ApplyEnsemblePatch(input_abs_path_.value().c_str(), |
+ patch_abs_path_.value().c_str(), |
+ output_abs_path_.value().c_str())); |
+ } else { |
+ NOTREACHED(); |
+ } |
} |
-void DeltaUpdateOpPatch::DonePatching(ComponentUnpacker::Error error, |
- int error_code) { |
- host_ = NULL; |
- if (error != ComponentUnpacker::kNone) { |
- error_code += strategy_->GetErrorOffset(); |
+void DeltaUpdateOpPatch::DonePatching( |
+ const ComponentUnpacker::Callback& callback, |
+ int result) { |
+ if (operation_ == kBsdiff) { |
+ if (result == courgette::OK) { |
+ callback.Run(ComponentUnpacker::kNone, 0); |
+ } else { |
+ callback.Run(ComponentUnpacker::kDeltaOperationFailure, |
+ result + kBsdiffErrorOffset); |
+ } |
+ } else if (operation_ == kCourgette) { |
+ if (result == courgette::C_OK) { |
+ callback.Run(ComponentUnpacker::kNone, 0); |
+ } else { |
+ callback.Run(ComponentUnpacker::kDeltaOperationFailure, |
+ result + kCourgetteErrorOffset); |
+ } |
+ } else { |
+ NOTREACHED(); |
} |
- callback_.Run(error, error_code); |
- // The callback is no longer needed - it is best to release it in case it |
- // contains a reference to this object. |
- callback_.Reset(); |
} |
} // namespace component_updater |