#ifndef CHROME_UPDATER_POLICY_SERVICE_H_
#define CHROME_UPDATER_POLICY_SERVICE_H_
#include <optional>
#include <set>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/updater/event_history.h"
#include "chrome/updater/external_constants.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/policy/manager.h"
namespace policy {
enum class PolicyFetchReason;
}
namespace updater {
class PolicyFetcher;
template <typename T>
class PolicyStatus {
public:
struct Entry {
Entry(const std::string& s, T p) : source(s), policy(p) {}
std::string source;
T policy{};
};
PolicyStatus() = default;
PolicyStatus(const PolicyStatus&) = default;
PolicyStatus& operator=(const PolicyStatus&) = default;
void AddPolicy(bool is_managed, const std::string& source, const T& policy) {
all_policies_.emplace_back(source, policy);
if (conflict_policy_) {
return;
}
if (!effective_policy_ && is_managed) {
effective_policy_ = std::make_optional<Entry>(source, policy);
} else if (effective_policy_ &&
policy != effective_policy_.value().policy) {
conflict_policy_ = std::make_optional<Entry>(source, policy);
}
}
const std::optional<Entry>& effective_policy() const {
return effective_policy_;
}
const std::optional<Entry>& conflict_policy() const {
return conflict_policy_;
}
const std::vector<Entry>& all_policies() const { return all_policies_; }
std::optional<T> effective_policy_value() const {
return effective_policy_ ? std::optional<T>(effective_policy_->policy)
: std::nullopt;
}
explicit operator bool() const { return effective_policy_.has_value(); }
const T& policy() const {
CHECK(effective_policy_);
return effective_policy_->policy;
}
const T& policy_or(const T& fallback) const {
return effective_policy_ ? policy() : fallback;
}
private:
std::optional<Entry> effective_policy_;
std::optional<Entry> conflict_policy_;
std::vector<Entry> all_policies_;
};
class PolicyService : public base::RefCountedThreadSafe<PolicyService> {
public:
class PolicyManagers {
public:
explicit PolicyManagers(
scoped_refptr<ExternalConstants> external_constants);
~PolicyManagers();
void ResetDeviceManagementManager(
scoped_refptr<PolicyManagerInterface> dm_manager);
std::vector<scoped_refptr<PolicyManagerInterface>> managers() const {
return managers_;
}
void SetManagersForTesting(
std::vector<scoped_refptr<PolicyManagerInterface>> managers);
private:
void CreateManagers(scoped_refptr<ExternalConstants> external_constants);
void InitializeManagersVector();
void SortManagersVector();
static bool CloudPolicyOverridesPlatformPolicy(
const std::vector<scoped_refptr<PolicyManagerInterface>>& providers);
std::vector<scoped_refptr<PolicyManagerInterface>> managers_;
scoped_refptr<PolicyManagerInterface> dm_policy_manager_;
scoped_refptr<PolicyManagerInterface> external_constants_policy_manager_;
scoped_refptr<PolicyManagerInterface> platform_policy_manager_;
scoped_refptr<PolicyManagerInterface> default_policy_manager_;
};
PolicyService(scoped_refptr<ExternalConstants> external_constants,
scoped_refptr<PersistedData> persisted_data);
PolicyService(const PolicyService&) = delete;
PolicyService& operator=(const PolicyService&) = delete;
void FetchPolicies(policy::PolicyFetchReason reason,
base::OnceCallback<void(int)> callback);
std::string source() const;
PolicyStatus<bool> CloudPolicyOverridesPlatformPolicy() const;
PolicyStatus<base::TimeDelta> GetLastCheckPeriod() const;
PolicyStatus<UpdatesSuppressedTimes> GetUpdatesSuppressedTimes() const;
PolicyStatus<std::string> GetDownloadPreference() const;
PolicyStatus<int> GetPackageCacheSizeLimitMBytes() const;
PolicyStatus<int> GetPackageCacheExpirationTimeDays() const;
PolicyStatus<int> GetPolicyForAppInstalls(const std::string& app_id) const;
PolicyStatus<int> GetPolicyForAppUpdates(const std::string& app_id) const;
PolicyStatus<std::string> GetTargetChannel(const std::string& app_id) const;
PolicyStatus<std::string> GetTargetVersionPrefix(
const std::string& app_id) const;
PolicyStatus<bool> IsRollbackToTargetVersionAllowed(
const std::string& app_id) const;
PolicyStatus<int> GetMajorVersionRolloutPolicy(
const std::string& app_id) const;
PolicyStatus<int> GetMinorVersionRolloutPolicy(
const std::string& app_id) const;
PolicyStatus<std::string> GetProxyMode() const;
PolicyStatus<std::string> GetProxyPacUrl() const;
PolicyStatus<std::string> GetProxyServer() const;
PolicyStatus<std::vector<std::string>> GetForceInstallApps() const;
PolicyStatus<int> DeprecatedGetLastCheckPeriodMinutes() const;
base::Value::Dict GetAllPolicies() const;
std::string GetAllPoliciesAsString() const;
bool AreUpdatesSuppressedNow(base::Time now = base::Time::Now()) const;
void SetManagersForTesting(
std::vector<scoped_refptr<PolicyManagerInterface>> managers);
protected:
virtual ~PolicyService();
private:
friend class base::RefCountedThreadSafe<PolicyService>;
template <typename T>
using PolicyQueryFunction =
std::optional<T> (PolicyManagerInterface::*)() const;
template <typename T>
using AppPolicyQueryFunction =
std::optional<T> (PolicyManagerInterface::*)(const std::string&) const;
void DoFetchPolicies(policy::PolicyFetchReason reason,
base::OnceCallback<void(int)> callback,
bool has_enrollment_token);
void FetchPoliciesDone(
scoped_refptr<PolicyFetcher> fetcher,
LoadPolicyEndEvent event,
int result,
scoped_refptr<PolicyManagerInterface> dm_policy_manager);
template <typename T, typename U = T>
PolicyStatus<U> QueryPolicy(
PolicyQueryFunction<T> policy_query_function,
const base::RepeatingCallback<std::optional<U>(std::optional<T>)>&
transform = base::NullCallback()) const;
template <typename T>
PolicyStatus<T> QueryAppPolicy(
AppPolicyQueryFunction<T> policy_query_function,
const std::string& app_id) const;
std::set<std::string> GetAppsWithPolicy() const;
SEQUENCE_CHECKER(sequence_checker_);
std::unique_ptr<PolicyManagers> policy_managers_;
const scoped_refptr<ExternalConstants> external_constants_;
base::OnceCallback<void(int)> fetch_policies_callback_;
scoped_refptr<PersistedData> persisted_data_;
};
struct PolicyServiceProxyConfiguration {
PolicyServiceProxyConfiguration();
~PolicyServiceProxyConfiguration();
PolicyServiceProxyConfiguration(const PolicyServiceProxyConfiguration&);
PolicyServiceProxyConfiguration(PolicyServiceProxyConfiguration&&);
PolicyServiceProxyConfiguration& operator=(
const PolicyServiceProxyConfiguration&);
PolicyServiceProxyConfiguration& operator=(PolicyServiceProxyConfiguration&&);
static std::optional<PolicyServiceProxyConfiguration> Get(
scoped_refptr<PolicyService> policy_service);
bool proxy_auto_detect = false;
std::optional<std::string> proxy_pac_url;
std::optional<std::string> proxy_url;
};
bool IsCloudManaged();
}
#endif