• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/light_bar.h"
6 
7 #include <cstring>  // needed for strlen()
8 
9 #include "base/command_line.h"
10 #include "base/files/file_util.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "chromeos/chromeos_switches.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 
16 namespace chromeos {
17 
18 namespace {
19 const int kDarkSuspendDelaySeconds = 4;
20 const char kLightBarControlPath[] =
21     "/sys/devices/platform/cros_ec_lpc.0/cros-ec-dev.0/chromeos/cros_ec/"
22     "lightbar/sequence";
23 const char kKonamiCommand[] = "KONAMI";
24 
25 // TODO(chirantan): These are used by a temporary workaround for lucid sleep and
26 // should be removed once the proper implementation is ready (crbug.com/414949).
27 const char kDarkResumeAlwaysFile[] = "/sys/power/dark_resume_always";
28 const char kEnableDarkResumeAlways[] = "1";
29 
30 }  // namespace
31 
LightBar()32 LightBar::LightBar()
33     : control_path_(base::FilePath(kLightBarControlPath)),
34       has_light_bar_(base::PathIsWritable(control_path_)) {
35   DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
36 
37   // Until the kernel can properly detect the wakeup source, we need to use a
38   // hack to tell the kernel to always enter dark resume.  Chrome can then
39   // detect any user activity and have the power manager transition out of dark
40   // resume into regular resume.  We don't care if the write succeeds or not
41   // because most devices will not have this file.
42   //
43   // TODO(chirantan): Remove this once we can properly detect the wakeup
44   // source (crbug.com/414949).
45   base::WriteFile(base::FilePath(kDarkResumeAlwaysFile),
46                   kEnableDarkResumeAlways,
47                   strlen(kEnableDarkResumeAlways));
48 }
49 
~LightBar()50 LightBar::~LightBar() {
51   DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
52 }
53 
DarkSuspendImminent()54 void LightBar::DarkSuspendImminent() {
55   // The plan is to track the progress of push events and then re-suspend as
56   // soon as we know they have been processed.  In the meanwhile, we can hack
57   // around this by just having the light bar delay for a long time so that
58   // people can at least start playing around with this feature for their apps.
59   //
60   // TODO(chirantan): Remove this once we can accurately track the progress of
61   // push events.
62   base::MessageLoop::current()->PostDelayedTask(
63       FROM_HERE,
64       DBusThreadManager::Get()
65           ->GetPowerManagerClient()
66           ->GetSuspendReadinessCallback(),
67       base::TimeDelta::FromSeconds(kDarkSuspendDelaySeconds));
68 
69   if (!has_light_bar_)
70     return;
71 
72   if (base::WriteFile(control_path_, kKonamiCommand, strlen(kKonamiCommand)) !=
73       static_cast<int>(strlen(kKonamiCommand)))
74     PLOG(WARNING) << "Unable to flash light bar during dark resume.";
75 }
76 
77 }  // namespace chromeos
78