| // Copyright 2021 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/common/chromeos/extensions/chromeos_system_extension_info.h" | 
 |  | 
 | #include <memory> | 
 | #include <optional> | 
 | #include <string> | 
 |  | 
 | #include "base/check.h" | 
 | #include "base/command_line.h" | 
 | #include "base/containers/fixed_flat_map.h" | 
 | #include "base/containers/flat_set.h" | 
 | #include "base/logging.h" | 
 | #include "build/chromeos_buildflags.h" | 
 | #include "components/web_package/signed_web_bundles/signed_web_bundle_id.h" | 
 |  | 
 | #if BUILDFLAG(IS_CHROMEOS_ASH) | 
 | #include "ash/constants/ash_features.h" | 
 | #endif  // BUILDFLAG(IS_CHROMEOS_ASH) | 
 |  | 
 | namespace chromeos { | 
 |  | 
 | namespace switches { | 
 |  | 
 | // Overrides |manufacturer| field of the ChromeOSSystemExtensionInfo structure. | 
 | // Used for development/testing. | 
 | const char kTelemetryExtensionManufacturerOverrideForTesting[] = | 
 |     "telemetry-extension-manufacturer-override-for-testing"; | 
 |  | 
 | // Overrides |pwa_origin| field of the ChromeOSSystemExtensionInfo structure. | 
 | // Used for development/testing. | 
 | const char kTelemetryExtensionPwaOriginOverrideForTesting[] = | 
 |     "telemetry-extension-pwa-origin-override-for-testing"; | 
 |  | 
 | // Overrides |iwa_id| field of the ChromeOSSystemExtensionInfo structure. | 
 | // Used for development/testing. | 
 | const char kTelemetryExtensionIwaIdOverrideForTesting[] = | 
 |     "telemetry-extension-iwa-id-override-for-testing"; | 
 |  | 
 | }  // namespace switches | 
 |  | 
 | namespace { | 
 |  | 
 | using ChromeOSSystemExtensionInfoMap = | 
 |     base::flat_map<std::string, ChromeOSSystemExtensionInfo>; | 
 |  | 
 | ChromeOSSystemExtensionInfoMap ConstructMap() { | 
 |   ChromeOSSystemExtensionInfoMap map{ | 
 |       {/*extension_id=*/"gogonhoemckpdpadfnjnpgbjpbjnodgc", | 
 |        { | 
 |            /*manufacturers=*/{"HP", "ASUS"}, | 
 |            /*pwa_origin=*/"*://googlechromelabs.github.io/*", | 
 |            /*iwa_id=*/std::nullopt, | 
 |        }}, | 
 |       {/*extension_id=*/"alnedpmllcfpgldkagbfbjkloonjlfjb", | 
 |        { | 
 |            /*manufacturers=*/{"HP"}, | 
 |            /*pwa_origin=*/"https://hpcs-appschr.hpcloud.hp.com/*", | 
 |            /*iwa_id=*/std::nullopt, | 
 |        }}, | 
 |       {/*extension_id=*/"hdnhcpcfohaeangjpkcjkgmgmjanbmeo", | 
 |        { | 
 |            /*manufacturers=*/{"ASUS"}, | 
 |            /*pwa_origin=*/"https://dlcdnccls.asus.com/*", | 
 |            /*iwa_id=*/std::nullopt, | 
 |        }}, | 
 |   }; | 
 |  | 
 |   if (IsChromeOSSystemExtensionDevExtensionEnabled()) { | 
 |     map.try_emplace( | 
 |         kChromeOSSystemExtensionDevExtensionId, | 
 |         ChromeOSSystemExtensionInfo{ | 
 |             /*manufacturers=*/{"Google", "HP", "ASUS"}, | 
 |             /*pwa_origin=*/"*://googlechromelabs.github.io/*", | 
 |             /*iwa_id=*/ | 
 |             web_package::SignedWebBundleId::Create( | 
 |                 "pt2jysa7yu326m2cbu5mce4rrajvguagronrsqwn5dhbaris6eaaaaic") | 
 |                 .value(), | 
 |         }); | 
 |   } | 
 |  | 
 |   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 
 |   if (command_line->HasSwitch( | 
 |           switches::kTelemetryExtensionPwaOriginOverrideForTesting)) { | 
 |     auto pwa_origin = command_line->GetSwitchValueASCII( | 
 |         switches::kTelemetryExtensionPwaOriginOverrideForTesting); | 
 |     for (auto& [extension_id, extension_info] : map) { | 
 |       extension_info.pwa_origin = pwa_origin; | 
 |     } | 
 |   } | 
 |  | 
 |   if (command_line->HasSwitch( | 
 |           switches::kTelemetryExtensionManufacturerOverrideForTesting)) { | 
 |     auto manufacturer = command_line->GetSwitchValueASCII( | 
 |         switches::kTelemetryExtensionManufacturerOverrideForTesting); | 
 |     for (auto& [extension_id, extension_info] : map) { | 
 |       extension_info.manufacturers = {manufacturer}; | 
 |     } | 
 |   } | 
 |  | 
 |   if (command_line->HasSwitch( | 
 |           switches::kTelemetryExtensionIwaIdOverrideForTesting)) { | 
 |     auto iwa_id_str = command_line->GetSwitchValueASCII( | 
 |         switches::kTelemetryExtensionIwaIdOverrideForTesting); | 
 |     auto iwa_id_res = web_package::SignedWebBundleId::Create(iwa_id_str); | 
 |     if (iwa_id_res.has_value()) { | 
 |       for (auto& [extension_id, extension_info] : map) { | 
 |         extension_info.iwa_id = iwa_id_res.value(); | 
 |       } | 
 |     } else { | 
 |       LOG(ERROR) << "Failed to parse iwa id " << iwa_id_str << ": " | 
 |                  << iwa_id_res.error(); | 
 |     } | 
 |   } | 
 |  | 
 |   return map; | 
 | } | 
 |  | 
 | ChromeOSSystemExtensionInfoMap*& GetMap() { | 
 |   static ChromeOSSystemExtensionInfoMap* g_map = | 
 |       new ChromeOSSystemExtensionInfoMap{ConstructMap()}; | 
 |   return g_map; | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | bool IsChromeOSSystemExtensionDevExtensionEnabled() { | 
 | #if BUILDFLAG(IS_CHROMEOS_ASH) | 
 |   return ash::features::IsShimlessRMA3pDiagnosticsDevModeEnabled(); | 
 | #else | 
 |   return false; | 
 | #endif  // BUILDFLAG(IS_CHROMEOS_ASH) | 
 | } | 
 |  | 
 | ChromeOSSystemExtensionInfo::ChromeOSSystemExtensionInfo( | 
 |     const base::flat_set<std::string>& manufacturers, | 
 |     const std::optional<std::string>& pwa_origin, | 
 |     const std::optional<web_package::SignedWebBundleId>& iwa_id) | 
 |     : manufacturers(manufacturers), pwa_origin(pwa_origin), iwa_id(iwa_id) {} | 
 |  | 
 | ChromeOSSystemExtensionInfo::ChromeOSSystemExtensionInfo( | 
 |     const ChromeOSSystemExtensionInfo&) = default; | 
 |  | 
 | ChromeOSSystemExtensionInfo& ChromeOSSystemExtensionInfo::operator=( | 
 |     const ChromeOSSystemExtensionInfo&) = default; | 
 |  | 
 | ChromeOSSystemExtensionInfo::~ChromeOSSystemExtensionInfo() = default; | 
 |  | 
 | const ChromeOSSystemExtensionInfo& GetChromeOSExtensionInfoById( | 
 |     const std::string& id) { | 
 |   CHECK(IsChromeOSSystemExtension(id)); | 
 |   return GetMap()->at(id); | 
 | } | 
 |  | 
 | bool IsChromeOSSystemExtension(const std::string& id) { | 
 |   return GetMap()->find(id) != GetMap()->end(); | 
 | } | 
 |  | 
 | bool Is3pDiagnosticsIwaId(const web_package::SignedWebBundleId& id) { | 
 |   for (const auto& [extension_id, extension_info] : *GetMap()) { | 
 |     if (extension_info.iwa_id == id) { | 
 |       return true; | 
 |     } | 
 |   } | 
 |   return false; | 
 | } | 
 |  | 
 | bool IsChromeOSSystemExtensionProvider(const std::string& manufacturer) { | 
 |   for (const auto& [extension_id, info] : *GetMap()) { | 
 |     if (info.manufacturers.contains(manufacturer)) { | 
 |       return true; | 
 |     } | 
 |   } | 
 |   return false; | 
 | } | 
 |  | 
 | class ScopedChromeOSSystemExtensionInfoImpl | 
 |     : public ScopedChromeOSSystemExtensionInfo { | 
 |  public: | 
 |   ScopedChromeOSSystemExtensionInfoImpl(); | 
 |   ScopedChromeOSSystemExtensionInfoImpl( | 
 |       ScopedChromeOSSystemExtensionInfoImpl&) = delete; | 
 |   ScopedChromeOSSystemExtensionInfoImpl& operator=( | 
 |       ScopedChromeOSSystemExtensionInfoImpl&) = delete; | 
 |   ~ScopedChromeOSSystemExtensionInfoImpl() override; | 
 |  | 
 |   void ApplyCommandLineSwitchesForTesting() override;  // IN-TEST | 
 |  | 
 |  private: | 
 |   raw_ptr<ChromeOSSystemExtensionInfoMap> map_; | 
 | }; | 
 |  | 
 | // static | 
 | std::unique_ptr<ScopedChromeOSSystemExtensionInfo> | 
 | ScopedChromeOSSystemExtensionInfo::CreateForTesting() { | 
 |   return std::make_unique<ScopedChromeOSSystemExtensionInfoImpl>(); | 
 | } | 
 |  | 
 | ScopedChromeOSSystemExtensionInfoImpl::ScopedChromeOSSystemExtensionInfoImpl() { | 
 |   map_ = GetMap(); | 
 |   GetMap() = new ChromeOSSystemExtensionInfoMap{ConstructMap()}; | 
 | } | 
 |  | 
 | ScopedChromeOSSystemExtensionInfoImpl:: | 
 |     ~ScopedChromeOSSystemExtensionInfoImpl() { | 
 |   delete GetMap(); | 
 |   GetMap() = map_; | 
 | } | 
 |  | 
 | void ScopedChromeOSSystemExtensionInfoImpl:: | 
 |     ApplyCommandLineSwitchesForTesting() { | 
 |   delete GetMap(); | 
 |   GetMap() = new ChromeOSSystemExtensionInfoMap{ConstructMap()}; | 
 | } | 
 |  | 
 | }  // namespace chromeos |