1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h" 6 7 #include "base/json/json_string_value_serializer.h" 8 #include "base/sys_info.h" 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/extensions/extension_service.h" 11 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" 12 #include "chrome/browser/profiles/profile_manager.h" 13 #include "chrome/browser/sync/about_sync_util.h" 14 #include "chrome/browser/sync/profile_sync_service_factory.h" 15 #include "chrome/common/chrome_version_info.h" 16 #include "content/public/browser/browser_thread.h" 17 #include "extensions/browser/extension_system.h" 18 #include "extensions/common/extension.h" 19 #include "extensions/common/extension_set.h" 20 21 22 namespace { 23 24 const char kSyncDataKey[] = "about_sync_data"; 25 const char kExtensionsListKey[] = "extensions"; 26 const char kChromeVersionTag[] = "CHROME VERSION"; 27 #if !defined(OS_CHROMEOS) 28 const char kOsVersionTag[] = "OS VERSION"; 29 #endif 30 31 } // namespace 32 33 namespace system_logs { 34 35 void ChromeInternalLogSource::Fetch(const SysLogsSourceCallback& callback) { 36 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 37 DCHECK(!callback.is_null()); 38 39 SystemLogsResponse response; 40 41 chrome::VersionInfo version_info; 42 response[kChromeVersionTag] = version_info.CreateVersionString(); 43 44 #if !defined(OS_CHROMEOS) 45 // On ChromeOS, this will be pulled in from the LSB_RELEASE. 46 std::string os_version = base::SysInfo::OperatingSystemName() + ": " + 47 base::SysInfo::OperatingSystemVersion(); 48 response[kOsVersionTag] = os_version; 49 #endif 50 51 PopulateSyncLogs(&response); 52 PopulateExtensionInfoLogs(&response); 53 54 callback.Run(&response); 55 } 56 57 void ChromeInternalLogSource::PopulateSyncLogs(SystemLogsResponse* response) { 58 // We are only interested in sync logs for the primary user profile. 59 Profile* profile = ProfileManager::GetPrimaryUserProfile(); 60 if (!profile || 61 !ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(profile)) 62 return; 63 64 ProfileSyncService* service = 65 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile); 66 scoped_ptr<base::DictionaryValue> sync_logs( 67 sync_ui_util::ConstructAboutInformation(service)); 68 69 // Remove identity section. 70 base::ListValue* details = NULL; 71 sync_logs->GetList(kDetailsKey, &details); 72 if (!details) 73 return; 74 for (base::ListValue::iterator it = details->begin(); 75 it != details->end(); ++it) { 76 base::DictionaryValue* dict = NULL; 77 if ((*it)->GetAsDictionary(&dict)) { 78 std::string title; 79 dict->GetString("title", &title); 80 if (title == kIdentityTitle) { 81 details->Erase(it, NULL); 82 break; 83 } 84 } 85 } 86 87 // Add sync logs to logs. 88 std::string sync_logs_string; 89 JSONStringValueSerializer serializer(&sync_logs_string); 90 serializer.Serialize(*sync_logs.get()); 91 92 (*response)[kSyncDataKey] = sync_logs_string; 93 } 94 95 void ChromeInternalLogSource::PopulateExtensionInfoLogs( 96 SystemLogsResponse* response) { 97 if (!ChromeMetricsServiceAccessor::IsCrashReportingEnabled()) 98 return; 99 100 Profile* primary_profile = 101 g_browser_process->profile_manager()->GetPrimaryUserProfile(); 102 if (!primary_profile) 103 return; 104 105 ExtensionService* service = 106 extensions::ExtensionSystem::Get(primary_profile)->extension_service(); 107 if (!service) 108 return; 109 110 std::string extensions_list; 111 const extensions::ExtensionSet* extensions = service->extensions(); 112 for (extensions::ExtensionSet::const_iterator it = extensions->begin(); 113 it != extensions->end(); 114 ++it) { 115 const extensions::Extension* extension = it->get(); 116 if (extensions_list.empty()) { 117 extensions_list = extension->name(); 118 } else { 119 extensions_list += ",\n" + extension->name(); 120 } 121 } 122 if (!extensions_list.empty()) 123 extensions_list += "\n"; 124 125 if (!extensions_list.empty()) 126 (*response)[kExtensionsListKey] = extensions_list; 127 } 128 129 } // namespace system_logs 130