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 16namespace chromeos { 17 18namespace { 19const int kDarkSuspendDelaySeconds = 4; 20const char kLightBarControlPath[] = 21 "/sys/devices/platform/cros_ec_lpc.0/cros-ec-dev.0/chromeos/cros_ec/" 22 "lightbar/sequence"; 23const 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). 27const char kDarkResumeAlwaysFile[] = "/sys/power/dark_resume_always"; 28const char kEnableDarkResumeAlways[] = "1"; 29 30} // namespace 31 32LightBar::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 50LightBar::~LightBar() { 51 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); 52} 53 54void 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