summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/prefs/incognito_mode_prefs.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/browser/prefs/incognito_mode_prefs.cc')
-rw-r--r--chromium/chrome/browser/prefs/incognito_mode_prefs.cc236
1 files changed, 236 insertions, 0 deletions
diff --git a/chromium/chrome/browser/prefs/incognito_mode_prefs.cc b/chromium/chrome/browser/prefs/incognito_mode_prefs.cc
new file mode 100644
index 00000000000..881d7e6934a
--- /dev/null
+++ b/chromium/chrome/browser/prefs/incognito_mode_prefs.cc
@@ -0,0 +1,236 @@
+// 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/prefs/incognito_mode_prefs.h"
+
+#include <stdint.h>
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/task/post_task.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_thread.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#include <objbase.h>
+#include <wpcapi.h>
+#include <wrl/client.h>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/memory/singleton.h"
+#endif // OS_WIN
+
+#if defined(OS_ANDROID)
+#include "chrome/browser/android/partner_browser_customizations.h"
+#endif // defined(OS_ANDROID)
+
+using content::BrowserThread;
+
+#if defined(OS_WIN)
+namespace {
+
+// This singleton allows us to attempt to calculate the Platform Parental
+// Controls enabled value on a worker thread before the UI thread needs the
+// value. If the UI thread finishes sooner than we expect, that's no worse than
+// today where we block.
+class PlatformParentalControlsValue {
+ public:
+ static PlatformParentalControlsValue* GetInstance() {
+ return base::Singleton<PlatformParentalControlsValue>::get();
+ }
+
+ bool is_enabled() const {
+ return is_enabled_;
+ }
+
+ private:
+ friend struct base::DefaultSingletonTraits<PlatformParentalControlsValue>;
+
+ // Histogram enum for tracking the thread that checked parental controls.
+ enum class ThreadType {
+ UI = 0,
+ BLOCKING,
+ COUNT,
+ };
+
+ PlatformParentalControlsValue()
+ : is_enabled_(IsParentalControlActivityLoggingOn()) {}
+
+ ~PlatformParentalControlsValue() = default;
+
+ // Returns true if Windows Parental control activity logging is enabled. This
+ // feature is available on Windows 7 and beyond. This function should be
+ // called on a COM Initialized thread and is potentially blocking.
+ static bool IsParentalControlActivityLoggingOn() {
+ ThreadType thread_type = ThreadType::BLOCKING;
+ if (BrowserThread::IsThreadInitialized(BrowserThread::UI) &&
+ content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
+ thread_type = ThreadType::UI;
+ }
+
+ UMA_HISTOGRAM_ENUMERATION(
+ "IncognitoModePrefs.WindowsParentalControlsInitThread",
+ static_cast<int32_t>(thread_type),
+ static_cast<int32_t>(ThreadType::COUNT));
+
+ base::Time begin_time = base::Time::Now();
+ bool result = IsParentalControlActivityLoggingOnImpl();
+ UMA_HISTOGRAM_TIMES("IncognitoModePrefs.WindowsParentalControlsInitTime",
+ base::Time::Now() - begin_time);
+ return result;
+ }
+
+ // Does the work of determining if Windows Parental control activity logging
+ // is enabled.
+ static bool IsParentalControlActivityLoggingOnImpl() {
+ // Since we can potentially block, make sure the thread is okay with this.
+ base::ScopedBlockingCall scoped_blocking_call(
+ FROM_HERE, base::BlockingType::MAY_BLOCK);
+ Microsoft::WRL::ComPtr<IWindowsParentalControlsCore> parent_controls;
+ HRESULT hr = ::CoCreateInstance(__uuidof(WindowsParentalControls), nullptr,
+ CLSCTX_ALL, IID_PPV_ARGS(&parent_controls));
+ if (FAILED(hr))
+ return false;
+
+ Microsoft::WRL::ComPtr<IWPCSettings> settings;
+ hr = parent_controls->GetUserSettings(nullptr, settings.GetAddressOf());
+ if (FAILED(hr))
+ return false;
+
+ unsigned long restrictions = 0;
+ settings->GetRestrictions(&restrictions);
+
+ return (restrictions & WPCFLAG_LOGGING_REQUIRED) ==
+ WPCFLAG_LOGGING_REQUIRED;
+ }
+
+ const bool is_enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformParentalControlsValue);
+};
+
+} // namespace
+#endif // OS_WIN
+
+// static
+// Sadly, this is required until c++17.
+constexpr IncognitoModePrefs::Availability
+ IncognitoModePrefs::kDefaultAvailability;
+
+// static
+bool IncognitoModePrefs::IntToAvailability(int in_value,
+ Availability* out_value) {
+ if (in_value < 0 || in_value >= AVAILABILITY_NUM_TYPES) {
+ *out_value = kDefaultAvailability;
+ return false;
+ }
+ *out_value = static_cast<Availability>(in_value);
+ return true;
+}
+
+// static
+IncognitoModePrefs::Availability IncognitoModePrefs::GetAvailability(
+ const PrefService* pref_service) {
+ return GetAvailabilityInternal(pref_service, CHECK_PARENTAL_CONTROLS);
+}
+
+// static
+void IncognitoModePrefs::SetAvailability(PrefService* prefs,
+ const Availability availability) {
+ prefs->SetInteger(prefs::kIncognitoModeAvailability, availability);
+}
+
+// static
+void IncognitoModePrefs::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterIntegerPref(prefs::kIncognitoModeAvailability,
+ kDefaultAvailability);
+}
+
+// static
+bool IncognitoModePrefs::ShouldLaunchIncognito(
+ const base::CommandLine& command_line,
+ const PrefService* prefs) {
+ // Note: This code only checks parental controls if the user requested
+ // to launch in incognito mode or if it was forced via prefs. This way,
+ // the parental controls check (which can be quite slow) can be avoided
+ // most of the time.
+ const bool should_use_incognito =
+ command_line.HasSwitch(switches::kIncognito) ||
+ GetAvailabilityInternal(prefs, DONT_CHECK_PARENTAL_CONTROLS) ==
+ IncognitoModePrefs::FORCED;
+ return should_use_incognito &&
+ GetAvailabilityInternal(prefs, CHECK_PARENTAL_CONTROLS) !=
+ IncognitoModePrefs::DISABLED;
+}
+
+// static
+bool IncognitoModePrefs::CanOpenBrowser(Profile* profile) {
+ if (profile->IsGuestSession())
+ return true;
+
+ switch (GetAvailability(profile->GetPrefs())) {
+ case IncognitoModePrefs::ENABLED:
+ return true;
+
+ case IncognitoModePrefs::DISABLED:
+ return !profile->IsOffTheRecord();
+
+ case IncognitoModePrefs::FORCED:
+ return profile->IsOffTheRecord();
+
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+#if defined(OS_WIN)
+// static
+void IncognitoModePrefs::InitializePlatformParentalControls() {
+ base::CreateCOMSTATaskRunner(
+ {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE})
+ ->PostTask(FROM_HERE, base::BindOnce(base::IgnoreResult(
+ &PlatformParentalControlsValue::GetInstance)));
+}
+#endif
+
+// static
+bool IncognitoModePrefs::ArePlatformParentalControlsEnabled() {
+#if defined(OS_WIN)
+ return PlatformParentalControlsValue::GetInstance()->is_enabled();
+#elif defined(OS_ANDROID)
+ return chrome::android::PartnerBrowserCustomizations::IsIncognitoDisabled();
+#else
+ return false;
+#endif
+}
+
+// static
+IncognitoModePrefs::Availability IncognitoModePrefs::GetAvailabilityInternal(
+ const PrefService* pref_service,
+ GetAvailabilityMode mode) {
+ DCHECK(pref_service);
+ int pref_value = pref_service->GetInteger(prefs::kIncognitoModeAvailability);
+ Availability result = kDefaultAvailability;
+ bool valid = IntToAvailability(pref_value, &result);
+ DCHECK(valid);
+ if (result != IncognitoModePrefs::DISABLED &&
+ mode == CHECK_PARENTAL_CONTROLS && ArePlatformParentalControlsEnabled()) {
+ if (result == IncognitoModePrefs::FORCED)
+ LOG(ERROR) << "Ignoring FORCED incognito. Parental control logging on";
+ return IncognitoModePrefs::DISABLED;
+ }
+ return result;
+}