| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/update_client/action_runner.h" |
| |
| #include <iterator> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/files/file_util.h" |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/task/post_task.h" |
| #include "build/build_config.h" |
| #include "components/crx_file/crx_verifier.h" |
| #include "components/update_client/component.h" |
| #include "components/update_client/configurator.h" |
| #include "components/update_client/task_traits.h" |
| #include "components/update_client/update_client.h" |
| #include "components/update_client/update_engine.h" |
| |
| namespace update_client { |
| |
| ActionRunner::ActionRunner(const Component& component) |
| : component_(component), |
| main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} |
| |
| ActionRunner::~ActionRunner() { |
| DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| } |
| |
| void ActionRunner::Run(Callback run_complete) { |
| DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| |
| run_complete_ = std::move(run_complete); |
| |
| base::CreateSequencedTaskRunnerWithTraits(kTaskTraits) |
| ->PostTask( |
| FROM_HERE, |
| base::BindOnce(&ActionRunner::Unpack, base::Unretained(this), |
| component_.config()->CreateServiceManagerConnector())); |
| } |
| |
| void ActionRunner::Unpack( |
| std::unique_ptr<service_manager::Connector> connector) { |
| const auto installer = component_.crx_component()->installer; |
| |
| base::FilePath file_path; |
| installer->GetInstalledFile(component_.action_run(), &file_path); |
| |
| // Contains the key hash of the CRX this object is allowed to run. |
| const auto key_hash = component_.config()->GetRunActionKeyHash(); |
| auto unpacker = base::MakeRefCounted<ComponentUnpacker>( |
| key_hash, file_path, installer, std::move(connector), |
| component_.crx_component()->crx_format_requirement); |
| unpacker->Unpack( |
| base::BindOnce(&ActionRunner::UnpackComplete, base::Unretained(this))); |
| } |
| |
| void ActionRunner::UnpackComplete(const ComponentUnpacker::Result& result) { |
| if (result.error != UnpackerError::kNone) { |
| DCHECK(!base::DirectoryExists(result.unpack_path)); |
| |
| main_task_runner_->PostTask( |
| FROM_HERE, |
| base::BindOnce(std::move(run_complete_), false, |
| static_cast<int>(result.error), result.extended_error)); |
| return; |
| } |
| |
| unpack_path_ = result.unpack_path; |
| base::SequencedTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, |
| base::BindOnce(&ActionRunner::RunCommand, base::Unretained(this), |
| MakeCommandLine(result.unpack_path))); |
| } |
| |
| #if !defined(OS_WIN) |
| |
| void ActionRunner::RunCommand(const base::CommandLine& cmdline) { |
| base::DeleteFile(unpack_path_, true); |
| main_task_runner_->PostTask( |
| FROM_HERE, base::BindOnce(std::move(run_complete_), false, -1, 0)); |
| } |
| |
| base::CommandLine ActionRunner::MakeCommandLine( |
| const base::FilePath& unpack_path) const { |
| return base::CommandLine(base::CommandLine::NO_PROGRAM); |
| } |
| |
| #endif // OS_WIN |
| |
| } // namespace update_client |