| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2014 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 #include "components/update_client/component_patcher.h" | 
|  | 6 | 
|  | 7 #include <string> | 
|  | 8 #include <vector> | 
|  | 9 | 
|  | 10 #include "base/bind.h" | 
|  | 11 #include "base/bind_helpers.h" | 
|  | 12 #include "base/files/file_path.h" | 
|  | 13 #include "base/files/file_util.h" | 
|  | 14 #include "base/json/json_file_value_serializer.h" | 
|  | 15 #include "base/location.h" | 
|  | 16 #include "base/memory/weak_ptr.h" | 
|  | 17 #include "base/values.h" | 
|  | 18 #include "components/update_client/component_patcher_operation.h" | 
|  | 19 | 
|  | 20 namespace update_client { | 
|  | 21 | 
|  | 22 namespace { | 
|  | 23 | 
|  | 24 // Deserialize the commands file (present in delta update packages). The top | 
|  | 25 // level must be a list. | 
|  | 26 base::ListValue* ReadCommands(const base::FilePath& unpack_path) { | 
|  | 27   const base::FilePath commands = | 
|  | 28       unpack_path.Append(FILE_PATH_LITERAL("commands.json")); | 
|  | 29   if (!base::PathExists(commands)) | 
|  | 30     return NULL; | 
|  | 31 | 
|  | 32   JSONFileValueSerializer serializer(commands); | 
|  | 33   scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL)); | 
|  | 34 | 
|  | 35   return (root.get() && root->IsType(base::Value::TYPE_LIST)) | 
|  | 36              ? static_cast<base::ListValue*>(root.release()) | 
|  | 37              : NULL; | 
|  | 38 } | 
|  | 39 | 
|  | 40 }  // namespace | 
|  | 41 | 
|  | 42 ComponentPatcher::ComponentPatcher( | 
|  | 43     const base::FilePath& input_dir, | 
|  | 44     const base::FilePath& unpack_dir, | 
|  | 45     ComponentInstaller* installer, | 
|  | 46     scoped_refptr<OutOfProcessPatcher> out_of_process_patcher, | 
|  | 47     scoped_refptr<base::SequencedTaskRunner> task_runner) | 
|  | 48     : input_dir_(input_dir), | 
|  | 49       unpack_dir_(unpack_dir), | 
|  | 50       installer_(installer), | 
|  | 51       out_of_process_patcher_(out_of_process_patcher), | 
|  | 52       task_runner_(task_runner) { | 
|  | 53 } | 
|  | 54 | 
|  | 55 ComponentPatcher::~ComponentPatcher() { | 
|  | 56 } | 
|  | 57 | 
|  | 58 void ComponentPatcher::Start(const ComponentUnpacker::Callback& callback) { | 
|  | 59   callback_ = callback; | 
|  | 60   task_runner_->PostTask(FROM_HERE, | 
|  | 61                          base::Bind(&ComponentPatcher::StartPatching, | 
|  | 62                                     scoped_refptr<ComponentPatcher>(this))); | 
|  | 63 } | 
|  | 64 | 
|  | 65 void ComponentPatcher::StartPatching() { | 
|  | 66   commands_.reset(ReadCommands(input_dir_)); | 
|  | 67   if (!commands_.get()) { | 
|  | 68     DonePatching(ComponentUnpacker::kDeltaBadCommands, 0); | 
|  | 69   } else { | 
|  | 70     next_command_ = commands_->begin(); | 
|  | 71     PatchNextFile(); | 
|  | 72   } | 
|  | 73 } | 
|  | 74 | 
|  | 75 void ComponentPatcher::PatchNextFile() { | 
|  | 76   if (next_command_ == commands_->end()) { | 
|  | 77     DonePatching(ComponentUnpacker::kNone, 0); | 
|  | 78     return; | 
|  | 79   } | 
|  | 80   if (!(*next_command_)->IsType(base::Value::TYPE_DICTIONARY)) { | 
|  | 81     DonePatching(ComponentUnpacker::kDeltaBadCommands, 0); | 
|  | 82     return; | 
|  | 83   } | 
|  | 84   const base::DictionaryValue* command_args = | 
|  | 85       static_cast<base::DictionaryValue*>(*next_command_); | 
|  | 86 | 
|  | 87   std::string operation; | 
|  | 88   if (command_args->GetString(kOp, &operation)) { | 
|  | 89     current_operation_ = | 
|  | 90         CreateDeltaUpdateOp(operation, out_of_process_patcher_); | 
|  | 91   } | 
|  | 92 | 
|  | 93   if (!current_operation_.get()) { | 
|  | 94     DonePatching(ComponentUnpacker::kDeltaUnsupportedCommand, 0); | 
|  | 95     return; | 
|  | 96   } | 
|  | 97   current_operation_->Run(command_args, input_dir_, unpack_dir_, installer_, | 
|  | 98                           base::Bind(&ComponentPatcher::DonePatchingFile, | 
|  | 99                                      scoped_refptr<ComponentPatcher>(this)), | 
|  | 100                           task_runner_); | 
|  | 101 } | 
|  | 102 | 
|  | 103 void ComponentPatcher::DonePatchingFile(ComponentUnpacker::Error error, | 
|  | 104                                         int extended_error) { | 
|  | 105   if (error != ComponentUnpacker::kNone) { | 
|  | 106     DonePatching(error, extended_error); | 
|  | 107   } else { | 
|  | 108     ++next_command_; | 
|  | 109     PatchNextFile(); | 
|  | 110   } | 
|  | 111 } | 
|  | 112 | 
|  | 113 void ComponentPatcher::DonePatching(ComponentUnpacker::Error error, | 
|  | 114                                     int extended_error) { | 
|  | 115   current_operation_ = NULL; | 
|  | 116   task_runner_->PostTask(FROM_HERE, | 
|  | 117                          base::Bind(callback_, error, extended_error)); | 
|  | 118   callback_.Reset(); | 
|  | 119 } | 
|  | 120 | 
|  | 121 }  // namespace update_client | 
| OLD | NEW | 
|---|