1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/updater/app/app_wakeall.h"
#include <optional>
#include "base/command_line.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/process/launch.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "base/version.h"
#include "chrome/updater/app/app.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/util/util.h"
namespace updater {
// AppWakeAll finds and launches --wake applications for all versions of the
// updater within the same scope.
class AppWakeAll : public App {
private:
~AppWakeAll() override = default;
// Overrides for App.
void FirstTaskRun() override;
};
void AppWakeAll::FirstTaskRun() {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::WithBaseSyncPrimitives()},
base::BindOnce(
[](UpdaterScope scope) {
std::optional<base::FilePath> base = GetInstallDirectory(scope);
if (!base) {
return kErrorNoBaseDirectory;
}
base::FileEnumerator(*base, false,
base::FileEnumerator::DIRECTORIES)
.ForEach([&scope](const base::FilePath& name) {
if (!base::Version(name.BaseName().AsUTF8Unsafe())
.IsValid()) {
return;
}
base::CommandLine command(
name.Append(GetExecutableRelativePath()));
command.AppendSwitch(kWakeSwitch);
if (IsSystemInstall(scope)) {
command.AppendSwitch(kSystemSwitch);
}
VLOG(1) << "Launching `" << command.GetCommandLineString()
<< "`";
int exit = 0;
const base::Process process =
base::LaunchProcess(command, {});
if (!process.IsValid()) {
VPLOG(1) << "`" << command.GetCommandLineString()
<< "` process invalid";
} else if (process.WaitForExitWithTimeout(base::Minutes(10),
&exit)) {
VLOG(1) << "`" << command.GetCommandLineString()
<< "` exited " << exit;
} else {
VPLOG(1) << "`" << command.GetCommandLineString()
<< "` timed out.";
}
});
return kErrorOk;
},
updater_scope()),
base::BindOnce(&AppWakeAll::Shutdown, this));
}
scoped_refptr<App> MakeAppWakeAll() {
return base::MakeRefCounted<AppWakeAll>();
}
} // namespace updater
|