ExtensionSyncService: listen for relevant changes instead of being explicitly called...
[chromium-blink-merge.git] / chrome / browser / prefs / incognito_mode_prefs.cc
blobf9d0fcd880efc0d3e795402a3783858cc1aeb8f2
1 // Copyright (c) 2012 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/prefs/incognito_mode_prefs.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/metrics/histogram_macros.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/threading/thread_restrictions.h"
12 #include "base/time/time.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/pref_registry/pref_registry_syncable.h"
17 #include "content/public/browser/browser_thread.h"
19 #if defined(OS_WIN)
20 #include <windows.h>
21 #include <wpcapi.h>
22 #include "base/bind.h"
23 #include "base/bind_helpers.h"
24 #include "base/memory/singleton.h"
25 #include "base/win/scoped_comptr.h"
26 #include "base/win/windows_version.h"
27 #endif // OS_WIN
29 #if defined(OS_ANDROID)
30 #include "chrome/browser/android/chrome_application.h"
31 #endif // OS_ANDROID
33 using content::BrowserThread;
35 #if defined(OS_WIN)
36 namespace {
38 // This singleton allows us to attempt to calculate the Platform Parental
39 // Controls enabled value on a worker thread before the UI thread needs the
40 // value. If the UI thread finishes sooner than we expect, that's no worse than
41 // today where we block.
42 class PlatformParentalControlsValue {
43 public:
44 static PlatformParentalControlsValue* GetInstance() {
45 return Singleton<PlatformParentalControlsValue>::get();
48 bool is_enabled() const {
49 return is_enabled_;
52 private:
53 friend struct DefaultSingletonTraits<PlatformParentalControlsValue>;
55 // Histogram enum for tracking the thread that checked parental controls.
56 enum class ThreadType {
57 UI = 0,
58 BLOCKING,
59 COUNT,
62 PlatformParentalControlsValue()
63 : is_enabled_(IsParentalControlActivityLoggingOn()) {}
65 ~PlatformParentalControlsValue() = default;
67 // Returns true if Windows Parental control activity logging is enabled. This
68 // feature is available on Windows 7 and beyond. This function should be
69 // called on a COM Initialized thread and is potentially blocking.
70 static bool IsParentalControlActivityLoggingOn() {
71 // Since we can potentially block, make sure the thread is okay with this.
72 base::ThreadRestrictions::AssertIOAllowed();
73 base::ThreadRestrictions::AssertWaitAllowed();
75 // Query this info on Windows 7 and above.
76 if (base::win::GetVersion() < base::win::VERSION_WIN7)
77 return false;
79 ThreadType thread_type = ThreadType::BLOCKING;
80 if (BrowserThread::IsThreadInitialized(BrowserThread::UI) &&
81 content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
82 thread_type = ThreadType::UI;
85 UMA_HISTOGRAM_ENUMERATION(
86 "IncognitoModePrefs.WindowsParentalControlsInitThread",
87 static_cast<int32_t>(thread_type),
88 static_cast<int32_t>(ThreadType::COUNT));
90 base::Time begin_time = base::Time::Now();
91 bool result = IsParentalControlActivityLoggingOnImpl();
92 UMA_HISTOGRAM_TIMES("IncognitoModePrefs.WindowsParentalControlsInitTime",
93 base::Time::Now() - begin_time);
94 return result;
97 // Does the work of determining if Windows Parental control activity logging
98 // is enabled.
99 static bool IsParentalControlActivityLoggingOnImpl() {
100 base::win::ScopedComPtr<IWindowsParentalControlsCore> parent_controls;
101 HRESULT hr = parent_controls.CreateInstance(
102 __uuidof(WindowsParentalControls));
103 if (FAILED(hr))
104 return false;
106 base::win::ScopedComPtr<IWPCSettings> settings;
107 hr = parent_controls->GetUserSettings(nullptr, settings.Receive());
108 if (FAILED(hr))
109 return false;
111 unsigned long restrictions = 0;
112 settings->GetRestrictions(&restrictions);
114 return (restrictions & WPCFLAG_LOGGING_REQUIRED) ==
115 WPCFLAG_LOGGING_REQUIRED;
118 const bool is_enabled_;
120 DISALLOW_COPY_AND_ASSIGN(PlatformParentalControlsValue);
123 } // namespace
124 #endif // OS_WIN
126 // static
127 bool IncognitoModePrefs::IntToAvailability(int in_value,
128 Availability* out_value) {
129 if (in_value < 0 || in_value >= AVAILABILITY_NUM_TYPES) {
130 *out_value = ENABLED;
131 return false;
133 *out_value = static_cast<Availability>(in_value);
134 return true;
137 // static
138 IncognitoModePrefs::Availability IncognitoModePrefs::GetAvailability(
139 const PrefService* pref_service) {
140 DCHECK(pref_service);
141 int pref_value = pref_service->GetInteger(prefs::kIncognitoModeAvailability);
142 Availability result = IncognitoModePrefs::ENABLED;
143 bool valid = IntToAvailability(pref_value, &result);
144 DCHECK(valid);
145 if (ArePlatformParentalControlsEnabled()) {
146 if (result == IncognitoModePrefs::FORCED)
147 LOG(ERROR) << "Ignoring FORCED incognito. Parental control logging on";
148 return IncognitoModePrefs::DISABLED;
150 return result;
153 // static
154 void IncognitoModePrefs::SetAvailability(PrefService* prefs,
155 const Availability availability) {
156 prefs->SetInteger(prefs::kIncognitoModeAvailability, availability);
159 // static
160 void IncognitoModePrefs::RegisterProfilePrefs(
161 user_prefs::PrefRegistrySyncable* registry) {
162 registry->RegisterIntegerPref(prefs::kIncognitoModeAvailability,
163 IncognitoModePrefs::ENABLED);
166 // static
167 bool IncognitoModePrefs::ShouldLaunchIncognito(
168 const base::CommandLine& command_line,
169 const PrefService* prefs) {
170 Availability incognito_avail = GetAvailability(prefs);
171 return incognito_avail != IncognitoModePrefs::DISABLED &&
172 (command_line.HasSwitch(switches::kIncognito) ||
173 incognito_avail == IncognitoModePrefs::FORCED);
176 // static
177 bool IncognitoModePrefs::CanOpenBrowser(Profile* profile) {
178 if (profile->IsGuestSession())
179 return true;
181 switch (GetAvailability(profile->GetPrefs())) {
182 case IncognitoModePrefs::ENABLED:
183 return true;
185 case IncognitoModePrefs::DISABLED:
186 return !profile->IsOffTheRecord();
188 case IncognitoModePrefs::FORCED:
189 return profile->IsOffTheRecord();
191 default:
192 NOTREACHED();
193 return false;
197 #if defined(OS_WIN)
198 // static
199 void IncognitoModePrefs::InitializePlatformParentalControls() {
200 content::BrowserThread::PostBlockingPoolTask(
201 FROM_HERE,
202 base::Bind(
203 base::IgnoreResult(&PlatformParentalControlsValue::GetInstance)));
205 #endif
207 // static
208 bool IncognitoModePrefs::ArePlatformParentalControlsEnabled() {
209 #if defined(OS_WIN)
210 return PlatformParentalControlsValue::GetInstance()->is_enabled();
211 #elif defined(OS_ANDROID)
212 return chrome::android::ChromeApplication::AreParentalControlsEnabled();
213 #else
214 return false;
215 #endif