Commit 72fe84a8 authored by Eric Orth's avatar Eric Orth Committed by Commit Bot

Generalize Windows parental controls lookup logic

Take the Windows parental controls logic in IncognitoModePrefs and
generalize it for use by other code in chrome/browser.  Move it to its
own file in chrome/browser/win, and allow checking some additional
properties besides just logging_required.

Additional minor changes to the moved logic:
*Remove expired histograms.
*Convert banned ComPtr::GetAddressOf() to operator&.

Bug: 1037961
Change-Id: I31a247a0f571177507ea561002dea6c67bd749b9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2090032
Commit-Queue: Eric Orth <ericorth@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747875}
parent caec9a07
...@@ -3986,6 +3986,8 @@ jumbo_static_library("browser") { ...@@ -3986,6 +3986,8 @@ jumbo_static_library("browser") {
"sync/roaming_profile_directory_deleter_win.h", "sync/roaming_profile_directory_deleter_win.h",
"taskbar/taskbar_decorator_win.cc", "taskbar/taskbar_decorator_win.cc",
"taskbar/taskbar_decorator_win.h", "taskbar/taskbar_decorator_win.h",
"win/parental_controls.cc",
"win/parental_controls.h",
"win/util_win_service.cc", "win/util_win_service.cc",
"win/util_win_service.h", "win/util_win_service.h",
] ]
......
...@@ -76,7 +76,6 @@ ...@@ -76,7 +76,6 @@
#include "chrome/browser/policy/chrome_browser_policy_connector.h" #include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/browser/prefs/chrome_command_line_pref_store.h" #include "chrome/browser/prefs/chrome_command_line_pref_store.h"
#include "chrome/browser/prefs/chrome_pref_service_factory.h" #include "chrome/browser/prefs/chrome_pref_service_factory.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/prefs/pref_metrics_service.h" #include "chrome/browser/prefs/pref_metrics_service.h"
#include "chrome/browser/process_singleton.h" #include "chrome/browser/process_singleton.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -242,6 +241,7 @@ ...@@ -242,6 +241,7 @@
#include "chrome/browser/web_applications/components/web_app_file_handler_registration_win.h" #include "chrome/browser/web_applications/components/web_app_file_handler_registration_win.h"
#include "chrome/browser/win/browser_util.h" #include "chrome/browser/win/browser_util.h"
#include "chrome/browser/win/chrome_select_file_dialog_factory.h" #include "chrome/browser/win/chrome_select_file_dialog_factory.h"
#include "chrome/browser/win/parental_controls.h"
#include "chrome/install_static/install_util.h" #include "chrome/install_static/install_util.h"
#include "ui/shell_dialogs/select_file_dialog.h" #include "ui/shell_dialogs/select_file_dialog.h"
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
...@@ -1158,7 +1158,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { ...@@ -1158,7 +1158,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
#if defined(OS_WIN) #if defined(OS_WIN)
// Windows parental controls calls can be slow, so we do an early init here // Windows parental controls calls can be slow, so we do an early init here
// that calculates this value off of the UI thread. // that calculates this value off of the UI thread.
IncognitoModePrefs::InitializePlatformParentalControls(); InitializeWinParentalControls();
#endif #endif
// Now that the file thread has been started, start metrics. // Now that the file thread has been started, start metrics.
......
...@@ -8,122 +8,21 @@ ...@@ -8,122 +8,21 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/time/time.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h" #include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#if defined(OS_WIN) #if defined(OS_WIN)
#include <windows.h> #include "chrome/browser/win/parental_controls.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 #endif // OS_WIN
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "chrome/browser/android/partner_browser_customizations.h" #include "chrome/browser/android/partner_browser_customizations.h"
#endif // defined(OS_ANDROID) #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 // static
// Sadly, this is required until c++17. // Sadly, this is required until c++17.
constexpr IncognitoModePrefs::Availability constexpr IncognitoModePrefs::Availability
...@@ -197,20 +96,10 @@ bool IncognitoModePrefs::CanOpenBrowser(Profile* profile) { ...@@ -197,20 +96,10 @@ bool IncognitoModePrefs::CanOpenBrowser(Profile* profile) {
} }
} }
#if defined(OS_WIN)
// static
void IncognitoModePrefs::InitializePlatformParentalControls() {
base::ThreadPool::CreateCOMSTATaskRunner(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE})
->PostTask(FROM_HERE, base::BindOnce(base::IgnoreResult(
&PlatformParentalControlsValue::GetInstance)));
}
#endif
// static // static
bool IncognitoModePrefs::ArePlatformParentalControlsEnabled() { bool IncognitoModePrefs::ArePlatformParentalControlsEnabled() {
#if defined(OS_WIN) #if defined(OS_WIN)
return PlatformParentalControlsValue::GetInstance()->is_enabled(); return GetWinParentalControls().logging_required;
#elif defined(OS_ANDROID) #elif defined(OS_ANDROID)
return chrome::android::PartnerBrowserCustomizations::IsIncognitoDisabled(); return chrome::android::PartnerBrowserCustomizations::IsIncognitoDisabled();
#else #else
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
#include "build/build_config.h"
class PrefService; class PrefService;
class Profile; class Profile;
...@@ -67,12 +66,6 @@ class IncognitoModePrefs { ...@@ -67,12 +66,6 @@ class IncognitoModePrefs {
// open new windows. // open new windows.
static bool CanOpenBrowser(Profile* profile); static bool CanOpenBrowser(Profile* profile);
#if defined(OS_WIN)
// Calculates and caches the platform parental controls enable value on a
// worker thread.
static void InitializePlatformParentalControls();
#endif
// Returns whether parental controls have been enabled on the platform. This // Returns whether parental controls have been enabled on the platform. This
// method evaluates and caches if the platform controls have been enabled on // method evaluates and caches if the platform controls have been enabled on
// the first call, which must be on the UI thread when IO and blocking are // the first call, which must be on the UI thread when IO and blocking are
......
// Copyright 2020 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/win/parental_controls.h"
#include <combaseapi.h>
#include <windows.h>
#include <winerror.h>
#include <wpcapi.h>
#include <wrl/client.h>
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/singleton.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/threading/scoped_blocking_call.h"
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 WinParentalControlsValue {
public:
static WinParentalControlsValue* GetInstance() {
return base::Singleton<WinParentalControlsValue>::get();
}
const WinParentalControls& parental_controls() const {
return parental_controls_;
}
private:
friend struct base::DefaultSingletonTraits<WinParentalControlsValue>;
// Histogram enum for tracking the thread that checked parental controls.
enum class ThreadType {
UI = 0,
BLOCKING,
COUNT,
};
WinParentalControlsValue() : parental_controls_(GetParentalControls()) {}
~WinParentalControlsValue() = default;
WinParentalControlsValue(const WinParentalControlsValue&) = delete;
WinParentalControlsValue& operator=(const WinParentalControlsValue&) = delete;
// Returns the Windows Parental control enablements. This feature is available
// on Windows 7 and beyond. This function should be called on a COM
// Initialized thread and is potentially blocking.
static WinParentalControls GetParentalControls() {
// 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 WinParentalControls();
Microsoft::WRL::ComPtr<IWPCSettings> settings;
hr = parent_controls->GetUserSettings(nullptr, &settings);
if (FAILED(hr))
return WinParentalControls();
DWORD restrictions = 0;
settings->GetRestrictions(&restrictions);
WinParentalControls controls = {
restrictions != WPCFLAG_NO_RESTRICTION /* any_restrictions */,
(restrictions & WPCFLAG_LOGGING_REQUIRED) == WPCFLAG_LOGGING_REQUIRED
/* logging_required */,
(restrictions & WPCFLAG_WEB_FILTERED) == WPCFLAG_WEB_FILTERED
/* web_filter */
};
return controls;
}
const WinParentalControls parental_controls_;
};
} // namespace
void InitializeWinParentalControls() {
base::ThreadPool::CreateCOMSTATaskRunner(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE})
->PostTask(FROM_HERE, base::BindOnce(base::IgnoreResult(
&WinParentalControlsValue::GetInstance)));
}
const WinParentalControls& GetWinParentalControls() {
return WinParentalControlsValue::GetInstance()->parental_controls();
}
// Copyright 2020 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.
#ifndef CHROME_BROWSER_WIN_PARENTAL_CONTROLS_H_
#define CHROME_BROWSER_WIN_PARENTAL_CONTROLS_H_
#include "base/compiler_specific.h"
struct WinParentalControls {
bool any_restrictions = false;
bool logging_required = false;
bool web_filter = false;
};
// Calculates and caches the platform parental controls on a worker thread.
void InitializeWinParentalControls();
// Returns a struct of enabled parental controls. This method evaluates and
// caches if the platform controls have been enabled on the first call, which
// requires a thread supporting blocking. Subsequent calls may be from any
// thread.
const WinParentalControls& GetWinParentalControls() WARN_UNUSED_RESULT;
#endif // CHROME_BROWSER_WIN_PARENTAL_CONTROLS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment