| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ash/arc/policy/arc_policy_util.h" |
| |
| #include <memory> |
| |
| #include "ash/constants/ash_switches.h" |
| #include "base/command_line.h" |
| #include "base/json/json_reader.h" |
| #include "base/logging.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "chrome/browser/ash/policy/handlers/configuration_policy_handler_ash.h" |
| #include "chrome/browser/policy/profile_policy_connector.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chromeos/ash/experiences/arc/arc_prefs.h" |
| #include "components/policy/core/common/policy_map.h" |
| #include "components/policy/policy_constants.h" |
| #include "components/policy/proto/cloud_policy.pb.h" |
| #include "components/prefs/pref_value_map.h" |
| |
| namespace arc { |
| namespace policy_util { |
| |
| namespace { |
| |
| // Constants used to parse ARC++ JSON policy. |
| constexpr char kApplicationsKey[] = "applications"; |
| constexpr char kInstallTypeKey[] = "installType"; |
| constexpr char kPackageNameKey[] = "packageName"; |
| constexpr char kInstallTypeRequired[] = "REQUIRED"; |
| constexpr char kInstallTypeForceInstalled[] = "FORCE_INSTALLED"; |
| |
| } // namespace |
| |
| bool IsAccountManaged(const Profile* profile) { |
| return profile->GetProfilePolicyConnector()->IsManaged(); |
| } |
| |
| bool IsArcDisabledForEnterprise() { |
| return base::CommandLine::ForCurrentProcess()->HasSwitch( |
| ash::switches::kEnterpriseDisableArc); |
| } |
| |
| std::set<std::string> GetRequestedPackagesFromArcPolicy( |
| const std::string& arc_policy) { |
| std::optional<base::Value> dict = ParsePolicyJson(arc_policy); |
| if (!dict.has_value() || !dict.value().is_dict()) { |
| return {}; |
| } |
| |
| std::map<std::string, std::set<std::string>> install_type_map = |
| CreateInstallTypeMap(dict.value()); |
| std::set<std::string> required_packages = |
| install_type_map[kInstallTypeRequired]; |
| std::set<std::string> force_installed_packages = |
| install_type_map[kInstallTypeForceInstalled]; |
| |
| // Only required and force installed packages are considered "requested" |
| std::set<std::string> requested_packages; |
| requested_packages.insert(required_packages.begin(), required_packages.end()); |
| requested_packages.insert(force_installed_packages.begin(), |
| force_installed_packages.end()); |
| return requested_packages; |
| } |
| |
| void RecordPolicyMetrics(const std::string& arc_policy) { |
| std::optional<base::Value> dict = ParsePolicyJson(arc_policy); |
| if (!dict.has_value() || !dict.value().is_dict()) { |
| return; |
| } |
| |
| for (const auto it : dict.value().GetDict()) { |
| std::optional<ArcPolicyKey> key = GetPolicyKeyFromString(it.first); |
| if (key.has_value()) { |
| UMA_HISTOGRAM_ENUMERATION("Arc.Policy.Keys", key.value()); |
| } |
| } |
| |
| std::map<std::string, std::set<std::string>> install_type_map = |
| CreateInstallTypeMap(dict.value()); |
| |
| for (auto& it : install_type_map) { |
| InstallType install_type_enum = GetInstallTypeEnumFromString(it.first); |
| UMA_HISTOGRAM_ENUMERATION("Arc.Policy.InstallTypesOnDevice", |
| install_type_enum); |
| } |
| } |
| |
| std::optional<base::Value> ParsePolicyJson(const std::string& arc_policy) { |
| return base::JSONReader::Read( |
| arc_policy, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS); |
| } |
| |
| std::map<std::string, std::set<std::string>> CreateInstallTypeMap( |
| const base::Value& dict) { |
| const base::Value::List* const packages = |
| dict.GetDict().FindList(kApplicationsKey); |
| if (!packages) |
| return {}; |
| |
| std::map<std::string, std::set<std::string>> install_type_map; |
| for (const auto& package : *packages) { |
| const base::Value::Dict* package_dict = package.GetIfDict(); |
| if (!package_dict) { |
| continue; |
| } |
| const std::string* const install_type = |
| package_dict->FindString(kInstallTypeKey); |
| if (!install_type) |
| continue; |
| |
| const std::string* const package_name = |
| package_dict->FindString(kPackageNameKey); |
| if (!package_name || package_name->empty()) { |
| continue; |
| } |
| install_type_map[*install_type].insert(*package_name); |
| } |
| return install_type_map; |
| } |
| |
| std::optional<ArcPolicyKey> GetPolicyKeyFromString( |
| const std::string& policy_key) { |
| if (policy_key == kArcPolicyKeyAvailableAppSetPolicyDeprecated || |
| policy_key == kArcPolicyKeyWorkAccountAppWhitelistDeprecated || |
| policy_key == kArcPolicyKeyGuid || |
| policy_key == kArcPolicyKeyMountPhysicalMediaDisabled || |
| policy_key == kArcPolicyKeyDpsInteractionsDisabled) { |
| // Ignore keys that are always set or represent server side flags. |
| return std::nullopt; |
| } |
| |
| if (policy_key == kArcPolicyKeyAccountTypesWithManagementDisabled) { |
| return ArcPolicyKey::kAccountTypesWithManagementDisabled; |
| } else if (policy_key == kArcPolicyKeyAlwaysOnVpnPackage) { |
| return ArcPolicyKey::kAlwaysOnVpnPackage; |
| } else if (policy_key == kArcPolicyKeyApplications) { |
| return ArcPolicyKey::kApplications; |
| } else if (policy_key == kArcPolicyKeyComplianceRules) { |
| return ArcPolicyKey::kComplianceRules; |
| } else if (policy_key == kArcPolicyKeyInstallUnknownSourcesDisabled) { |
| return ArcPolicyKey::kInstallUnknownSourcesDisabled; |
| } else if (policy_key == kArcPolicyKeyMaintenanceWindow) { |
| return ArcPolicyKey::kMaintenanceWindow; |
| } else if (policy_key == kArcPolicyKeyModifyAccountsDisabled) { |
| return ArcPolicyKey::kModifyAccountsDisabled; |
| } else if (policy_key == kArcPolicyKeyPermissionGrants) { |
| return ArcPolicyKey::kPermissionGrants; |
| } else if (policy_key == kArcPolicyKeyPermittedAccessibilityServices) { |
| return ArcPolicyKey::kPermittedAccessibilityServices; |
| } else if (policy_key == kArcPolicyKeyPlayStoreMode) { |
| return ArcPolicyKey::kPlayStoreMode; |
| } else if (policy_key == kArcPolicyKeyShortSupportMessage) { |
| return ArcPolicyKey::kShortSupportMessage; |
| } else if (policy_key == kArcPolicyKeyStatusReportingSettings) { |
| return ArcPolicyKey::kStatusReportingSettings; |
| } else if (policy_key == kArcPolicyKeyApkCacheEnabled) { |
| return ArcPolicyKey::kApkCacheEnabled; |
| } else if (policy_key == kArcPolicyKeyDebuggingFeaturesDisabled) { |
| return ArcPolicyKey::kDebuggingFeaturesDisabled; |
| } else if (policy_key == kArcPolicyKeyCameraDisabled) { |
| return ArcPolicyKey::kCameraDisabled; |
| } else if (policy_key == kArcPolicyKeyPrintingDisabled) { |
| return ArcPolicyKey::kPrintingDisabled; |
| } else if (policy_key == kArcPolicyKeyScreenCaptureDisabled) { |
| return ArcPolicyKey::kScreenCaptureDisabled; |
| } else if (policy_key == kArcPolicyKeyShareLocationDisabled) { |
| return ArcPolicyKey::kShareLocationDisabled; |
| } else if (policy_key == kArcPolicyKeyUnmuteMicrophoneDisabled) { |
| return ArcPolicyKey::kUnmuteMicrophoneDisabled; |
| } else if (policy_key == kArcPolicyKeySetWallpaperDisabled) { |
| return ArcPolicyKey::kSetWallpaperDisabled; |
| } else if (policy_key == kArcPolicyKeyVpnConfigDisabled) { |
| return ArcPolicyKey::kVpnConfigDisabled; |
| } else if (policy_key == kArcPolicyKeyPrivateKeySelectionEnabled) { |
| return ArcPolicyKey::kPrivateKeySelectionEnabled; |
| } else if (policy_key == kArcPolicyKeyChoosePrivateKeyRules) { |
| return ArcPolicyKey::kChoosePrivateKeyRules; |
| } else if (policy_key == kArcPolicyKeyCredentialsConfigDisabled) { |
| return ArcPolicyKey::kCredentialsConfigDisabled; |
| } else if (policy_key == kArcPolicyKeyCaCerts) { |
| return ArcPolicyKey::kCaCerts; |
| } else if (policy_key == kArcPolicyKeyRequiredKeyPairs) { |
| return ArcPolicyKey::kRequiredKeyPairs; |
| } else if (policy_key == kArcPolicyKeyEnabledSystemAppPackageNames) { |
| return ArcPolicyKey::kEnabledSystemAppPackageNames; |
| } |
| |
| LOG(WARNING) << "Unknown policy key: " << policy_key; |
| return ArcPolicyKey::kUnknown; |
| } |
| |
| InstallType GetInstallTypeEnumFromString(const std::string& install_type) { |
| if (install_type == "OPTIONAL") { |
| return InstallType::kOptional; |
| } else if (install_type == "REQUIRED") { |
| return InstallType::kRequired; |
| } else if (install_type == "PRELOAD") { |
| return InstallType::kPreload; |
| } else if (install_type == "FORCE_INSTALLED") { |
| return InstallType::kForceInstalled; |
| } else if (install_type == "BLOCKED") { |
| return InstallType::kBlocked; |
| } else if (install_type == "AVAILABLE") { |
| return InstallType::kAvailable; |
| } else if (install_type == "REQUIRED_FOR_SETUP") { |
| return InstallType::kRequiredForSetup; |
| } else if (install_type == "KIOSK") { |
| return InstallType::kKiosk; |
| } |
| |
| LOG(WARNING) << "Unknown app install type in the policy: " << install_type; |
| return InstallType::kUnknown; |
| } |
| |
| } // namespace policy_util |
| } // namespace arc |