Upload upstream chromium 94.0.4606.31
[platform/framework/web/chromium-efl.git] / ash / policy / policy_recommendation_restorer.cc
1 // Copyright 2018 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.
4
5 #include "ash/policy/policy_recommendation_restorer.h"
6
7 #include "ash/session/session_controller_impl.h"
8 #include "ash/shell.h"
9 #include "base/bind.h"
10 #include "base/check.h"
11 #include "base/containers/contains.h"
12 #include "base/notreached.h"
13 #include "components/prefs/pref_change_registrar.h"
14 #include "components/prefs/pref_service.h"
15 #include "ui/base/user_activity/user_activity_detector.h"
16
17 namespace ash {
18
19 namespace {
20
21 // The amount of idle time after which recommended values are restored.
22 constexpr base::TimeDelta kRestoreDelayInMinutes =
23     base::TimeDelta::FromMinutes(1);
24
25 }  // namespace
26
27 PolicyRecommendationRestorer::PolicyRecommendationRestorer() {
28   Shell::Get()->session_controller()->AddObserver(this);
29 }
30
31 PolicyRecommendationRestorer::~PolicyRecommendationRestorer() {
32   StopTimer();
33   Shell::Get()->session_controller()->RemoveObserver(this);
34 }
35
36 void PolicyRecommendationRestorer::ObservePref(const std::string& pref_name) {
37   PrefService* prefs =
38       Shell::Get()->session_controller()->GetSigninScreenPrefService();
39   DCHECK(prefs);
40   DCHECK(!base::Contains(pref_names_, pref_name));
41
42   if (!pref_change_registrar_) {
43     pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
44     pref_change_registrar_->Init(prefs);
45   }
46
47   pref_change_registrar_->Add(
48       pref_name, base::BindRepeating(&PolicyRecommendationRestorer::Restore,
49                                      base::Unretained(this), true));
50   pref_names_.insert(pref_name);
51   Restore(false /* allow_delay */, pref_name);
52 }
53
54 void PolicyRecommendationRestorer::OnActiveUserPrefServiceChanged(
55     PrefService* pref_service) {
56   active_user_pref_connected_ = true;
57   StopTimer();
58   RestoreAll();
59 }
60
61 void PolicyRecommendationRestorer::OnUserActivity(const ui::Event* event) {
62   if (restore_timer_.IsRunning())
63     restore_timer_.Reset();
64 }
65
66 void PolicyRecommendationRestorer::DisableForTesting() {
67   disabled_for_testing_ = true;
68 }
69
70 void PolicyRecommendationRestorer::Restore(bool allow_delay,
71                                            const std::string& pref_name) {
72   const PrefService::Preference* pref =
73       pref_change_registrar_->prefs()->FindPreference(pref_name);
74   if (!pref) {
75     NOTREACHED();
76     return;
77   }
78
79   if (!pref->GetRecommendedValue() || !pref->HasUserSetting())
80     return;
81
82   if (active_user_pref_connected_) {
83     allow_delay = false;
84   } else if (allow_delay) {
85     // Skip the delay if there has been no user input since |pref_name| is
86     // started observing recommended value.
87     const ui::UserActivityDetector* user_activity_detector =
88         ui::UserActivityDetector::Get();
89     if (user_activity_detector &&
90         user_activity_detector->last_activity_time().is_null()) {
91       allow_delay = false;
92     }
93   }
94
95   if (allow_delay)
96     StartTimer();
97   else if (!disabled_for_testing_)
98     pref_change_registrar_->prefs()->ClearPref(pref->name());
99 }
100
101 void PolicyRecommendationRestorer::RestoreAll() {
102   for (const auto& pref_name : pref_names_)
103     Restore(false, pref_name);
104 }
105
106 void PolicyRecommendationRestorer::StartTimer() {
107   // Listen for user activity so that the timer can be reset while the user is
108   // active, causing it to fire only when the user remains idle for
109   // |kRestoreDelayInMinutes|.
110   ui::UserActivityDetector* user_activity_detector =
111       ui::UserActivityDetector::Get();
112   if (user_activity_detector && !user_activity_detector->HasObserver(this))
113     user_activity_detector->AddObserver(this);
114
115   // There should be a separate timer for each pref. However, in the common
116   // case of the user changing settings, a single timer is sufficient. This is
117   // because a change initiated by the user implies user activity, so that even
118   // if there was a separate timer per pref, they would all be reset at that
119   // point, causing them to fire at exactly the same time. In the much rarer
120   // case of a recommended value changing, a single timer is a close
121   // approximation of the behavior that would be obtained by resetting the timer
122   // for the affected pref only.
123   restore_timer_.Start(FROM_HERE, kRestoreDelayInMinutes,
124                        base::BindOnce(&PolicyRecommendationRestorer::RestoreAll,
125                                       base::Unretained(this)));
126 }
127
128 void PolicyRecommendationRestorer::StopTimer() {
129   restore_timer_.Stop();
130   if (ui::UserActivityDetector::Get())
131     ui::UserActivityDetector::Get()->RemoveObserver(this);
132 }
133
134 }  // namespace ash