1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2013 The Chromium Authors. All rights reserved.
2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file.
4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
5864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "chrome/browser/chromeos/policy/recommendation_restorer.h"
6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "ash/shell.h"
8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "base/bind.h"
9864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "base/bind_helpers.h"
10864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "base/location.h"
11864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "base/logging.h"
12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "base/prefs/pref_service.h"
13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "base/time/time.h"
14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "base/values.h"
15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "chrome/browser/chrome_notification_types.h"
16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "chrome/browser/chromeos/profiles/profile_helper.h"
17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "chrome/browser/profiles/profile.h"
18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "chrome/common/pref_names.h"
19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "content/public/browser/notification_details.h"
20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "content/public/browser/notification_service.h"
21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "content/public/browser/notification_source.h"
22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include "ui/wm/core/user_activity_detector.h"
23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace policy {
25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace {
27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The amount of idle time after which recommended values are restored.
28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst int kRestoreDelayInMs = 60 * 1000;  // 1 minute.
29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}  // namespace
30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgRecommendationRestorer::RecommendationRestorer(Profile* profile)
32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    : logged_in_(false) {
33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (!chromeos::ProfileHelper::IsSigninProfile(profile))
34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return;
35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  pref_change_registrar_.Init(profile->GetPrefs());
37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  pref_change_registrar_.Add(
38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      prefs::kAccessibilityLargeCursorEnabled,
39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      base::Bind(
40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          &RecommendationRestorer::Restore, base::Unretained(this), true));
419aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  pref_change_registrar_.Add(
425de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org      prefs::kAccessibilitySpokenFeedbackEnabled,
43196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      base::Bind(
44196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          &RecommendationRestorer::Restore, base::Unretained(this), true));
45196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  pref_change_registrar_.Add(
46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      prefs::kAccessibilityHighContrastEnabled,
47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      base::Bind(
48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          &RecommendationRestorer::Restore, base::Unretained(this), true));
49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  pref_change_registrar_.Add(
50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      prefs::kAccessibilityScreenMagnifierEnabled,
51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      base::Bind(
52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          &RecommendationRestorer::Restore, base::Unretained(this), true));
53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  pref_change_registrar_.Add(
545de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org      prefs::kAccessibilityScreenMagnifierType,
55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      base::Bind(
56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          &RecommendationRestorer::Restore, base::Unretained(this), true));
57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  pref_change_registrar_.Add(
58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      prefs::kAccessibilityVirtualKeyboardEnabled,
59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      base::Bind(
60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          &RecommendationRestorer::Restore, base::Unretained(this), true));
61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  notification_registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_CHANGED,
63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                              content::NotificationService::AllSources());
64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  RestoreAll();
66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgRecommendationRestorer::~RecommendationRestorer() {
69e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid RecommendationRestorer::Shutdown() {
72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  StopTimer();
73e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  pref_change_registrar_.RemoveAll();
74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  notification_registrar_.RemoveAll();
75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
76e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid RecommendationRestorer::Observe(
78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    int type,
79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    const content::NotificationSource& source,
80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    const content::NotificationDetails& details) {
81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    logged_in_ = true;
83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    notification_registrar_.RemoveAll();
84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    StopTimer();
85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    RestoreAll();
86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  } else {
87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    NOTREACHED();
88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid RecommendationRestorer::OnUserActivity(const ui::Event* event) {
92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (restore_timer_.IsRunning())
93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    restore_timer_.Reset();
94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid RecommendationRestorer::Restore(bool allow_delay,
97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                     const std::string& pref_name) {
98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const PrefService::Preference* pref =
99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      pref_change_registrar_.prefs()->FindPreference(pref_name.c_str());
100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (!pref) {
101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    NOTREACHED();
102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return;
103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (!pref->GetRecommendedValue() || !pref->HasUserSetting())
106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return;
107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (logged_in_) {
109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    allow_delay = false;
110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  } else if (allow_delay && ash::Shell::HasInstance()) {
111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // Skip the delay if there has been no user input since the browser started.
1125de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org    const wm::UserActivityDetector* user_activity_detector =
113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        ash::Shell::GetInstance()->user_activity_detector();
114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    allow_delay = !user_activity_detector->last_activity_time().is_null();
115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (allow_delay)
118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    StartTimer();
119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  else
120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    pref_change_registrar_.prefs()->ClearPref(pref->name().c_str());
121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid RecommendationRestorer::RestoreAll() {
124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Restore(false, prefs::kAccessibilityLargeCursorEnabled);
125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Restore(false, prefs::kAccessibilitySpokenFeedbackEnabled);
126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Restore(false, prefs::kAccessibilityHighContrastEnabled);
127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Restore(false, prefs::kAccessibilityScreenMagnifierEnabled);
128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Restore(false, prefs::kAccessibilityScreenMagnifierType);
129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Restore(false, prefs::kAccessibilityVirtualKeyboardEnabled);
130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid RecommendationRestorer::StartTimer() {
133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Listen for user activity so that the timer can be reset while the user is
134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // active, causing it to fire only when the user remains idle for
135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // |kRestoreDelayInMs|.
136e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (ash::Shell::HasInstance()) {
137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    wm::UserActivityDetector* user_activity_detector =
138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        ash::Shell::GetInstance()->user_activity_detector();
139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    if (!user_activity_detector->HasObserver(this))
140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      user_activity_detector->AddObserver(this);
141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // There should be a separate timer for each pref. However, in the common
144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // case of the user changing settings, a single timer is sufficient. This is
145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // because a change initiated by the user implies user activity, so that even
146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // if there was a separate timer per pref, they would all be reset at that
147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // point, causing them to fire at exactly the same time. In the much rarer
148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // case of a recommended value changing, a single timer is a close
149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // approximation of the behavior that would be obtained by resetting the timer
150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // for the affected pref only.
151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  restore_timer_.Start(FROM_HERE,
152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                       base::TimeDelta::FromMilliseconds(kRestoreDelayInMs),
153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                       base::Bind(&RecommendationRestorer::RestoreAll,
154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                  base::Unretained(this)));
155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid RecommendationRestorer::StopTimer() {
158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  restore_timer_.Stop();
159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (ash::Shell::HasInstance())
160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this);
161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}  // namespace policy
164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org