| // Copyright 2023 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/system_logs/app_service_log_source.h" |
| |
| #include "chrome/browser/apps/app_service/app_service_proxy.h" |
| #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" |
| #include "chrome/browser/apps/app_service/metrics/app_platform_metrics.h" |
| #include "chrome/browser/apps/app_service/metrics/app_platform_metrics_utils.h" |
| #include "chrome/browser/ash/profiles/profile_helper.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chromeos/ash/components/browser_context_helper/browser_context_helper.h" |
| #include "components/user_manager/user_manager.h" |
| #include "content/public/browser/browser_thread.h" |
| |
| namespace system_logs { |
| |
| namespace { |
| |
| constexpr char kAppServiceLogEntry[] = "app_service"; |
| |
| } // namespace |
| |
| AppServiceLogSource::AppServiceLogSource() |
| : SystemLogsSource("AppServiceLog") {} |
| |
| AppServiceLogSource::~AppServiceLogSource() = default; |
| |
| void AppServiceLogSource::Fetch(SysLogsSourceCallback callback) { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| DCHECK(!callback.is_null()); |
| |
| auto response = std::make_unique<SystemLogsResponse>(); |
| |
| const auto* user = user_manager::UserManager::Get()->GetPrimaryUser(); |
| if (!user) { |
| std::move(callback).Run(std::move(response)); |
| return; |
| } |
| Profile* profile = ash::ProfileHelper::Get()->GetProfileByUser(user); |
| if (!profile || |
| !apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile)) { |
| std::move(callback).Run(std::move(response)); |
| return; |
| } |
| |
| std::set<std::string> running; |
| std::set<std::string> seen; |
| std::stringstream log_data; |
| |
| auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile); |
| proxy->InstanceRegistry().ForEachInstance( |
| [&running](const apps::InstanceUpdate& update) { |
| running.insert(update.AppId()); |
| }); |
| proxy->AppRegistryCache().ForEachApp([&log_data, &running, &seen, profile]( |
| const apps::AppUpdate& update) { |
| std::string status = |
| base::Contains(running, update.AppId()) ? "running" : "installed"; |
| auto app_type = apps::GetAppTypeHistogramName( |
| apps::GetAppTypeName(profile, update.AppType(), update.AppId(), |
| apps::LaunchContainer::kLaunchContainerNone)); |
| std::string id = |
| apps::AppPlatformMetrics::GetURLForApp(profile, update.AppId()).spec(); |
| // Different apps can coalesce to the same ID, only report the first |
| // instance. |
| if (id.empty() || base::Contains(seen, id)) { |
| return; |
| } |
| log_data << id << ", " << app_type << ", " << status << std::endl; |
| seen.insert(id); |
| }); |
| |
| (*response)[kAppServiceLogEntry] = log_data.str(); |
| std::move(callback).Run(std::move(response)); |
| } |
| |
| } // namespace system_logs |