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)#include "components/component_updater/component_patcher.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string> 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <vector> 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind_helpers.h" 12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/files/file_path.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/json/json_file_value_serializer.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/location.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/memory/weak_ptr.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/values.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_patcher_operation.h" 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_service.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace component_updater { 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace { 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Deserialize the commands file (present in delta update packages). The top 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// level must be a list. 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::ListValue* ReadCommands(const base::FilePath& unpack_path) { 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::FilePath commands = 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unpack_path.Append(FILE_PATH_LITERAL("commands.json")); 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(commands)) 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return NULL; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JSONFileValueSerializer serializer(commands); 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL)); 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return (root.get() && root->IsType(base::Value::TYPE_LIST)) 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ? static_cast<base::ListValue*>(root.release()) 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : NULL; 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 43effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochComponentPatcher::ComponentPatcher( 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::FilePath& input_dir, 45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::FilePath& unpack_dir, 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ComponentInstaller* installer, 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<OutOfProcessPatcher> out_of_process_patcher, 48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<base::SequencedTaskRunner> task_runner) 49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : input_dir_(input_dir), 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch unpack_dir_(unpack_dir), 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch installer_(installer), 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) out_of_process_patcher_(out_of_process_patcher), 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch task_runner_(task_runner) { 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 56effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochComponentPatcher::~ComponentPatcher() { 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ComponentPatcher::Start(const ComponentUnpacker::Callback& callback) { 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch callback_ = callback; 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch task_runner_->PostTask(FROM_HERE, 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&ComponentPatcher::StartPatching, 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<ComponentPatcher>(this))); 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ComponentPatcher::StartPatching() { 67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch commands_.reset(ReadCommands(input_dir_)); 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!commands_.get()) { 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DonePatching(ComponentUnpacker::kDeltaBadCommands, 0); 70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch next_command_ = commands_->begin(); 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PatchNextFile(); 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ComponentPatcher::PatchNextFile() { 77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (next_command_ == commands_->end()) { 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DonePatching(ComponentUnpacker::kNone, 0); 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!(*next_command_)->IsType(base::Value::TYPE_DICTIONARY)) { 82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DonePatching(ComponentUnpacker::kDeltaBadCommands, 0); 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* command_args = 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch static_cast<base::DictionaryValue*>(*next_command_); 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string operation; 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (command_args->GetString(kOp, &operation)) { 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current_operation_ = 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CreateDeltaUpdateOp(operation, out_of_process_patcher_); 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!current_operation_.get()) { 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DonePatching(ComponentUnpacker::kDeltaUnsupportedCommand, 0); 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) current_operation_->Run(command_args, 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_dir_, 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) unpack_dir_, 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) installer_, 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&ComponentPatcher::DonePatchingFile, 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<ComponentPatcher>(this)), 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) task_runner_); 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ComponentPatcher::DonePatchingFile(ComponentUnpacker::Error error, 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int extended_error) { 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (error != ComponentUnpacker::kNone) { 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DonePatching(error, extended_error); 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++next_command_; 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PatchNextFile(); 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ComponentPatcher::DonePatching(ComponentUnpacker::Error error, 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int extended_error) { 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch current_operation_ = NULL; 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) task_runner_->PostTask(FROM_HERE, 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(callback_, error, extended_error)); 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch callback_.Reset(); 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace component_updater 126