Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: chrome/browser/sync/engine/syncer_thread.cc

Issue 553051: Add support for UserIdleTime to Linux. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 #include "chrome/browser/sync/engine/syncer_thread.h" 4 #include "chrome/browser/sync/engine/syncer_thread.h"
5 5
6 #include "build/build_config.h" 6 #include "build/build_config.h"
7 7
8 #if defined(OS_MACOSX) 8 #if defined(OS_MACOSX)
9 #include <CoreFoundation/CFNumber.h> 9 #include <CoreFoundation/CFNumber.h>
10 #include <IOKit/IOTypes.h> 10 #include <IOKit/IOTypes.h>
(...skipping 13 matching lines...) Expand all
24 #include "chrome/browser/sync/notifier/listener/talk_mediator_impl.h" 24 #include "chrome/browser/sync/notifier/listener/talk_mediator_impl.h"
25 #include "chrome/browser/sync/syncable/directory_manager.h" 25 #include "chrome/browser/sync/syncable/directory_manager.h"
26 #include "chrome/common/chrome_switches.h" 26 #include "chrome/common/chrome_switches.h"
27 27
28 using std::priority_queue; 28 using std::priority_queue;
29 using std::min; 29 using std::min;
30 using base::Time; 30 using base::Time;
31 using base::TimeDelta; 31 using base::TimeDelta;
32 using base::TimeTicks; 32 using base::TimeTicks;
33 33
34 namespace {
35
36 // Returns the amount of time since the user last interacted with the computer,
37 // in milliseconds
38 int UserIdleTime() {
39 #if defined(OS_WIN)
40 LASTINPUTINFO last_input_info;
41 last_input_info.cbSize = sizeof(LASTINPUTINFO);
42
43 // Get time in windows ticks since system start of last activity.
44 BOOL b = ::GetLastInputInfo(&last_input_info);
45 if (b == TRUE)
46 return ::GetTickCount() - last_input_info.dwTime;
47 #elif defined(OS_MACOSX)
48 // It would be great to do something like:
49 //
50 // return 1000 *
51 // CGEventSourceSecondsSinceLastEventType(
52 // kCGEventSourceStateCombinedSessionState,
53 // kCGAnyInputEventType);
54 //
55 // Unfortunately, CGEvent* lives in ApplicationServices, and we're a daemon
56 // and can't link that high up the food chain. Thus this mucking in IOKit.
57
58 io_service_t hid_service =
59 IOServiceGetMatchingService(kIOMasterPortDefault,
60 IOServiceMatching("IOHIDSystem"));
61 if (!hid_service) {
62 LOG(WARNING) << "Could not obtain IOHIDSystem";
63 return 0;
64 }
65
66 CFTypeRef object = IORegistryEntryCreateCFProperty(hid_service,
67 CFSTR("HIDIdleTime"),
68 kCFAllocatorDefault,
69 0);
70 if (!object) {
71 LOG(WARNING) << "Could not get IOHIDSystem's HIDIdleTime property";
72 IOObjectRelease(hid_service);
73 return 0;
74 }
75
76 int64 idle_time; // in nanoseconds
77 Boolean success = false;
78 if (CFGetTypeID(object) == CFNumberGetTypeID()) {
79 success = CFNumberGetValue((CFNumberRef)object,
80 kCFNumberSInt64Type,
81 &idle_time);
82 } else {
83 LOG(WARNING) << "IOHIDSystem's HIDIdleTime property isn't a number!";
84 }
85
86 CFRelease(object);
87 IOObjectRelease(hid_service);
88
89 if (!success) {
90 LOG(WARNING) << "Could not get IOHIDSystem's HIDIdleTime property's value";
91 return 0;
92 } else {
93 return idle_time / 1000000; // nano to milli
94 }
95 #else
96 static bool was_logged = false;
97 if (!was_logged) {
98 was_logged = true;
99 LOG(INFO) << "UserIdleTime unimplemented on this platform, "
100 "synchronization will not throttle when user idle";
101 }
102 #endif
103
104 return 0;
105 }
106
107 } // namespace
108 34
109 namespace browser_sync { 35 namespace browser_sync {
110 36
111 const int SyncerThread::kDefaultShortPollIntervalSeconds = 60; 37 const int SyncerThread::kDefaultShortPollIntervalSeconds = 60;
112 const int SyncerThread::kDefaultLongPollIntervalSeconds = 3600; 38 const int SyncerThread::kDefaultLongPollIntervalSeconds = 3600;
113 const int SyncerThread::kDefaultMaxPollIntervalMs = 30 * 60 * 1000; 39 const int SyncerThread::kDefaultMaxPollIntervalMs = 30 * 60 * 1000;
114 40
115 void SyncerThread::NudgeSyncer(int milliseconds_from_now, NudgeSource source) { 41 void SyncerThread::NudgeSyncer(int milliseconds_from_now, NudgeSource source) {
116 AutoLock lock(lock_); 42 AutoLock lock(lock_);
117 if (vault_.syncer_ == NULL) { 43 if (vault_.syncer_ == NULL) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 LOG(INFO) << "In thread main loop."; 179 LOG(INFO) << "In thread main loop.";
254 180
255 // Use the short poll value by default. 181 // Use the short poll value by default.
256 vault_.current_wait_interval_.poll_delta = 182 vault_.current_wait_interval_.poll_delta =
257 TimeDelta::FromSeconds(syncer_short_poll_interval_seconds_); 183 TimeDelta::FromSeconds(syncer_short_poll_interval_seconds_);
258 int user_idle_milliseconds = 0; 184 int user_idle_milliseconds = 0;
259 TimeTicks last_sync_time; 185 TimeTicks last_sync_time;
260 bool initial_sync_for_thread = true; 186 bool initial_sync_for_thread = true;
261 bool continue_sync_cycle = false; 187 bool continue_sync_cycle = false;
262 188
189 #if defined(OS_LINUX)
190 idle_query_.reset(new IdleQueryLinux());
191 #endif
192
263 while (!vault_.stop_syncer_thread_) { 193 while (!vault_.stop_syncer_thread_) {
264 // The Wait()s in these conditionals using |vault_| are not TimedWait()s (as 194 // The Wait()s in these conditionals using |vault_| are not TimedWait()s (as
265 // below) because we cannot poll until these conditions are met, so we wait 195 // below) because we cannot poll until these conditions are met, so we wait
266 // indefinitely. 196 // indefinitely.
267 if (!vault_.connected_) { 197 if (!vault_.connected_) {
268 LOG(INFO) << "Syncer thread waiting for connection."; 198 LOG(INFO) << "Syncer thread waiting for connection.";
269 while (!vault_.connected_ && !vault_.stop_syncer_thread_) 199 while (!vault_.connected_ && !vault_.stop_syncer_thread_)
270 vault_field_changed_.Wait(); 200 vault_field_changed_.Wait();
271 LOG_IF(INFO, vault_.connected_) << "Syncer thread found connection."; 201 LOG_IF(INFO, vault_.connected_) << "Syncer thread found connection.";
272 continue; 202 continue;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 LOG(INFO) << "Calling Sync Main at time " << Time::Now().ToInternalValue(); 252 LOG(INFO) << "Calling Sync Main at time " << Time::Now().ToInternalValue();
323 SyncMain(vault_.syncer_); 253 SyncMain(vault_.syncer_);
324 last_sync_time = TimeTicks::Now(); 254 last_sync_time = TimeTicks::Now();
325 255
326 LOG(INFO) << "Updating the next polling time after SyncMain"; 256 LOG(INFO) << "Updating the next polling time after SyncMain";
327 vault_.current_wait_interval_ = CalculatePollingWaitTime( 257 vault_.current_wait_interval_ = CalculatePollingWaitTime(
328 allstatus_->status(), 258 allstatus_->status(),
329 static_cast<int>(vault_.current_wait_interval_.poll_delta.InSeconds()), 259 static_cast<int>(vault_.current_wait_interval_.poll_delta.InSeconds()),
330 &user_idle_milliseconds, &continue_sync_cycle, nudged); 260 &user_idle_milliseconds, &continue_sync_cycle, nudged);
331 } 261 }
262 #if defined(OS_LINUX)
263 idle_query_.reset();
264 #endif
332 } 265 }
333 266
334 // We check how long the user's been idle and sync less often if the machine is 267 // We check how long the user's been idle and sync less often if the machine is
335 // not in use. The aim is to reduce server load. 268 // not in use. The aim is to reduce server load.
336 // TODO(timsteele): Should use Time(Delta). 269 // TODO(timsteele): Should use Time(Delta).
337 SyncerThread::WaitInterval SyncerThread::CalculatePollingWaitTime( 270 SyncerThread::WaitInterval SyncerThread::CalculatePollingWaitTime(
338 const AllStatus::Status& status, 271 const AllStatus::Status& status,
339 int last_poll_wait, // Time in seconds. 272 int last_poll_wait, // Time in seconds.
340 int* user_idle_milliseconds, 273 int* user_idle_milliseconds,
341 bool* continue_sync_cycle, 274 bool* continue_sync_cycle,
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 } 563 }
631 break; 564 break;
632 default: 565 default:
633 break; 566 break;
634 } 567 }
635 568
636 session_context_->set_notifications_enabled(p2p_authenticated_ && 569 session_context_->set_notifications_enabled(p2p_authenticated_ &&
637 p2p_subscribed_); 570 p2p_subscribed_);
638 } 571 }
639 572
573 // Returns the amount of time since the user last interacted with the computer,
574 // in milliseconds
575 int SyncerThread::UserIdleTime() {
576 #if defined(OS_WIN)
577 LASTINPUTINFO last_input_info;
578 last_input_info.cbSize = sizeof(LASTINPUTINFO);
579
580 // Get time in windows ticks since system start of last activity.
581 BOOL b = ::GetLastInputInfo(&last_input_info);
582 if (b == TRUE)
583 return ::GetTickCount() - last_input_info.dwTime;
584 #elif defined(OS_MACOSX)
585 // It would be great to do something like:
586 //
587 // return 1000 *
588 // CGEventSourceSecondsSinceLastEventType(
589 // kCGEventSourceStateCombinedSessionState,
590 // kCGAnyInputEventType);
591 //
592 // Unfortunately, CGEvent* lives in ApplicationServices, and we're a daemon
593 // and can't link that high up the food chain. Thus this mucking in IOKit.
594
595 io_service_t hid_service =
596 IOServiceGetMatchingService(kIOMasterPortDefault,
597 IOServiceMatching("IOHIDSystem"));
598 if (!hid_service) {
599 LOG(WARNING) << "Could not obtain IOHIDSystem";
600 return 0;
601 }
602
603 CFTypeRef object = IORegistryEntryCreateCFProperty(hid_service,
604 CFSTR("HIDIdleTime"),
605 kCFAllocatorDefault,
606 0);
607 if (!object) {
608 LOG(WARNING) << "Could not get IOHIDSystem's HIDIdleTime property";
609 IOObjectRelease(hid_service);
610 return 0;
611 }
612
613 int64 idle_time; // in nanoseconds
614 Boolean success = false;
615 if (CFGetTypeID(object) == CFNumberGetTypeID()) {
616 success = CFNumberGetValue((CFNumberRef)object,
617 kCFNumberSInt64Type,
618 &idle_time);
619 } else {
620 LOG(WARNING) << "IOHIDSystem's HIDIdleTime property isn't a number!";
621 }
622
623 CFRelease(object);
624 IOObjectRelease(hid_service);
625
626 if (!success) {
627 LOG(WARNING) << "Could not get IOHIDSystem's HIDIdleTime property's value";
628 return 0;
629 } else {
630 return idle_time / 1000000; // nano to milli
631 }
632 #elif defined(OS_LINUX)
633 if (idle_query_.get()) {
634 return idle_query_->IdleTime();
635 } else {
636 return 0;
637 }
638 #else
639 static bool was_logged = false;
640 if (!was_logged) {
641 was_logged = true;
642 LOG(INFO) << "UserIdleTime unimplemented on this platform, "
643 "synchronization will not throttle when user idle";
644 }
645 #endif
646
647 return 0;
648 }
649
650
640 } // namespace browser_sync 651 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698