OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/component_updater/component_patcher_operation.h" | 5 #include "chrome/browser/component_updater/component_patcher_operation.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
| 10 #include "base/bind.h" |
10 #include "base/file_util.h" | 11 #include "base/file_util.h" |
11 #include "base/files/memory_mapped_file.h" | 12 #include "base/files/memory_mapped_file.h" |
12 #include "base/json/json_file_value_serializer.h" | 13 #include "base/json/json_file_value_serializer.h" |
13 #include "base/memory/scoped_handle.h" | 14 #include "base/memory/scoped_handle.h" |
14 #include "base/path_service.h" | 15 #include "base/path_service.h" |
15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
16 #include "chrome/browser/component_updater/component_patcher.h" | 17 #include "chrome/browser/component_updater/component_patcher.h" |
17 #include "chrome/browser/component_updater/component_updater_service.h" | 18 #include "chrome/browser/component_updater/component_updater_service.h" |
| 19 #include "chrome/common/chrome_utility_messages.h" |
18 #include "chrome/common/extensions/extension_constants.h" | 20 #include "chrome/common/extensions/extension_constants.h" |
| 21 #include "content/public/browser/browser_thread.h" |
| 22 #include "content/public/browser/utility_process_host.h" |
| 23 #include "courgette/courgette.h" |
| 24 #include "courgette/third_party/bsdiff.h" |
19 #include "crypto/secure_hash.h" | 25 #include "crypto/secure_hash.h" |
20 #include "crypto/sha2.h" | 26 #include "crypto/sha2.h" |
21 #include "crypto/signature_verifier.h" | 27 #include "crypto/signature_verifier.h" |
22 #include "extensions/common/crx_file.h" | 28 #include "extensions/common/crx_file.h" |
| 29 #include "ipc/ipc_message_macros.h" |
23 #include "third_party/zlib/google/zip.h" | 30 #include "third_party/zlib/google/zip.h" |
24 | 31 |
25 using crypto::SecureHash; | 32 using crypto::SecureHash; |
26 | 33 |
27 namespace component_updater { | 34 namespace component_updater { |
28 | 35 |
29 namespace { | 36 namespace { |
30 | 37 |
31 const char kInput[] = "input"; | 38 const char kInput[] = "input"; |
32 const char kOp[] = "op"; | 39 const char kOp[] = "op"; |
33 const char kOutput[] = "output"; | 40 const char kOutput[] = "output"; |
34 const char kPatch[] = "patch"; | 41 const char kPatch[] = "patch"; |
35 const char kSha256[] = "sha256"; | 42 const char kSha256[] = "sha256"; |
36 | 43 |
| 44 // The integer offset disambiguates between overlapping error ranges. |
| 45 const int kCourgetteErrorOffset = 300; |
| 46 const int kBsdiffErrorOffset = 600; |
| 47 |
| 48 class CourgetteTraits : public DeltaUpdateOpPatchTraits { |
| 49 public: |
| 50 virtual int GetErrorOffset() OVERRIDE; |
| 51 virtual int GetSuccessCode() OVERRIDE; |
| 52 virtual IPC::Message* GetPatchMessage( |
| 53 base::FilePath input_abs_path, |
| 54 base::FilePath patch_abs_path, |
| 55 base::FilePath output_abs_path) OVERRIDE; |
| 56 virtual int Patch(base::FilePath input_abs_path, |
| 57 base::FilePath patch_abs_path, |
| 58 base::FilePath output_abs_path) OVERRIDE; |
| 59 }; |
| 60 |
| 61 int CourgetteTraits::GetErrorOffset() { |
| 62 return kCourgetteErrorOffset; |
| 63 } |
| 64 |
| 65 int CourgetteTraits::GetSuccessCode() { |
| 66 return courgette::C_OK; |
| 67 } |
| 68 |
| 69 IPC::Message* CourgetteTraits::GetPatchMessage(base::FilePath input_abs_path, |
| 70 base::FilePath patch_abs_path, |
| 71 base::FilePath output_abs_path) { |
| 72 return new ChromeUtilityMsg_PatchFileCourgette(input_abs_path, |
| 73 patch_abs_path, |
| 74 output_abs_path); |
| 75 } |
| 76 |
| 77 int CourgetteTraits::Patch(base::FilePath input_abs_path, |
| 78 base::FilePath patch_abs_path, |
| 79 base::FilePath output_abs_path) { |
| 80 return courgette::ApplyEnsemblePatch(input_abs_path.value().c_str(), |
| 81 patch_abs_path.value().c_str(), |
| 82 output_abs_path.value().c_str()); |
| 83 } |
| 84 |
| 85 class BsdiffTraits : public DeltaUpdateOpPatchTraits { |
| 86 public: |
| 87 virtual int GetErrorOffset() OVERRIDE; |
| 88 virtual int GetSuccessCode() OVERRIDE; |
| 89 virtual IPC::Message* GetPatchMessage( |
| 90 base::FilePath input_abs_path, |
| 91 base::FilePath patch_abs_path, |
| 92 base::FilePath output_abs_path) OVERRIDE; |
| 93 virtual int Patch(base::FilePath input_abs_path, |
| 94 base::FilePath patch_abs_path, |
| 95 base::FilePath output_abs_path) OVERRIDE; |
| 96 }; |
| 97 |
| 98 int BsdiffTraits::GetErrorOffset() { |
| 99 return kBsdiffErrorOffset; |
| 100 } |
| 101 |
| 102 int BsdiffTraits::GetSuccessCode() { |
| 103 return courgette::OK; |
| 104 } |
| 105 |
| 106 IPC::Message* BsdiffTraits::GetPatchMessage(base::FilePath input_abs_path, |
| 107 base::FilePath patch_abs_path, |
| 108 base::FilePath output_abs_path) { |
| 109 return new ChromeUtilityMsg_PatchFileBsdiff(input_abs_path, |
| 110 patch_abs_path, |
| 111 output_abs_path); |
| 112 } |
| 113 |
| 114 int BsdiffTraits::Patch(base::FilePath input_abs_path, |
| 115 base::FilePath patch_abs_path, |
| 116 base::FilePath output_abs_path) { |
| 117 return courgette::ApplyBinaryPatch(input_abs_path, |
| 118 patch_abs_path, |
| 119 output_abs_path); |
| 120 } |
| 121 |
37 } // namespace | 122 } // namespace |
38 | 123 |
39 DeltaUpdateOp* CreateDeltaUpdateOp(base::DictionaryValue* command) { | 124 DeltaUpdateOpPatchTraits::~DeltaUpdateOpPatchTraits() { |
40 std::string operation; | 125 } |
41 if (!command->GetString(kOp, &operation)) | 126 |
42 return NULL; | 127 DeltaUpdateOp* CreateDeltaUpdateOp(const std::string& operation) { |
43 if (operation == "copy") | 128 if (operation == "copy") { |
44 return new DeltaUpdateOpCopy(); | 129 return new DeltaUpdateOpCopy(); |
45 else if (operation == "create") | 130 } else if (operation == "create") { |
46 return new DeltaUpdateOpCreate(); | 131 return new DeltaUpdateOpCreate(); |
47 else if (operation == "bsdiff") | 132 } else if (operation == "bsdiff") { |
48 return new DeltaUpdateOpPatchBsdiff(); | 133 scoped_ptr<DeltaUpdateOpPatchTraits> traits(new BsdiffTraits()); |
49 else if (operation == "courgette") | 134 return new DeltaUpdateOpPatch(traits.Pass()); |
50 return new DeltaUpdateOpPatchCourgette(); | 135 } else if (operation == "courgette") { |
| 136 scoped_ptr<DeltaUpdateOpPatchTraits> traits(new CourgetteTraits()); |
| 137 return new DeltaUpdateOpPatch(traits.Pass()); |
| 138 } |
51 return NULL; | 139 return NULL; |
52 } | 140 } |
53 | 141 |
54 DeltaUpdateOp::DeltaUpdateOp() {} | 142 DeltaUpdateOp* CreateDeltaUpdateOp(const base::DictionaryValue& command) { |
| 143 std::string operation; |
| 144 if (!command.GetString(kOp, &operation)) |
| 145 return NULL; |
| 146 return CreateDeltaUpdateOp(operation); |
| 147 } |
| 148 |
| 149 DeltaUpdateOp::DeltaUpdateOp() : in_process_(false) {} |
55 | 150 |
56 DeltaUpdateOp::~DeltaUpdateOp() {} | 151 DeltaUpdateOp::~DeltaUpdateOp() {} |
57 | 152 |
58 ComponentUnpacker::Error DeltaUpdateOp::Run(base::DictionaryValue* command_args, | 153 void DeltaUpdateOp::Run( |
59 const base::FilePath& input_dir, | 154 base::DictionaryValue* command_args, |
60 const base::FilePath& unpack_dir, | 155 const base::FilePath& input_dir, |
61 ComponentPatcher* patcher, | 156 const base::FilePath& unpack_dir, |
62 ComponentInstaller* installer, | 157 ComponentInstaller* installer, |
63 int* error) { | 158 bool in_process, |
| 159 const Callback& callback, |
| 160 scoped_refptr<base::SequencedTaskRunner> task_runner) { |
| 161 callback_ = callback; |
| 162 in_process_ = in_process; |
| 163 task_runner_ = task_runner; |
64 std::string output_rel_path; | 164 std::string output_rel_path; |
65 if (!command_args->GetString(kOutput, &output_rel_path) || | 165 if (!command_args->GetString(kOutput, &output_rel_path) || |
66 !command_args->GetString(kSha256, &output_sha256_)) | 166 !command_args->GetString(kSha256, &output_sha256_)) { |
67 return ComponentUnpacker::kDeltaBadCommands; | 167 DoneRunning(ComponentUnpacker::kDeltaBadCommands, 0); |
| 168 return; |
| 169 } |
68 | 170 |
69 output_abs_path_ = unpack_dir.Append( | 171 output_abs_path_ = unpack_dir.Append( |
70 base::FilePath::FromUTF8Unsafe(output_rel_path)); | 172 base::FilePath::FromUTF8Unsafe(output_rel_path)); |
71 ComponentUnpacker::Error parse_result = DoParseArguments( | 173 ComponentUnpacker::Error parse_result = DoParseArguments( |
72 command_args, input_dir, installer); | 174 command_args, input_dir, installer); |
73 if (parse_result != ComponentUnpacker::kNone) | 175 if (parse_result != ComponentUnpacker::kNone) { |
74 return parse_result; | 176 DoneRunning(parse_result, 0); |
| 177 return; |
| 178 } |
75 | 179 |
76 const base::FilePath parent = output_abs_path_.DirName(); | 180 const base::FilePath parent = output_abs_path_.DirName(); |
77 if (!base::DirectoryExists(parent)) { | 181 if (!base::DirectoryExists(parent)) { |
78 if (!base::CreateDirectory(parent)) | 182 if (!base::CreateDirectory(parent)) { |
79 return ComponentUnpacker::kIoError; | 183 DoneRunning(ComponentUnpacker::kIoError, 0); |
| 184 return; |
| 185 } |
80 } | 186 } |
81 | 187 |
82 ComponentUnpacker::Error run_result = DoRun(patcher, error); | 188 DoRun(base::Bind(&DeltaUpdateOp::DoneRunning, |
83 if (run_result != ComponentUnpacker::kNone) | 189 scoped_refptr<DeltaUpdateOp>(this))); |
84 return run_result; | 190 } |
85 | 191 |
86 return CheckHash(); | 192 void DeltaUpdateOp::DoneRunning(ComponentUnpacker::Error error, |
| 193 int extended_error) { |
| 194 if (error == ComponentUnpacker::kNone) |
| 195 error = CheckHash(); |
| 196 task_runner_->PostTask(FROM_HERE, |
| 197 base::Bind(callback_, error, extended_error)); |
87 } | 198 } |
88 | 199 |
89 // Uses the hash as a checksum to confirm that the file now residing in the | 200 // Uses the hash as a checksum to confirm that the file now residing in the |
90 // output directory probably has the contents it should. | 201 // output directory probably has the contents it should. |
91 ComponentUnpacker::Error DeltaUpdateOp::CheckHash() { | 202 ComponentUnpacker::Error DeltaUpdateOp::CheckHash() { |
92 std::vector<uint8> expected_hash; | 203 std::vector<uint8> expected_hash; |
93 if (!base::HexStringToBytes(output_sha256_, &expected_hash) || | 204 if (!base::HexStringToBytes(output_sha256_, &expected_hash) || |
94 expected_hash.size() != crypto::kSHA256Length) | 205 expected_hash.size() != crypto::kSHA256Length) |
95 return ComponentUnpacker::kDeltaVerificationFailure; | 206 return ComponentUnpacker::kDeltaVerificationFailure; |
96 | 207 |
97 base::MemoryMappedFile output_file_mmapped; | 208 base::MemoryMappedFile output_file_mmapped; |
98 if (!output_file_mmapped.Initialize(output_abs_path_)) | 209 if (!output_file_mmapped.Initialize(output_abs_path_)) |
99 return ComponentUnpacker::kDeltaVerificationFailure; | 210 return ComponentUnpacker::kDeltaVerificationFailure; |
100 | 211 |
101 uint8 actual_hash[crypto::kSHA256Length] = {0}; | 212 uint8 actual_hash[crypto::kSHA256Length] = {0}; |
102 const scoped_ptr<SecureHash> hasher(SecureHash::Create(SecureHash::SHA256)); | 213 const scoped_ptr<SecureHash> hasher(SecureHash::Create(SecureHash::SHA256)); |
103 hasher->Update(output_file_mmapped.data(), output_file_mmapped.length()); | 214 hasher->Update(output_file_mmapped.data(), output_file_mmapped.length()); |
104 hasher->Finish(actual_hash, sizeof(actual_hash)); | 215 hasher->Finish(actual_hash, sizeof(actual_hash)); |
105 if (memcmp(actual_hash, &expected_hash[0], sizeof(actual_hash))) | 216 if (memcmp(actual_hash, &expected_hash[0], sizeof(actual_hash))) |
106 return ComponentUnpacker::kDeltaVerificationFailure; | 217 return ComponentUnpacker::kDeltaVerificationFailure; |
107 | 218 |
108 return ComponentUnpacker::kNone; | 219 return ComponentUnpacker::kNone; |
109 } | 220 } |
110 | 221 |
| 222 bool DeltaUpdateOp::InProcess() { |
| 223 return in_process_; |
| 224 } |
| 225 |
111 DeltaUpdateOpCopy::DeltaUpdateOpCopy() {} | 226 DeltaUpdateOpCopy::DeltaUpdateOpCopy() {} |
112 | 227 |
| 228 DeltaUpdateOpCopy::~DeltaUpdateOpCopy() {} |
| 229 |
113 ComponentUnpacker::Error DeltaUpdateOpCopy::DoParseArguments( | 230 ComponentUnpacker::Error DeltaUpdateOpCopy::DoParseArguments( |
114 base::DictionaryValue* command_args, | 231 base::DictionaryValue* command_args, |
115 const base::FilePath& input_dir, | 232 const base::FilePath& input_dir, |
116 ComponentInstaller* installer) { | 233 ComponentInstaller* installer) { |
117 std::string input_rel_path; | 234 std::string input_rel_path; |
118 if (!command_args->GetString(kInput, &input_rel_path)) | 235 if (!command_args->GetString(kInput, &input_rel_path)) |
119 return ComponentUnpacker::kDeltaBadCommands; | 236 return ComponentUnpacker::kDeltaBadCommands; |
120 | 237 |
121 if (!installer->GetInstalledFile(input_rel_path, &input_abs_path_)) | 238 if (!installer->GetInstalledFile(input_rel_path, &input_abs_path_)) |
122 return ComponentUnpacker::kDeltaMissingExistingFile; | 239 return ComponentUnpacker::kDeltaMissingExistingFile; |
123 | 240 |
124 return ComponentUnpacker::kNone; | 241 return ComponentUnpacker::kNone; |
125 } | 242 } |
126 | 243 |
127 ComponentUnpacker::Error DeltaUpdateOpCopy::DoRun(ComponentPatcher*, | 244 void DeltaUpdateOpCopy::DoRun(const Callback& callback) { |
128 int* error) { | |
129 *error = 0; | |
130 if (!base::CopyFile(input_abs_path_, output_abs_path_)) | 245 if (!base::CopyFile(input_abs_path_, output_abs_path_)) |
131 return ComponentUnpacker::kDeltaOperationFailure; | 246 callback.Run(ComponentUnpacker::kDeltaOperationFailure, 0); |
132 | 247 else |
133 return ComponentUnpacker::kNone; | 248 callback.Run(ComponentUnpacker::kNone, 0); |
134 } | 249 } |
135 | 250 |
136 DeltaUpdateOpCreate::DeltaUpdateOpCreate() {} | 251 DeltaUpdateOpCreate::DeltaUpdateOpCreate() {} |
137 | 252 |
| 253 DeltaUpdateOpCreate::~DeltaUpdateOpCreate() {} |
| 254 |
138 ComponentUnpacker::Error DeltaUpdateOpCreate::DoParseArguments( | 255 ComponentUnpacker::Error DeltaUpdateOpCreate::DoParseArguments( |
139 base::DictionaryValue* command_args, | 256 base::DictionaryValue* command_args, |
140 const base::FilePath& input_dir, | 257 const base::FilePath& input_dir, |
141 ComponentInstaller* installer) { | 258 ComponentInstaller* installer) { |
142 std::string patch_rel_path; | 259 std::string patch_rel_path; |
143 if (!command_args->GetString(kPatch, &patch_rel_path)) | 260 if (!command_args->GetString(kPatch, &patch_rel_path)) |
144 return ComponentUnpacker::kDeltaBadCommands; | 261 return ComponentUnpacker::kDeltaBadCommands; |
145 | 262 |
146 patch_abs_path_ = input_dir.Append( | 263 patch_abs_path_ = input_dir.Append( |
147 base::FilePath::FromUTF8Unsafe(patch_rel_path)); | 264 base::FilePath::FromUTF8Unsafe(patch_rel_path)); |
148 | 265 |
149 return ComponentUnpacker::kNone; | 266 return ComponentUnpacker::kNone; |
150 } | 267 } |
151 | 268 |
152 ComponentUnpacker::Error DeltaUpdateOpCreate::DoRun(ComponentPatcher*, | 269 void DeltaUpdateOpCreate::DoRun(const Callback& callback) { |
153 int* error) { | |
154 *error = 0; | |
155 if (!base::Move(patch_abs_path_, output_abs_path_)) | 270 if (!base::Move(patch_abs_path_, output_abs_path_)) |
156 return ComponentUnpacker::kDeltaOperationFailure; | 271 callback.Run(ComponentUnpacker::kDeltaOperationFailure, 0); |
157 | 272 else |
158 return ComponentUnpacker::kNone; | 273 callback.Run(ComponentUnpacker::kNone, 0); |
159 } | 274 } |
160 | 275 |
161 DeltaUpdateOpPatchBsdiff::DeltaUpdateOpPatchBsdiff() {} | |
162 | 276 |
163 ComponentUnpacker::Error DeltaUpdateOpPatchBsdiff::DoParseArguments( | 277 DeltaUpdateOpPatch::DeltaUpdateOpPatch( |
| 278 scoped_ptr<DeltaUpdateOpPatchTraits> traits) { |
| 279 traits_ = traits.Pass(); |
| 280 } |
| 281 |
| 282 DeltaUpdateOpPatch::~DeltaUpdateOpPatch() { |
| 283 } |
| 284 |
| 285 ComponentUnpacker::Error DeltaUpdateOpPatch::DoParseArguments( |
164 base::DictionaryValue* command_args, | 286 base::DictionaryValue* command_args, |
165 const base::FilePath& input_dir, | 287 const base::FilePath& input_dir, |
166 ComponentInstaller* installer) { | 288 ComponentInstaller* installer) { |
167 std::string patch_rel_path; | 289 std::string patch_rel_path; |
168 std::string input_rel_path; | 290 std::string input_rel_path; |
169 if (!command_args->GetString(kPatch, &patch_rel_path) || | 291 if (!command_args->GetString(kPatch, &patch_rel_path) || |
170 !command_args->GetString(kInput, &input_rel_path)) | 292 !command_args->GetString(kInput, &input_rel_path)) |
171 return ComponentUnpacker::kDeltaBadCommands; | 293 return ComponentUnpacker::kDeltaBadCommands; |
172 | 294 |
173 if (!installer->GetInstalledFile(input_rel_path, &input_abs_path_)) | 295 if (!installer->GetInstalledFile(input_rel_path, &input_abs_path_)) |
174 return ComponentUnpacker::kDeltaMissingExistingFile; | 296 return ComponentUnpacker::kDeltaMissingExistingFile; |
175 | 297 |
176 patch_abs_path_ = input_dir.Append( | 298 patch_abs_path_ = input_dir.Append( |
177 base::FilePath::FromUTF8Unsafe(patch_rel_path)); | 299 base::FilePath::FromUTF8Unsafe(patch_rel_path)); |
178 | 300 |
179 return ComponentUnpacker::kNone; | 301 return ComponentUnpacker::kNone; |
180 } | 302 } |
181 | 303 |
182 ComponentUnpacker::Error DeltaUpdateOpPatchBsdiff::DoRun( | 304 void DeltaUpdateOpPatch::DoRun(const Callback& callback) { |
183 ComponentPatcher* patcher, | 305 callback_ = callback; |
184 int* error) { | 306 if (!InProcess()) { |
185 *error = 0; | 307 content::BrowserThread::PostTask( |
186 return patcher->Patch(ComponentPatcher::kPatchTypeBsdiff, | 308 content::BrowserThread::IO, |
187 input_abs_path_, | 309 FROM_HERE, |
188 patch_abs_path_, | 310 base::Bind(&DeltaUpdateOpPatch::StartProcess, base::Unretained(this))); |
189 output_abs_path_, | 311 return; |
190 error); | 312 } |
| 313 const int result = traits_->Patch(input_abs_path_, |
| 314 patch_abs_path_, |
| 315 output_abs_path_); |
| 316 if (result == traits_->GetSuccessCode()) |
| 317 DonePatching(ComponentUnpacker::kNone, 0); |
| 318 else |
| 319 DonePatching(ComponentUnpacker::kDeltaOperationFailure, result); |
191 } | 320 } |
192 | 321 |
193 DeltaUpdateOpPatchCourgette::DeltaUpdateOpPatchCourgette() {} | 322 void DeltaUpdateOpPatch::StartProcess() { |
194 | 323 content::UtilityProcessHost* host = content::UtilityProcessHost::Create( |
195 ComponentUnpacker::Error DeltaUpdateOpPatchCourgette::DoParseArguments( | 324 this, base::MessageLoopProxy::current().get()); |
196 base::DictionaryValue* command_args, | 325 host->DisableSandbox(); |
197 const base::FilePath& input_dir, | 326 host->Send(traits_->GetPatchMessage(input_abs_path_, |
198 ComponentInstaller* installer) { | 327 patch_abs_path_, |
199 std::string patch_rel_path; | 328 output_abs_path_)); |
200 std::string input_rel_path; | |
201 if (!command_args->GetString(kPatch, &patch_rel_path) || | |
202 !command_args->GetString(kInput, &input_rel_path)) | |
203 return ComponentUnpacker::kDeltaBadCommands; | |
204 | |
205 if (!installer->GetInstalledFile(input_rel_path, &input_abs_path_)) | |
206 return ComponentUnpacker::kDeltaMissingExistingFile; | |
207 | |
208 patch_abs_path_ = input_dir.Append( | |
209 base::FilePath::FromUTF8Unsafe(patch_rel_path)); | |
210 | |
211 return ComponentUnpacker::kNone; | |
212 } | 329 } |
213 | 330 |
214 ComponentUnpacker::Error DeltaUpdateOpPatchCourgette::DoRun( | 331 void DeltaUpdateOpPatch::DonePatching(ComponentUnpacker::Error error, |
215 ComponentPatcher* patcher, | 332 int error_code) { |
216 int* error) { | 333 if (error != ComponentUnpacker::kNone) { |
217 *error = 0; | 334 error_code += traits_->GetErrorOffset(); |
218 return patcher->Patch(ComponentPatcher::kPatchTypeCourgette, | 335 } |
219 input_abs_path_, | 336 callback_.Run(error, error_code); |
220 patch_abs_path_, | 337 } |
221 output_abs_path_, | 338 |
222 error); | 339 bool DeltaUpdateOpPatch::OnMessageReceived(const IPC::Message& message) { |
| 340 bool handled = true; |
| 341 IPC_BEGIN_MESSAGE_MAP(DeltaUpdateOpPatch, message) |
| 342 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PatchFile_Succeeded, |
| 343 OnPatchSucceeded) |
| 344 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PatchFile_Failed, |
| 345 OnPatchFailed) |
| 346 IPC_MESSAGE_UNHANDLED(handled = false) |
| 347 IPC_END_MESSAGE_MAP() |
| 348 return handled; |
| 349 } |
| 350 |
| 351 void DeltaUpdateOpPatch::OnProcessCrashed(int exit_code) { |
| 352 DonePatching(ComponentUnpacker::kDeltaPatchProcessFailure, exit_code); |
| 353 } |
| 354 |
| 355 void DeltaUpdateOpPatch::OnPatchSucceeded() { |
| 356 DonePatching(ComponentUnpacker::kNone, 0); |
| 357 } |
| 358 |
| 359 void DeltaUpdateOpPatch::OnPatchFailed(int error_code) { |
| 360 DonePatching(ComponentUnpacker::kDeltaOperationFailure, error_code); |
223 } | 361 } |
224 | 362 |
225 } // namespace component_updater | 363 } // namespace component_updater |
OLD | NEW |