OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h" | 5 #include "chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h" |
6 | 6 |
7 #include "base/sys_info.h" | 7 #include "base/sys_info.h" |
8 #include "chrome/common/chrome_notification_types.h" | |
9 #include "content/public/browser/browser_thread.h" | |
10 #include "content/public/browser/notification_details.h" | |
11 #include "content/public/browser/notification_service.h" | |
12 #include "content/public/browser/notification_source.h" | |
13 #include "content/public/browser/notification_types.h" | |
14 | 8 |
15 namespace extensions { | 9 namespace extensions { |
16 | 10 |
17 using api::system_info_cpu::CpuInfo; | 11 using api::system_info_cpu::CpuInfo; |
18 using api::system_info_cpu::CpuUpdateInfo; | |
19 using content::BrowserThread; | |
20 | 12 |
21 // Default sampling interval is 1000ms. | 13 CpuInfoProvider::CpuInfoProvider() {} |
22 const unsigned int kDefaultSamplingIntervalMs = 1000; | |
23 | 14 |
24 CpuInfoProvider::CpuInfoProvider() | 15 CpuInfoProvider::~CpuInfoProvider() {} |
25 : is_sampling_started_(false), | |
26 sampling_timer_(NULL), | |
27 sampling_interval_(kDefaultSamplingIntervalMs) { | |
28 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | |
29 content::NotificationService::AllSources()); | |
30 } | |
31 | |
32 CpuInfoProvider::~CpuInfoProvider() { | |
33 DCHECK(sampling_timer_ == NULL); | |
34 registrar_.RemoveAll(); | |
35 } | |
36 | 16 |
37 bool CpuInfoProvider::QueryInfo(CpuInfo* info) { | 17 bool CpuInfoProvider::QueryInfo(CpuInfo* info) { |
38 if (info == NULL) | 18 if (info == NULL) |
39 return false; | 19 return false; |
40 | 20 |
41 info->num_of_processors = base::SysInfo::NumberOfProcessors(); | 21 info->num_of_processors = base::SysInfo::NumberOfProcessors(); |
42 info->arch_name = base::SysInfo::OperatingSystemArchitecture(); | 22 info->arch_name = base::SysInfo::OperatingSystemArchitecture(); |
43 info->model_name = base::SysInfo::CPUModelName(); | 23 info->model_name = base::SysInfo::CPUModelName(); |
44 return true; | 24 return true; |
45 } | 25 } |
46 | 26 |
47 void CpuInfoProvider::StartSampling(const SamplingCallback& callback) { | |
48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
49 BrowserThread::PostTask( | |
50 BrowserThread::FILE, | |
51 FROM_HERE, | |
52 base::Bind(&CpuInfoProvider::StartSamplingOnFileThread, this, callback)); | |
53 } | |
54 | |
55 void CpuInfoProvider::StopSampling() { | |
56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
57 BrowserThread::PostTask( | |
58 BrowserThread::FILE, | |
59 FROM_HERE, | |
60 base::Bind(&CpuInfoProvider::StopSamplingOnFileThread, this)); | |
61 } | |
62 | |
63 // static | 27 // static |
64 CpuInfoProvider* CpuInfoProvider::Get() { | 28 CpuInfoProvider* CpuInfoProvider::Get() { |
65 return CpuInfoProvider::GetInstance<CpuInfoProvider>(); | 29 return CpuInfoProvider::GetInstance<CpuInfoProvider>(); |
66 } | 30 } |
67 | 31 |
68 void CpuInfoProvider::Observe( | |
69 int type, | |
70 const content::NotificationSource& source, | |
71 const content::NotificationDetails& details) { | |
72 switch (type) { | |
73 case chrome::NOTIFICATION_APP_TERMINATING: | |
74 StopSampling(); | |
75 break; | |
76 default: | |
77 NOTREACHED(); | |
78 break; | |
79 } | |
80 } | |
81 | |
82 void CpuInfoProvider::StartSamplingOnFileThread( | |
83 const SamplingCallback& callback) { | |
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
85 if (is_sampling_started_) | |
86 return; | |
87 | |
88 if (!QueryCpuTimePerProcessor(&baseline_cpu_time_)) | |
89 return; | |
90 | |
91 is_sampling_started_ = true; | |
92 callback_ = callback; | |
93 DCHECK(!sampling_timer_) << "The sampling timer has leaked. Did you forgot " | |
94 "to call StopSampling?"; | |
95 // Should be deleted on FILE thread. | |
96 sampling_timer_ = new base::RepeatingTimer<CpuInfoProvider>(); | |
97 sampling_timer_->Start(FROM_HERE, | |
98 base::TimeDelta::FromMilliseconds(sampling_interval_), | |
99 this, &CpuInfoProvider::DoSample); | |
100 } | |
101 | |
102 void CpuInfoProvider::StopSamplingOnFileThread() { | |
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
104 if (!is_sampling_started_) return; | |
105 delete sampling_timer_; | |
106 sampling_timer_ = NULL; | |
107 baseline_cpu_time_.clear(); | |
108 is_sampling_started_ = false; | |
109 } | |
110 | |
111 void CpuInfoProvider::DoSample() { | |
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
113 | |
114 std::vector<CpuTime> next_cpu_time; | |
115 if (!QueryCpuTimePerProcessor(&next_cpu_time)) | |
116 return; | |
117 | |
118 // Calculate the CPU usage information from the next_cpu_time and | |
119 // |baseline_cpu_time_|. | |
120 double total_usage = 0; | |
121 scoped_ptr<CpuUpdateInfo> info(new CpuUpdateInfo()); | |
122 for (size_t i = 0; i < next_cpu_time.size(); ++i) { | |
123 double total_time = | |
124 (next_cpu_time[i].user - baseline_cpu_time_[i].user) + | |
125 (next_cpu_time[i].kernel - baseline_cpu_time_[i].kernel) + | |
126 (next_cpu_time[i].idle - baseline_cpu_time_[i].idle); | |
127 double idle_time = next_cpu_time[i].idle - baseline_cpu_time_[i].idle; | |
128 | |
129 double usage = 0; | |
130 if (total_time != 0) | |
131 usage = (100 - idle_time * 100 / total_time); | |
132 info->usage_per_processor.push_back(usage); | |
133 total_usage += usage; | |
134 } | |
135 | |
136 info->average_usage = total_usage / next_cpu_time.size(); | |
137 if (!callback_.is_null()) | |
138 callback_.Run(info.Pass()); | |
139 // Use next_cpu_time as baseline_cpu_time_ for the next sampling cycle. | |
140 baseline_cpu_time_.swap(next_cpu_time); | |
141 } | |
142 | |
143 } // namespace extensions | 32 } // namespace extensions |
OLD | NEW |