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()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 ~LightBar()50LightBar::~LightBar() { 51 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); 52 } 53 DarkSuspendImminent()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