1 // Copyright 2015 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/chromeos/system/system_clock.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/prefs/pref_change_registrar.h"
10 #include "base/prefs/pref_service.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
13 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
14 #include "chrome/browser/chromeos/profiles/profile_helper.h"
15 #include "chrome/browser/chromeos/settings/cros_settings.h"
16 #include "chrome/browser/chromeos/system/system_clock_observer.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/common/pref_names.h"
20 #include "chromeos/login/login_state.h"
21 #include "chromeos/settings/cros_settings_names.h"
22 #include "components/user_manager/user.h"
23 #include "components/user_manager/user_manager.h"
24 #include "content/public/browser/notification_service.h"
31 void SetShouldUse24HourClock(bool use_24_hour_clock
) {
32 user_manager::User
* const user
=
33 user_manager::UserManager::Get()->GetActiveUser();
35 Profile
* const profile
= ProfileHelper::Get()->GetProfileByUser(user
);
37 return; // May occur in tests or if not running on a device.
38 OwnerSettingsServiceChromeOS
* const service
=
39 OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(profile
);
41 service
->SetBoolean(kSystemUse24HourClock
, use_24_hour_clock
);
44 } // anonymous namespace
46 SystemClock::SystemClock()
47 : user_pod_was_focused_(false),
48 last_focused_pod_hour_clock_type_(base::k12HourClock
),
50 device_settings_observer_(CrosSettings::Get()->AddSettingsObserver(
51 kSystemUse24HourClock
,
52 base::Bind(&SystemClock::OnSystemPrefChanged
,
53 base::Unretained(this)))) {
54 if (LoginState::IsInitialized())
55 LoginState::Get()->AddObserver(this);
56 // Register notifications on construction so that events such as
57 // PROFILE_CREATED do not get missed if they happen before Initialize().
58 registrar_
.reset(new content::NotificationRegistrar
);
59 if (!LoginState::IsInitialized() ||
60 LoginState::Get()->GetLoggedInUserType() ==
61 LoginState::LOGGED_IN_USER_NONE
) {
62 registrar_
->Add(this, chrome::NOTIFICATION_SESSION_STARTED
,
63 content::NotificationService::AllSources());
65 registrar_
->Add(this, chrome::NOTIFICATION_PROFILE_CREATED
,
66 content::NotificationService::AllSources());
67 registrar_
->Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED
,
68 content::NotificationService::AllSources());
69 registrar_
->Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
,
70 content::NotificationService::AllSources());
71 user_manager::UserManager::Get()->AddSessionStateObserver(this);
74 SystemClock::~SystemClock() {
76 device_settings_observer_
.reset();
77 if (LoginState::IsInitialized())
78 LoginState::Get()->RemoveObserver(this);
79 if (user_manager::UserManager::IsInitialized())
80 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
83 // LoginState::Observer overrides.
84 void SystemClock::LoggedInStateChanged() {
85 // It apparently sometimes takes a while after login before the current user
86 // is recognized as the owner. Make sure that the system-wide clock setting
87 // is updated when the recognition eventually happens (crbug.com/278601).
88 if (user_manager::UserManager::Get()->IsCurrentUserOwner())
89 SetShouldUse24HourClock(ShouldUse24HourClock());
92 // content::NotificationObserver implementation.
93 void SystemClock::Observe(int type
,
94 const content::NotificationSource
& source
,
95 const content::NotificationDetails
& details
) {
97 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED
: {
101 case chrome::NOTIFICATION_PROFILE_CREATED
: {
102 OnActiveProfileChanged(content::Source
<Profile
>(source
).ptr());
103 registrar_
->Remove(this, chrome::NOTIFICATION_PROFILE_CREATED
,
104 content::NotificationService::AllSources());
107 case chrome::NOTIFICATION_PROFILE_DESTROYED
: {
108 if (OnProfileDestroyed(content::Source
<Profile
>(source
).ptr())) {
109 registrar_
->Remove(this, chrome::NOTIFICATION_PROFILE_DESTROYED
,
110 content::NotificationService::AllSources());
114 case chrome::NOTIFICATION_SESSION_STARTED
: {
115 OnActiveProfileChanged(ProfileManager::GetActiveUserProfile());
123 void SystemClock::ActiveUserChanged(const user_manager::User
* /*user*/) {
127 void SystemClock::AddObserver(SystemClockObserver
* observer
) {
128 observer_list_
.AddObserver(observer
);
131 void SystemClock::RemoveObserver(SystemClockObserver
* observer
) {
132 observer_list_
.RemoveObserver(observer
);
135 void SystemClock::OnActiveProfileChanged(Profile
* profile
) {
136 user_profile_
= profile
;
137 PrefService
* prefs
= profile
->GetPrefs();
138 user_pref_registrar_
.reset(new PrefChangeRegistrar
);
139 user_pref_registrar_
->Init(prefs
);
140 user_pref_registrar_
->Add(
141 prefs::kUse24HourClock
,
142 base::Bind(&SystemClock::UpdateClockType
, base::Unretained(this)));
145 bool SystemClock::OnProfileDestroyed(Profile
* profile
) {
146 if (profile
!= user_profile_
)
148 user_pref_registrar_
.reset();
149 user_profile_
= NULL
;
153 void SystemClock::SetLastFocusedPodHourClockType(
154 base::HourClockType hour_clock_type
) {
155 user_pod_was_focused_
= true;
156 last_focused_pod_hour_clock_type_
= hour_clock_type
;
160 bool SystemClock::ShouldUse24HourClock() const {
161 // On login screen and in guest mode owner default is used for
162 // kUse24HourClock preference.
163 const chromeos::LoginState::LoggedInUserType status
=
164 LoginState::IsInitialized() ? LoginState::Get()->GetLoggedInUserType()
165 : LoginState::LOGGED_IN_USER_NONE
;
167 if (status
== LoginState::LOGGED_IN_USER_NONE
&& user_pod_was_focused_
)
168 return last_focused_pod_hour_clock_type_
== base::k24HourClock
;
170 const CrosSettings
* const cros_settings
= CrosSettings::Get();
171 bool system_use_24_hour_clock
= true;
172 const bool system_value_found
= cros_settings
->GetBoolean(
173 kSystemUse24HourClock
, &system_use_24_hour_clock
);
175 if ((status
== LoginState::LOGGED_IN_USER_NONE
) || !user_pref_registrar_
) {
176 return (system_value_found
177 ? system_use_24_hour_clock
178 : (base::GetHourClockType() == base::k24HourClock
));
181 const PrefService::Preference
* user_pref
=
182 user_pref_registrar_
->prefs()->FindPreference(prefs::kUse24HourClock
);
183 if (status
== LoginState::LOGGED_IN_USER_GUEST
&&
184 user_pref
->IsDefaultValue()) {
185 return (system_value_found
186 ? system_use_24_hour_clock
187 : (base::GetHourClockType() == base::k24HourClock
));
190 user_manager::User
* active_user
=
191 user_manager::UserManager::Get()->GetActiveUser();
193 Profile
* user_profile
= ProfileHelper::Get()->GetProfileByUser(active_user
);
196 user_profile
->GetPrefs()->FindPreference(prefs::kUse24HourClock
);
200 bool use_24_hour_clock
= true;
201 user_pref
->GetValue()->GetAsBoolean(&use_24_hour_clock
);
202 return use_24_hour_clock
;
205 void SystemClock::OnSystemPrefChanged() {
209 void SystemClock::UpdateClockType() {
210 // This also works for enterprise-managed devices because they never have
212 if (user_manager::UserManager::Get()->IsCurrentUserOwner())
213 SetShouldUse24HourClock(ShouldUse24HourClock());
214 FOR_EACH_OBSERVER(SystemClockObserver
, observer_list_
,
215 OnSystemClockChanged(this));
218 } // namespace system
219 } // namespace chromeos