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

Unified Diff: chrome/browser/chromeos/session_length_limiter.cc

Issue 11499012: Add policy for limiting the session length (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. Not sure why the patch is not applying - bot source out of sync with ToT? Created 8 years 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/session_length_limiter.cc
diff --git a/chrome/browser/chromeos/session_length_limiter.cc b/chrome/browser/chromeos/session_length_limiter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fb0d94c27f2bf3b95d53dcde766ad5c3e2dd2fa3
--- /dev/null
+++ b/chrome/browser/chromeos/session_length_limiter.cc
@@ -0,0 +1,177 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/session_length_limiter.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/prefs/public/pref_service_base.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/pref_names.h"
+
+namespace chromeos {
+
+namespace {
+
+// The minimum session time limit that can be set.
+const int kSessionLengthLimitMinMs = 30 * 1000; // 30 seconds.
+
+// The maximum session time limit that can be set.
+const int kSessionLengthLimitMaxMs = 24 * 60 * 60 * 1000; // 24 hours.
+
+// The interval at which to fire periodic callbacks and check whether the
+// session time limit has been reached.
+const int kSessionLengthLimitTimerIntervalMs = 1000;
+
+// A default delegate implementation that returns the current time and does log
+// out the current user when requested. This can be replaced with a mock in
+// tests.
+class SessionLengthLimiterDelegateImpl : public SessionLengthLimiter::Delegate {
+ public:
+ SessionLengthLimiterDelegateImpl();
+ virtual ~SessionLengthLimiterDelegateImpl();
+
+ virtual const base::Time GetCurrentTime() const;
+ virtual void Logout();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SessionLengthLimiterDelegateImpl);
+};
+
+SessionLengthLimiterDelegateImpl::SessionLengthLimiterDelegateImpl() {
+}
+
+SessionLengthLimiterDelegateImpl::~SessionLengthLimiterDelegateImpl() {
+}
+
+const base::Time SessionLengthLimiterDelegateImpl::GetCurrentTime() const {
+ return base::Time::Now();
+}
+
+void SessionLengthLimiterDelegateImpl::Logout() {
+ browser::AttemptUserExit();
+}
+
+} // namespace
+
+SessionLengthLimiter::Observer::~Observer() {
+}
+
+SessionLengthLimiter::Delegate::~Delegate() {
+}
+
+SessionLengthLimiter::SessionLengthLimiter(Delegate* delegate,
+ PrefService* prefs)
+ : delegate_(delegate ? delegate : new SessionLengthLimiterDelegateImpl) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // Update the session start time in prefs to the current time when going
+ // through a user login. If the browser is restarting after a crash instead,
+ // only update the value if it appears corrupted (value unset, value lying in
+ // the future, zero value).
+ int64 session_start_time = prefs->GetInt64(prefs::kSessionStartTime);
+ int64 now = delegate_->GetCurrentTime().ToInternalValue();
+ if (!UserManager::Get()->HasBrowserRestarted() ||
+ session_start_time <= 0 || session_start_time > now) {
+ prefs->SetInt64(prefs::kSessionStartTime, now);
+ session_start_time = now;
+ }
+ session_start_time_ = base::Time::FromInternalValue(session_start_time);
+
+ // Listen for changes to the session length limit.
+ pref_change_registrar_.Init(prefs);
+ pref_change_registrar_.Add(
+ prefs::kSessionLengthLimit,
+ base::Bind(&SessionLengthLimiter::OnSessionLengthLimitChanged,
+ base::Unretained(this)));
+ OnSessionLengthLimitChanged();
+}
+
+SessionLengthLimiter::~SessionLengthLimiter() {
+}
+
+void SessionLengthLimiter::Shutdown() {
+ pref_change_registrar_.RemoveAll();
Mattias Nissler (ping if slow) 2012/12/12 10:12:57 not needed AFAICS
bartfab (slow) 2012/12/13 16:22:48 Correct. I only did this because other PKS do it,
+}
+
+void SessionLengthLimiter::AddObserver(Observer* observer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ observers_.AddObserver(observer);
+ observer->SessionTimeRemainingChanged(GetRemainingTime().get());
+}
+
+void SessionLengthLimiter::RemoveObserver(Observer* observer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ observers_.RemoveObserver(observer);
+}
+
+void SessionLengthLimiter::OnSessionLengthLimitChanged() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ int limit;
+ const PrefServiceBase::Preference* session_length_limit_pref =
+ pref_change_registrar_.prefs()->
+ FindPreference(prefs::kSessionLengthLimit);
+ // If no session length limit is set, stop the timer, calling the observers
+ // one last time to notify them that there is no more limit.
+ if (session_length_limit_pref->IsDefaultValue() ||
+ !session_length_limit_pref->GetValue()->GetAsInteger(&limit)) {
+ session_length_limit_ = base::TimeDelta();
+ StopTimer();
+ return;
+ }
+ // If a session length limit is set, clamp it to the valid range and start
+ // the timer after calling the observers immediately to notify them that there
+ // now is a limit.
+ session_length_limit_ = base::TimeDelta::FromMilliseconds(
+ std::min(std::max(limit, kSessionLengthLimitMinMs),
+ kSessionLengthLimitMaxMs));
+ StartTimer();
+}
+
+void SessionLengthLimiter::StartTimer() {
+ TimerTick();
+ if (repeating_timer_.IsRunning())
+ return;
+ repeating_timer_.Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kSessionLengthLimitTimerIntervalMs),
+ this,
+ &SessionLengthLimiter::TimerTick);
+}
+
+void SessionLengthLimiter::StopTimer() {
+ if (repeating_timer_.IsRunning())
+ repeating_timer_.Stop();
+ TimerTick();
+}
+
+void SessionLengthLimiter::TimerTick() {
+ scoped_ptr<base::TimeDelta> remaining = GetRemainingTime();
+ FOR_EACH_OBSERVER(Observer, observers_,
+ SessionTimeRemainingChanged(remaining.get()));
+ // End the session if a limit is set and the remaining time reaches zero.
+ if (remaining && *remaining == base::TimeDelta())
+ delegate_->Logout();
+}
+
+scoped_ptr<base::TimeDelta> SessionLengthLimiter::GetRemainingTime() const {
Mattias Nissler (ping if slow) 2012/12/12 10:12:57 Wrapping in a scoped_ptr for returning an optional
bartfab (slow) 2012/12/13 16:22:48 Done.
+ // If no limit is set, return |NULL|.
+ const base::TimeDelta kZeroTimeDelta = base::TimeDelta();
+ if (session_length_limit_ == kZeroTimeDelta)
+ return scoped_ptr<base::TimeDelta>();
+ // If a limit is set, return the remaining time, clamped so that it never
+ // falls below zero.
+ base::TimeDelta remaining = session_length_limit_ -
+ (delegate_->GetCurrentTime() - session_start_time_);
+ if (remaining < kZeroTimeDelta)
+ remaining = kZeroTimeDelta;
+ return scoped_ptr<base::TimeDelta>(new base::TimeDelta(remaining));
+}
+
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698