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
3 // found in the LICENSE file.
5 #include "chrome/browser/metrics/metrics_log.h"
9 #include "base/base64.h"
10 #include "base/basictypes.h"
11 #include "base/command_line.h"
12 #include "base/port.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/prefs/scoped_user_pref_update.h"
15 #include "base/prefs/testing_pref_service.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/time/time.h"
22 #include "base/tracked_objects.h"
23 #include "chrome/browser/google/google_util.h"
24 #include "chrome/browser/prefs/browser_prefs.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/metrics/proto/profiler_event.pb.h"
27 #include "chrome/common/metrics/proto/system_profile.pb.h"
28 #include "chrome/common/metrics/variations/variations_util.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/installer/util/google_update_settings.h"
31 #include "components/variations/metrics_util.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/common/process_type.h"
34 #include "content/public/common/webplugininfo.h"
35 #include "content/public/test/test_browser_thread_bundle.h"
36 #include "content/public/test/test_utils.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "ui/gfx/size.h"
41 #if defined(OS_CHROMEOS)
42 #include "chrome/browser/chromeos/login/fake_user_manager.h"
43 #include "chrome/browser/chromeos/login/user_manager.h"
44 #include "chrome/browser/metrics/metrics_log_chromeos.h"
45 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
46 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
47 #include "chromeos/dbus/fake_bluetooth_device_client.h"
48 #include "chromeos/dbus/fake_bluetooth_input_client.h"
49 #include "chromeos/dbus/fake_dbus_thread_manager.h"
51 using chromeos::DBusThreadManager
;
52 using chromeos::BluetoothAdapterClient
;
53 using chromeos::BluetoothAgentManagerClient
;
54 using chromeos::BluetoothDeviceClient
;
55 using chromeos::BluetoothInputClient
;
56 using chromeos::FakeBluetoothAdapterClient
;
57 using chromeos::FakeBluetoothAgentManagerClient
;
58 using chromeos::FakeBluetoothDeviceClient
;
59 using chromeos::FakeBluetoothInputClient
;
60 using chromeos::FakeDBusThreadManager
;
63 using base::TimeDelta
;
64 using metrics::ProfilerEventProto
;
65 using tracked_objects::ProcessDataSnapshot
;
66 using tracked_objects::TaskSnapshot
;
70 const char kClientId
[] = "bogus client ID";
71 const int64 kInstallDate
= 1373051956;
72 const int64 kInstallDateExpected
= 1373050800; // Computed from kInstallDate.
73 const int64 kEnabledDate
= 1373001211;
74 const int64 kEnabledDateExpected
= 1373000400; // Computed from kEnabledDate.
75 const int kSessionId
= 127;
76 const int kScreenWidth
= 1024;
77 const int kScreenHeight
= 768;
78 const int kScreenCount
= 3;
79 const float kScreenScaleFactor
= 2;
80 const char kBrandForTesting
[] = "brand_for_testing";
81 const chrome_variations::ActiveGroupId kFieldTrialIds
[] = {
86 const chrome_variations::ActiveGroupId kSyntheticTrials
[] = {
91 #if defined(ENABLE_PLUGINS)
92 content::WebPluginInfo
CreateFakePluginInfo(
93 const std::string
& name
,
94 const base::FilePath::CharType
* path
,
95 const std::string
& version
,
97 content::WebPluginInfo
plugin(base::UTF8ToUTF16(name
),
99 base::UTF8ToUTF16(version
),
102 plugin
.type
= content::WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS
;
104 plugin
.type
= content::WebPluginInfo::PLUGIN_TYPE_NPAPI
;
107 #endif // defined(ENABLE_PLUGINS)
109 #if defined(OS_CHROMEOS)
110 class TestMetricsLogChromeOS
: public MetricsLogChromeOS
{
112 explicit TestMetricsLogChromeOS(
113 metrics::ChromeUserMetricsExtension
* uma_proto
)
114 : MetricsLogChromeOS(uma_proto
) {
117 #endif // OS_CHROMEOS
119 class TestMetricsLog
: public MetricsLog
{
121 TestMetricsLog(const std::string
& client_id
, int session_id
)
122 : MetricsLog(client_id
, session_id
),
123 prefs_(&scoped_prefs_
),
124 brand_for_testing_(kBrandForTesting
) {
125 #if defined(OS_CHROMEOS)
126 metrics_log_chromeos_
.reset(new TestMetricsLogChromeOS(
127 MetricsLog::uma_proto()));
128 #endif // OS_CHROMEOS
129 chrome::RegisterLocalState(scoped_prefs_
.registry());
132 // Creates a TestMetricsLog that will use |prefs| as the fake local state.
133 // Useful for tests that need to re-use the local state prefs between logs.
134 TestMetricsLog(const std::string
& client_id
,
136 TestingPrefServiceSimple
* prefs
)
137 : MetricsLog(client_id
, session_id
),
139 brand_for_testing_(kBrandForTesting
) {
140 #if defined(OS_CHROMEOS)
141 metrics_log_chromeos_
.reset(new TestMetricsLogChromeOS(
142 MetricsLog::uma_proto()));
143 #endif // OS_CHROMEOS
146 virtual ~TestMetricsLog() {}
148 virtual PrefService
* GetPrefService() OVERRIDE
{
152 const metrics::ChromeUserMetricsExtension
& uma_proto() const {
153 return *MetricsLog::uma_proto();
156 const metrics::SystemProfileProto
& system_profile() const {
157 return uma_proto().system_profile();
162 prefs_
->SetInt64(prefs::kInstallDate
, kInstallDate
);
163 prefs_
->SetString(prefs::kMetricsReportingEnabledTimestamp
,
164 base::Int64ToString(kEnabledDate
));
165 #if defined(OS_CHROMEOS)
166 prefs_
->SetInteger(prefs::kStabilityChildProcessCrashCount
, 10);
167 prefs_
->SetInteger(prefs::kStabilityOtherUserCrashCount
, 11);
168 prefs_
->SetInteger(prefs::kStabilityKernelCrashCount
, 12);
169 prefs_
->SetInteger(prefs::kStabilitySystemUncleanShutdownCount
, 13);
170 #endif // OS_CHROMEOS
173 virtual void GetFieldTrialIds(
174 std::vector
<chrome_variations::ActiveGroupId
>* field_trial_ids
) const
176 ASSERT_TRUE(field_trial_ids
->empty());
178 for (size_t i
= 0; i
< arraysize(kFieldTrialIds
); ++i
) {
179 field_trial_ids
->push_back(kFieldTrialIds
[i
]);
183 virtual gfx::Size
GetScreenSize() const OVERRIDE
{
184 return gfx::Size(kScreenWidth
, kScreenHeight
);
187 virtual float GetScreenDeviceScaleFactor() const OVERRIDE
{
188 return kScreenScaleFactor
;
191 virtual int GetScreenCount() const OVERRIDE
{
195 // Scoped PrefsService, which may not be used if |prefs_ != &scoped_prefs|.
196 TestingPrefServiceSimple scoped_prefs_
;
197 // Weak pointer to the PrefsService used by this log.
198 TestingPrefServiceSimple
* prefs_
;
200 google_util::BrandForTesting brand_for_testing_
;
202 DISALLOW_COPY_AND_ASSIGN(TestMetricsLog
);
207 class MetricsLogTest
: public testing::Test
{
212 virtual void SetUp() OVERRIDE
{
213 #if defined(OS_CHROMEOS)
214 // Enable multi-profiles.
215 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kMultiProfiles
);
217 // Set up the fake Bluetooth environment,
218 scoped_ptr
<FakeDBusThreadManager
> fake_dbus_thread_manager(
219 new FakeDBusThreadManager
);
220 fake_dbus_thread_manager
->SetBluetoothAdapterClient(
221 scoped_ptr
<BluetoothAdapterClient
>(new FakeBluetoothAdapterClient
));
222 fake_dbus_thread_manager
->SetBluetoothDeviceClient(
223 scoped_ptr
<BluetoothDeviceClient
>(new FakeBluetoothDeviceClient
));
224 fake_dbus_thread_manager
->SetBluetoothInputClient(
225 scoped_ptr
<BluetoothInputClient
>(new FakeBluetoothInputClient
));
226 fake_dbus_thread_manager
->SetBluetoothAgentManagerClient(
227 scoped_ptr
<BluetoothAgentManagerClient
>(
228 new FakeBluetoothAgentManagerClient
));
229 DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager
.release());
231 // Grab pointers to members of the thread manager for easier testing.
232 fake_bluetooth_adapter_client_
= static_cast<FakeBluetoothAdapterClient
*>(
233 DBusThreadManager::Get()->GetBluetoothAdapterClient());
234 fake_bluetooth_device_client_
= static_cast<FakeBluetoothDeviceClient
*>(
235 DBusThreadManager::Get()->GetBluetoothDeviceClient());
236 #endif // OS_CHROMEOS
239 virtual void TearDown() OVERRIDE
{
240 #if defined(OS_CHROMEOS)
241 DBusThreadManager::Shutdown();
242 #endif // OS_CHROMEOS
245 // Check that the values in |system_values| correspond to the test data
246 // defined at the top of this file.
247 void CheckSystemProfile(const metrics::SystemProfileProto
& system_profile
) {
248 EXPECT_EQ(kInstallDateExpected
, system_profile
.install_date());
249 EXPECT_EQ(kEnabledDateExpected
, system_profile
.uma_enabled_date());
251 ASSERT_EQ(arraysize(kFieldTrialIds
) + arraysize(kSyntheticTrials
),
252 static_cast<size_t>(system_profile
.field_trial_size()));
253 for (size_t i
= 0; i
< arraysize(kFieldTrialIds
); ++i
) {
254 const metrics::SystemProfileProto::FieldTrial
& field_trial
=
255 system_profile
.field_trial(i
);
256 EXPECT_EQ(kFieldTrialIds
[i
].name
, field_trial
.name_id());
257 EXPECT_EQ(kFieldTrialIds
[i
].group
, field_trial
.group_id());
259 // Verify the right data is present for the synthetic trials.
260 for (size_t i
= 0; i
< arraysize(kSyntheticTrials
); ++i
) {
261 const metrics::SystemProfileProto::FieldTrial
& field_trial
=
262 system_profile
.field_trial(i
+ arraysize(kFieldTrialIds
));
263 EXPECT_EQ(kSyntheticTrials
[i
].name
, field_trial
.name_id());
264 EXPECT_EQ(kSyntheticTrials
[i
].group
, field_trial
.group_id());
267 EXPECT_EQ(kBrandForTesting
, system_profile
.brand_code());
269 const metrics::SystemProfileProto::Hardware
& hardware
=
270 system_profile
.hardware();
271 EXPECT_EQ(kScreenWidth
, hardware
.primary_screen_width());
272 EXPECT_EQ(kScreenHeight
, hardware
.primary_screen_height());
273 EXPECT_EQ(kScreenScaleFactor
, hardware
.primary_screen_scale_factor());
274 EXPECT_EQ(kScreenCount
, hardware
.screen_count());
276 EXPECT_TRUE(hardware
.has_cpu());
277 EXPECT_TRUE(hardware
.cpu().has_vendor_name());
278 EXPECT_TRUE(hardware
.cpu().has_signature());
280 // TODO(isherman): Verify other data written into the protobuf as a result
285 #if defined(OS_CHROMEOS)
286 FakeBluetoothAdapterClient
* fake_bluetooth_adapter_client_
;
287 FakeBluetoothDeviceClient
* fake_bluetooth_device_client_
;
288 #endif // OS_CHROMEOS
291 content::TestBrowserThreadBundle thread_bundle_
;
293 DISALLOW_COPY_AND_ASSIGN(MetricsLogTest
);
296 TEST_F(MetricsLogTest
, RecordEnvironment
) {
297 TestMetricsLog
log(kClientId
, kSessionId
);
299 std::vector
<content::WebPluginInfo
> plugins
;
300 GoogleUpdateMetrics google_update_metrics
;
301 std::vector
<chrome_variations::ActiveGroupId
> synthetic_trials
;
302 // Add two synthetic trials.
303 synthetic_trials
.push_back(kSyntheticTrials
[0]);
304 synthetic_trials
.push_back(kSyntheticTrials
[1]);
306 log
.RecordEnvironment(plugins
, google_update_metrics
, synthetic_trials
);
307 // Check that the system profile on the log has the correct values set.
308 CheckSystemProfile(log
.system_profile());
310 // Check that the system profile has also been written to prefs.
311 PrefService
* local_state
= log
.GetPrefService();
312 const std::string base64_system_profile
=
313 local_state
->GetString(prefs::kStabilitySavedSystemProfile
);
314 EXPECT_FALSE(base64_system_profile
.empty());
315 std::string serialied_system_profile
;
316 EXPECT_TRUE(base::Base64Decode(base64_system_profile
,
317 &serialied_system_profile
));
318 SystemProfileProto decoded_system_profile
;
319 EXPECT_TRUE(decoded_system_profile
.ParseFromString(serialied_system_profile
));
320 CheckSystemProfile(decoded_system_profile
);
323 TEST_F(MetricsLogTest
, LoadSavedEnvironmentFromPrefs
) {
324 const char* kSystemProfilePref
= prefs::kStabilitySavedSystemProfile
;
325 const char* kSystemProfileHashPref
= prefs::kStabilitySavedSystemProfileHash
;
327 TestingPrefServiceSimple prefs
;
328 chrome::RegisterLocalState(prefs
.registry());
330 // The pref value is empty, so loading it from prefs should fail.
332 TestMetricsLog
log(kClientId
, kSessionId
, &prefs
);
333 EXPECT_FALSE(log
.LoadSavedEnvironmentFromPrefs());
336 // Do a RecordEnvironment() call and check whether the pref is recorded.
338 TestMetricsLog
log(kClientId
, kSessionId
, &prefs
);
339 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
340 GoogleUpdateMetrics(),
341 std::vector
<chrome_variations::ActiveGroupId
>());
342 EXPECT_FALSE(prefs
.GetString(kSystemProfilePref
).empty());
343 EXPECT_FALSE(prefs
.GetString(kSystemProfileHashPref
).empty());
347 TestMetricsLog
log(kClientId
, kSessionId
, &prefs
);
348 EXPECT_TRUE(log
.LoadSavedEnvironmentFromPrefs());
349 // Check some values in the system profile.
350 EXPECT_EQ(kInstallDateExpected
, log
.system_profile().install_date());
351 EXPECT_EQ(kEnabledDateExpected
, log
.system_profile().uma_enabled_date());
352 // Ensure that the call cleared the prefs.
353 EXPECT_TRUE(prefs
.GetString(kSystemProfilePref
).empty());
354 EXPECT_TRUE(prefs
.GetString(kSystemProfileHashPref
).empty());
357 // Ensure that a non-matching hash results in the pref being invalid.
359 TestMetricsLog
log(kClientId
, kSessionId
, &prefs
);
360 // Call RecordEnvironment() to record the pref again.
361 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
362 GoogleUpdateMetrics(),
363 std::vector
<chrome_variations::ActiveGroupId
>());
367 // Set the hash to a bad value.
368 prefs
.SetString(kSystemProfileHashPref
, "deadbeef");
369 TestMetricsLog
log(kClientId
, kSessionId
, &prefs
);
370 EXPECT_FALSE(log
.LoadSavedEnvironmentFromPrefs());
371 // Ensure that the prefs are cleared, even if the call failed.
372 EXPECT_TRUE(prefs
.GetString(kSystemProfilePref
).empty());
373 EXPECT_TRUE(prefs
.GetString(kSystemProfileHashPref
).empty());
377 TEST_F(MetricsLogTest
, InitialLogStabilityMetrics
) {
378 TestMetricsLog
log(kClientId
, kSessionId
);
379 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
380 GoogleUpdateMetrics(),
381 std::vector
<chrome_variations::ActiveGroupId
>());
382 log
.RecordStabilityMetrics(
383 base::TimeDelta(), base::TimeDelta(), MetricsLog::INITIAL_LOG
);
384 const metrics::SystemProfileProto_Stability
& stability
=
385 log
.system_profile().stability();
387 EXPECT_TRUE(stability
.has_launch_count());
388 EXPECT_TRUE(stability
.has_crash_count());
389 // Initial log metrics:
390 EXPECT_TRUE(stability
.has_incomplete_shutdown_count());
391 EXPECT_TRUE(stability
.has_breakpad_registration_success_count());
392 EXPECT_TRUE(stability
.has_breakpad_registration_failure_count());
393 EXPECT_TRUE(stability
.has_debugger_present_count());
394 EXPECT_TRUE(stability
.has_debugger_not_present_count());
397 TEST_F(MetricsLogTest
, OngoingLogStabilityMetrics
) {
398 TestMetricsLog
log(kClientId
, kSessionId
);
399 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
400 GoogleUpdateMetrics(),
401 std::vector
<chrome_variations::ActiveGroupId
>());
402 log
.RecordStabilityMetrics(
403 base::TimeDelta(), base::TimeDelta(), MetricsLog::ONGOING_LOG
);
404 const metrics::SystemProfileProto_Stability
& stability
=
405 log
.system_profile().stability();
407 EXPECT_TRUE(stability
.has_launch_count());
408 EXPECT_TRUE(stability
.has_crash_count());
409 // Initial log metrics:
410 EXPECT_FALSE(stability
.has_incomplete_shutdown_count());
411 EXPECT_FALSE(stability
.has_breakpad_registration_success_count());
412 EXPECT_FALSE(stability
.has_breakpad_registration_failure_count());
413 EXPECT_FALSE(stability
.has_debugger_present_count());
414 EXPECT_FALSE(stability
.has_debugger_not_present_count());
417 #if defined(ENABLE_PLUGINS)
418 TEST_F(MetricsLogTest
, Plugins
) {
419 TestMetricsLog
log(kClientId
, kSessionId
);
421 std::vector
<content::WebPluginInfo
> plugins
;
422 plugins
.push_back(CreateFakePluginInfo("p1", FILE_PATH_LITERAL("p1.plugin"),
424 plugins
.push_back(CreateFakePluginInfo("p2", FILE_PATH_LITERAL("p2.plugin"),
426 log
.RecordEnvironment(plugins
, GoogleUpdateMetrics(),
427 std::vector
<chrome_variations::ActiveGroupId
>());
429 const metrics::SystemProfileProto
& system_profile
= log
.system_profile();
430 ASSERT_EQ(2, system_profile
.plugin_size());
431 EXPECT_EQ("p1", system_profile
.plugin(0).name());
432 EXPECT_EQ("p1.plugin", system_profile
.plugin(0).filename());
433 EXPECT_EQ("1.5", system_profile
.plugin(0).version());
434 EXPECT_TRUE(system_profile
.plugin(0).is_pepper());
435 EXPECT_EQ("p2", system_profile
.plugin(1).name());
436 EXPECT_EQ("p2.plugin", system_profile
.plugin(1).filename());
437 EXPECT_EQ("2.0", system_profile
.plugin(1).version());
438 EXPECT_FALSE(system_profile
.plugin(1).is_pepper());
440 // Now set some plugin stability stats for p2 and verify they're recorded.
441 scoped_ptr
<base::DictionaryValue
> plugin_dict(new base::DictionaryValue
);
442 plugin_dict
->SetString(prefs::kStabilityPluginName
, "p2");
443 plugin_dict
->SetInteger(prefs::kStabilityPluginLaunches
, 1);
444 plugin_dict
->SetInteger(prefs::kStabilityPluginCrashes
, 2);
445 plugin_dict
->SetInteger(prefs::kStabilityPluginInstances
, 3);
446 plugin_dict
->SetInteger(prefs::kStabilityPluginLoadingErrors
, 4);
448 ListPrefUpdate
update(log
.GetPrefService(), prefs::kStabilityPluginStats
);
449 update
.Get()->Append(plugin_dict
.release());
452 log
.RecordStabilityMetrics(
453 base::TimeDelta(), base::TimeDelta(), MetricsLog::ONGOING_LOG
);
454 const metrics::SystemProfileProto_Stability
& stability
=
455 log
.system_profile().stability();
456 ASSERT_EQ(1, stability
.plugin_stability_size());
457 EXPECT_EQ("p2", stability
.plugin_stability(0).plugin().name());
458 EXPECT_EQ("p2.plugin", stability
.plugin_stability(0).plugin().filename());
459 EXPECT_EQ("2.0", stability
.plugin_stability(0).plugin().version());
460 EXPECT_FALSE(stability
.plugin_stability(0).plugin().is_pepper());
461 EXPECT_EQ(1, stability
.plugin_stability(0).launch_count());
462 EXPECT_EQ(2, stability
.plugin_stability(0).crash_count());
463 EXPECT_EQ(3, stability
.plugin_stability(0).instance_count());
464 EXPECT_EQ(4, stability
.plugin_stability(0).loading_error_count());
466 #endif // defined(ENABLE_PLUGINS)
468 // Test that we properly write profiler data to the log.
469 TEST_F(MetricsLogTest
, RecordProfilerData
) {
470 TestMetricsLog
log(kClientId
, kSessionId
);
471 EXPECT_EQ(0, log
.uma_proto().profiler_event_size());
474 ProcessDataSnapshot process_data
;
475 process_data
.process_id
= 177;
476 process_data
.tasks
.push_back(TaskSnapshot());
477 process_data
.tasks
.back().birth
.location
.file_name
= "file";
478 process_data
.tasks
.back().birth
.location
.function_name
= "function";
479 process_data
.tasks
.back().birth
.location
.line_number
= 1337;
480 process_data
.tasks
.back().birth
.thread_name
= "birth_thread";
481 process_data
.tasks
.back().death_data
.count
= 37;
482 process_data
.tasks
.back().death_data
.run_duration_sum
= 31;
483 process_data
.tasks
.back().death_data
.run_duration_max
= 17;
484 process_data
.tasks
.back().death_data
.run_duration_sample
= 13;
485 process_data
.tasks
.back().death_data
.queue_duration_sum
= 8;
486 process_data
.tasks
.back().death_data
.queue_duration_max
= 5;
487 process_data
.tasks
.back().death_data
.queue_duration_sample
= 3;
488 process_data
.tasks
.back().death_thread_name
= "Still_Alive";
489 process_data
.tasks
.push_back(TaskSnapshot());
490 process_data
.tasks
.back().birth
.location
.file_name
= "file2";
491 process_data
.tasks
.back().birth
.location
.function_name
= "function2";
492 process_data
.tasks
.back().birth
.location
.line_number
= 1773;
493 process_data
.tasks
.back().birth
.thread_name
= "birth_thread2";
494 process_data
.tasks
.back().death_data
.count
= 19;
495 process_data
.tasks
.back().death_data
.run_duration_sum
= 23;
496 process_data
.tasks
.back().death_data
.run_duration_max
= 11;
497 process_data
.tasks
.back().death_data
.run_duration_sample
= 7;
498 process_data
.tasks
.back().death_data
.queue_duration_sum
= 0;
499 process_data
.tasks
.back().death_data
.queue_duration_max
= 0;
500 process_data
.tasks
.back().death_data
.queue_duration_sample
= 0;
501 process_data
.tasks
.back().death_thread_name
= "death_thread";
503 log
.RecordProfilerData(process_data
, content::PROCESS_TYPE_BROWSER
);
504 ASSERT_EQ(1, log
.uma_proto().profiler_event_size());
505 EXPECT_EQ(ProfilerEventProto::STARTUP_PROFILE
,
506 log
.uma_proto().profiler_event(0).profile_type());
507 EXPECT_EQ(ProfilerEventProto::WALL_CLOCK_TIME
,
508 log
.uma_proto().profiler_event(0).time_source());
510 ASSERT_EQ(2, log
.uma_proto().profiler_event(0).tracked_object_size());
512 const ProfilerEventProto::TrackedObject
* tracked_object
=
513 &log
.uma_proto().profiler_event(0).tracked_object(0);
514 EXPECT_EQ(GG_UINT64_C(10123486280357988687),
515 tracked_object
->source_file_name_hash());
516 EXPECT_EQ(GG_UINT64_C(13962325592283560029),
517 tracked_object
->source_function_name_hash());
518 EXPECT_EQ(1337, tracked_object
->source_line_number());
519 EXPECT_EQ(GG_UINT64_C(3400908935414830400),
520 tracked_object
->birth_thread_name_hash());
521 EXPECT_EQ(37, tracked_object
->exec_count());
522 EXPECT_EQ(31, tracked_object
->exec_time_total());
523 EXPECT_EQ(13, tracked_object
->exec_time_sampled());
524 EXPECT_EQ(8, tracked_object
->queue_time_total());
525 EXPECT_EQ(3, tracked_object
->queue_time_sampled());
526 EXPECT_EQ(GG_UINT64_C(10151977472163283085),
527 tracked_object
->exec_thread_name_hash());
528 EXPECT_EQ(177U, tracked_object
->process_id());
529 EXPECT_EQ(ProfilerEventProto::TrackedObject::BROWSER
,
530 tracked_object
->process_type());
532 tracked_object
= &log
.uma_proto().profiler_event(0).tracked_object(1);
533 EXPECT_EQ(GG_UINT64_C(2025659946535236365),
534 tracked_object
->source_file_name_hash());
535 EXPECT_EQ(GG_UINT64_C(55232426147951219),
536 tracked_object
->source_function_name_hash());
537 EXPECT_EQ(1773, tracked_object
->source_line_number());
538 EXPECT_EQ(GG_UINT64_C(1518842999910132863),
539 tracked_object
->birth_thread_name_hash());
540 EXPECT_EQ(19, tracked_object
->exec_count());
541 EXPECT_EQ(23, tracked_object
->exec_time_total());
542 EXPECT_EQ(7, tracked_object
->exec_time_sampled());
543 EXPECT_EQ(0, tracked_object
->queue_time_total());
544 EXPECT_EQ(0, tracked_object
->queue_time_sampled());
545 EXPECT_EQ(GG_UINT64_C(14275151213201158253),
546 tracked_object
->exec_thread_name_hash());
547 EXPECT_EQ(177U, tracked_object
->process_id());
548 EXPECT_EQ(ProfilerEventProto::TrackedObject::BROWSER
,
549 tracked_object
->process_type());
553 ProcessDataSnapshot process_data
;
554 process_data
.process_id
= 1177;
555 process_data
.tasks
.push_back(TaskSnapshot());
556 process_data
.tasks
.back().birth
.location
.file_name
= "file3";
557 process_data
.tasks
.back().birth
.location
.function_name
= "function3";
558 process_data
.tasks
.back().birth
.location
.line_number
= 7331;
559 process_data
.tasks
.back().birth
.thread_name
= "birth_thread3";
560 process_data
.tasks
.back().death_data
.count
= 137;
561 process_data
.tasks
.back().death_data
.run_duration_sum
= 131;
562 process_data
.tasks
.back().death_data
.run_duration_max
= 117;
563 process_data
.tasks
.back().death_data
.run_duration_sample
= 113;
564 process_data
.tasks
.back().death_data
.queue_duration_sum
= 108;
565 process_data
.tasks
.back().death_data
.queue_duration_max
= 105;
566 process_data
.tasks
.back().death_data
.queue_duration_sample
= 103;
567 process_data
.tasks
.back().death_thread_name
= "death_thread3";
569 log
.RecordProfilerData(process_data
, content::PROCESS_TYPE_RENDERER
);
570 ASSERT_EQ(1, log
.uma_proto().profiler_event_size());
571 EXPECT_EQ(ProfilerEventProto::STARTUP_PROFILE
,
572 log
.uma_proto().profiler_event(0).profile_type());
573 EXPECT_EQ(ProfilerEventProto::WALL_CLOCK_TIME
,
574 log
.uma_proto().profiler_event(0).time_source());
575 ASSERT_EQ(3, log
.uma_proto().profiler_event(0).tracked_object_size());
577 const ProfilerEventProto::TrackedObject
* tracked_object
=
578 &log
.uma_proto().profiler_event(0).tracked_object(2);
579 EXPECT_EQ(GG_UINT64_C(2686523203278102732),
580 tracked_object
->source_file_name_hash());
581 EXPECT_EQ(GG_UINT64_C(5081672290546182009),
582 tracked_object
->source_function_name_hash());
583 EXPECT_EQ(7331, tracked_object
->source_line_number());
584 EXPECT_EQ(GG_UINT64_C(1518842999910132863),
585 tracked_object
->birth_thread_name_hash());
586 EXPECT_EQ(137, tracked_object
->exec_count());
587 EXPECT_EQ(131, tracked_object
->exec_time_total());
588 EXPECT_EQ(113, tracked_object
->exec_time_sampled());
589 EXPECT_EQ(108, tracked_object
->queue_time_total());
590 EXPECT_EQ(103, tracked_object
->queue_time_sampled());
591 EXPECT_EQ(GG_UINT64_C(2203893603452504755),
592 tracked_object
->exec_thread_name_hash());
593 EXPECT_EQ(1177U, tracked_object
->process_id());
594 EXPECT_EQ(ProfilerEventProto::TrackedObject::RENDERER
,
595 tracked_object
->process_type());
599 #if defined(OS_CHROMEOS)
600 TEST_F(MetricsLogTest
, MultiProfileUserCount
) {
601 std::string
user1("user1@example.com");
602 std::string
user2("user2@example.com");
603 std::string
user3("user3@example.com");
605 // |scoped_enabler| takes over the lifetime of |user_manager|.
606 chromeos::FakeUserManager
* user_manager
= new chromeos::FakeUserManager();
607 chromeos::ScopedUserManagerEnabler
scoped_enabler(user_manager
);
608 user_manager
->AddKioskAppUser(user1
);
609 user_manager
->AddKioskAppUser(user2
);
610 user_manager
->AddKioskAppUser(user3
);
612 user_manager
->LoginUser(user1
);
613 user_manager
->LoginUser(user3
);
615 TestMetricsLog
log(kClientId
, kSessionId
);
616 std::vector
<content::WebPluginInfo
> plugins
;
617 GoogleUpdateMetrics google_update_metrics
;
618 std::vector
<chrome_variations::ActiveGroupId
> synthetic_trials
;
619 log
.RecordEnvironment(plugins
, google_update_metrics
, synthetic_trials
);
620 EXPECT_EQ(2u, log
.system_profile().multi_profile_user_count());
623 TEST_F(MetricsLogTest
, MultiProfileCountInvalidated
) {
624 std::string
user1("user1@example.com");
625 std::string
user2("user2@example.com");
626 std::string
user3("user3@example.com");
628 // |scoped_enabler| takes over the lifetime of |user_manager|.
629 chromeos::FakeUserManager
* user_manager
= new chromeos::FakeUserManager();
630 chromeos::ScopedUserManagerEnabler
scoped_enabler(user_manager
);
631 user_manager
->AddKioskAppUser(user1
);
632 user_manager
->AddKioskAppUser(user2
);
633 user_manager
->AddKioskAppUser(user3
);
635 user_manager
->LoginUser(user1
);
637 TestMetricsLog
log(kClientId
, kSessionId
);
638 EXPECT_EQ(1u, log
.system_profile().multi_profile_user_count());
640 user_manager
->LoginUser(user2
);
641 std::vector
<chrome_variations::ActiveGroupId
> synthetic_trials
;
642 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
643 GoogleUpdateMetrics(), synthetic_trials
);
644 EXPECT_EQ(0u, log
.system_profile().multi_profile_user_count());
647 TEST_F(MetricsLogTest
, BluetoothHardwareDisabled
) {
648 TestMetricsLog
log(kClientId
, kSessionId
);
649 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
650 GoogleUpdateMetrics(),
651 std::vector
<chrome_variations::ActiveGroupId
>());
653 EXPECT_TRUE(log
.system_profile().has_hardware());
654 EXPECT_TRUE(log
.system_profile().hardware().has_bluetooth());
656 EXPECT_TRUE(log
.system_profile().hardware().bluetooth().is_present());
657 EXPECT_FALSE(log
.system_profile().hardware().bluetooth().is_enabled());
660 TEST_F(MetricsLogTest
, BluetoothHardwareEnabled
) {
661 FakeBluetoothAdapterClient::Properties
* properties
=
662 fake_bluetooth_adapter_client_
->GetProperties(
663 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
664 properties
->powered
.ReplaceValue(true);
666 TestMetricsLog
log(kClientId
, kSessionId
);
667 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
668 GoogleUpdateMetrics(),
669 std::vector
<chrome_variations::ActiveGroupId
>());
671 EXPECT_TRUE(log
.system_profile().has_hardware());
672 EXPECT_TRUE(log
.system_profile().hardware().has_bluetooth());
674 EXPECT_TRUE(log
.system_profile().hardware().bluetooth().is_present());
675 EXPECT_TRUE(log
.system_profile().hardware().bluetooth().is_enabled());
678 TEST_F(MetricsLogTest
, BluetoothPairedDevices
) {
679 // The fake bluetooth adapter class already claims to be paired with one
680 // device when initialized. Add a second and third fake device to it so we
681 // can test the cases where a device is not paired (LE device, generally)
682 // and a device that does not have Device ID information.
683 fake_bluetooth_device_client_
->CreateDevice(
684 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
685 dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath
));
687 fake_bluetooth_device_client_
->CreateDevice(
688 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
689 dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath
));
691 FakeBluetoothDeviceClient::Properties
* properties
=
692 fake_bluetooth_device_client_
->GetProperties(
693 dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath
));
694 properties
->paired
.ReplaceValue(true);
696 TestMetricsLog
log(kClientId
, kSessionId
);
697 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
698 GoogleUpdateMetrics(),
699 std::vector
<chrome_variations::ActiveGroupId
>());
701 ASSERT_TRUE(log
.system_profile().has_hardware());
702 ASSERT_TRUE(log
.system_profile().hardware().has_bluetooth());
704 // Only two of the devices should appear.
706 log
.system_profile().hardware().bluetooth().paired_device_size());
708 typedef metrics::SystemProfileProto::Hardware::Bluetooth::PairedDevice
711 // First device should match the Paired Device object, complete with
712 // parsed Device ID information.
713 PairedDevice device1
=
714 log
.system_profile().hardware().bluetooth().paired_device(0);
716 EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceClass
,
717 device1
.bluetooth_class());
718 EXPECT_EQ(PairedDevice::DEVICE_COMPUTER
, device1
.type());
719 EXPECT_EQ(0x001122U
, device1
.vendor_prefix());
720 EXPECT_EQ(PairedDevice::VENDOR_ID_USB
, device1
.vendor_id_source());
721 EXPECT_EQ(0x05ACU
, device1
.vendor_id());
722 EXPECT_EQ(0x030DU
, device1
.product_id());
723 EXPECT_EQ(0x0306U
, device1
.device_id());
725 // Second device should match the Confirm Passkey object, this has
726 // no Device ID information.
727 PairedDevice device2
=
728 log
.system_profile().hardware().bluetooth().paired_device(1);
730 EXPECT_EQ(FakeBluetoothDeviceClient::kConfirmPasskeyClass
,
731 device2
.bluetooth_class());
732 EXPECT_EQ(PairedDevice::DEVICE_PHONE
, device2
.type());
733 EXPECT_EQ(0x207D74U
, device2
.vendor_prefix());
734 EXPECT_EQ(PairedDevice::VENDOR_ID_UNKNOWN
, device2
.vendor_id_source());
736 #endif // OS_CHROMEOS