1 // Copyright 2017 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 "media/audio/power_observer_helper.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/power_monitor/power_monitor.h"
12 
13 namespace media {
14 
PowerObserverHelper(scoped_refptr<base::SequencedTaskRunner> task_runner,base::RepeatingClosure suspend_callback,base::RepeatingClosure resume_callback)15 PowerObserverHelper::PowerObserverHelper(
16     scoped_refptr<base::SequencedTaskRunner> task_runner,
17     base::RepeatingClosure suspend_callback,
18     base::RepeatingClosure resume_callback)
19     : task_runner_(std::move(task_runner)),
20       suspend_callback_(std::move(suspend_callback)),
21       resume_callback_(std::move(resume_callback)) {
22   DCHECK(!suspend_callback_.is_null());
23   DCHECK(!resume_callback_.is_null());
24 
25   // The PowerMonitor requires significant setup (a CFRunLoop and preallocated
26   // IO ports) so it's not available under unit tests.  See the OSX impl of
27   // base::PowerMonitorDeviceSource for more details.
28   // TODO(grunell): We could be suspending when adding this as observer, and
29   // we won't be notified about that. See if we can add
30   // PowerMonitorSource::IsSuspending() so that this can be checked here.
31   base::PowerMonitor::AddObserver(this);
32 }
33 
~PowerObserverHelper()34 PowerObserverHelper::~PowerObserverHelper() {
35   DCHECK(task_runner_->RunsTasksInCurrentSequence());
36   base::PowerMonitor::RemoveObserver(this);
37 }
38 
IsSuspending() const39 bool PowerObserverHelper::IsSuspending() const {
40   DCHECK(task_runner_->RunsTasksInCurrentSequence());
41   return is_suspending_;
42 }
43 
OnSuspend()44 void PowerObserverHelper::OnSuspend() {
45   DVLOG(1) << "OnSuspend";
46   if (!task_runner_->RunsTasksInCurrentSequence()) {
47     task_runner_->PostTask(FROM_HERE,
48                            base::BindOnce(&PowerObserverHelper::OnSuspend,
49                                           weak_factory_.GetWeakPtr()));
50     return;
51   }
52 
53   is_suspending_ = true;
54   suspend_callback_.Run();
55 }
56 
OnResume()57 void PowerObserverHelper::OnResume() {
58   DVLOG(1) << "OnResume";
59   if (!task_runner_->RunsTasksInCurrentSequence()) {
60     task_runner_->PostTask(FROM_HERE,
61                            base::BindOnce(&PowerObserverHelper::OnResume,
62                                           weak_factory_.GetWeakPtr()));
63     return;
64   }
65 
66   is_suspending_ = false;
67   resume_callback_.Run();
68 }
69 
70 }  // namespace media
71