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 "chrome/browser/chromeos/power/freezer_cgroup_process_manager.h"
6
7#include <string>
8
9#include "base/files/file_util.h"
10#include "base/logging.h"
11
12namespace chromeos {
13
14namespace {
15const char kFreezerStatePath[] =
16    "/sys/fs/cgroup/freezer/chrome_renderers/freezer.state";
17const char kFreezeCommand[] = "FROZEN";
18const char kThawCommand[] = "THAWED";
19
20}  // namespace
21
22FreezerCgroupProcessManager::FreezerCgroupProcessManager()
23    : state_path_(base::FilePath(kFreezerStatePath)),
24      enabled_(base::PathIsWritable(state_path_)) {
25  if (!enabled_) {
26    LOG(WARNING) << "Cgroup freezer does not exist or is not writable. "
27                 << "Unable to freeze renderer processes.";
28  }
29}
30
31FreezerCgroupProcessManager::~FreezerCgroupProcessManager() {
32}
33
34bool FreezerCgroupProcessManager::FreezeRenderers() {
35  if (!enabled_) {
36    LOG(ERROR) << "Attempting to freeze renderers when the freezer cgroup is "
37               << "not available.";
38    return false;
39  }
40
41  return WriteCommandToStateFile(kFreezeCommand);
42}
43
44bool FreezerCgroupProcessManager::ThawRenderers() {
45  if (!enabled_) {
46    LOG(ERROR) << "Attempting to thaw renderers when the freezer cgroup is not "
47               << "available.";
48    return false;
49  }
50
51  return WriteCommandToStateFile(kThawCommand);
52}
53
54bool FreezerCgroupProcessManager::CanFreezeRenderers() {
55  return enabled_;
56}
57
58bool FreezerCgroupProcessManager::WriteCommandToStateFile(
59    const std::string& command) {
60  int bytes = base::WriteFile(state_path_, command.c_str(), command.size());
61  if (bytes == -1) {
62    PLOG(ERROR) << "Writing " << command << " to " << state_path_.value()
63                << " failed";
64    return false;
65  } else if (bytes != static_cast<int>(command.size())) {
66    LOG(ERROR) << "Only wrote " << bytes << " byte(s) when writing "
67               << command << " to " << state_path_.value();
68    return false;
69  }
70  return true;
71}
72
73}  // namespace chromeos
74