Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/browser_about_handler.h" | 5 #include "chrome/browser/browser_about_handler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "base/threading/thread.h" | 24 #include "base/threading/thread.h" |
| 25 #include "base/tracked_objects.h" | 25 #include "base/tracked_objects.h" |
| 26 #include "base/utf_string_conversions.h" | 26 #include "base/utf_string_conversions.h" |
| 27 #include "base/values.h" | 27 #include "base/values.h" |
| 28 #include "chrome/browser/about_flags.h" | 28 #include "chrome/browser/about_flags.h" |
| 29 #include "chrome/browser/browser_process.h" | 29 #include "chrome/browser/browser_process.h" |
| 30 #include "chrome/browser/defaults.h" | 30 #include "chrome/browser/defaults.h" |
| 31 #include "chrome/browser/memory_details.h" | 31 #include "chrome/browser/memory_details.h" |
| 32 #include "chrome/browser/metrics/histogram_synchronizer.h" | 32 #include "chrome/browser/metrics/histogram_synchronizer.h" |
| 33 #include "chrome/browser/net/predictor_api.h" | 33 #include "chrome/browser/net/predictor_api.h" |
| 34 #include "chrome/browser/net/url_fixer_upper.h" | |
| 34 #include "chrome/browser/platform_util.h" | 35 #include "chrome/browser/platform_util.h" |
| 35 #include "chrome/browser/profiles/profile.h" | 36 #include "chrome/browser/profiles/profile.h" |
| 36 #include "chrome/browser/profiles/profile_manager.h" | 37 #include "chrome/browser/profiles/profile_manager.h" |
| 37 #include "chrome/browser/ui/browser_dialogs.h" | 38 #include "chrome/browser/ui/browser_dialogs.h" |
| 38 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" | 39 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" |
| 39 #include "chrome/common/about_handler.h" | 40 #include "chrome/common/about_handler.h" |
| 40 #include "chrome/common/chrome_paths.h" | 41 #include "chrome/common/chrome_paths.h" |
| 41 #include "chrome/common/chrome_version_info.h" | 42 #include "chrome/common/chrome_version_info.h" |
| 42 #include "chrome/common/jstemplate_builder.h" | 43 #include "chrome/common/jstemplate_builder.h" |
| 43 #include "chrome/common/net/gaia/google_service_auth_error.h" | 44 #include "chrome/common/net/gaia/google_service_auth_error.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 | 97 |
| 97 // Glue between the callback task and the method in the singleton. | 98 // Glue between the callback task and the method in the singleton. |
| 98 void AboutTcmallocRendererCallback(base::ProcessId pid, | 99 void AboutTcmallocRendererCallback(base::ProcessId pid, |
| 99 const std::string& output) { | 100 const std::string& output) { |
| 100 AboutTcmallocOutputs::GetInstance()->RendererCallback(pid, output); | 101 AboutTcmallocOutputs::GetInstance()->RendererCallback(pid, output); |
| 101 } | 102 } |
| 102 #endif | 103 #endif |
| 103 | 104 |
| 104 namespace { | 105 namespace { |
| 105 | 106 |
| 106 // The (alphabetized) paths used for the about pages. | 107 // Add paths here to be included in about:about. |
| 107 // Note: Keep these in sync with url_constants.h | 108 // These paths will also be suggested by BuiltinProvider. |
| 108 const char kAppCacheInternalsPath[] = "appcache-internals"; | 109 const char *kAllAboutPaths[] = { |
| 109 const char kBlobInternalsPath[] = "blob-internals"; | 110 chrome::kChromeUIAboutHost, |
| 110 const char kCreditsPath[] = "credits"; | 111 chrome::kChromeUIAppCacheInternalsHost, |
| 111 const char kCachePath[] = "view-http-cache"; | 112 chrome::kChromeUIBlobInternalsHost, |
| 113 chrome::kChromeUICreditsHost, | |
| 114 chrome::kChromeUIDNSHost, | |
| 115 chrome::kChromeUIFlagsHost, | |
| 116 chrome::kChromeUIFlashHost, | |
| 117 chrome::kChromeUIGpuInternalsHost, | |
| 118 chrome::kChromeUIHistogramsHost, | |
| 119 chrome::kChromeUIMemoryHost, | |
| 120 chrome::kChromeUINetInternalsHost, | |
| 121 chrome::kChromeUINetworkViewCacheHost, | |
| 122 chrome::kChromeUIPluginsHost, | |
| 123 chrome::kChromeUIStatsHost, | |
| 124 chrome::kChromeUISyncInternalsHost, | |
| 125 chrome::kChromeUITCMallocHost, | |
| 126 chrome::kChromeUITermsHost, | |
| 127 chrome::kChromeUIVersionHost, | |
| 128 #ifdef TRACK_ALL_TASK_OBJECTS | |
| 129 chrome::kChromeUITasksHost, | |
| 130 #endif | |
| 112 #if defined(OS_WIN) | 131 #if defined(OS_WIN) |
| 113 const char kConflictsPath[] = "conflicts"; | 132 chrome::kChromeUIConflictsHost, |
| 114 #endif | 133 #endif |
| 115 const char kDnsPath[] = "dns"; | |
| 116 const char kFlagsPath[] = "flags"; | |
| 117 const char kFlashPath[] = "flash"; | |
| 118 const char kGpuPath[] = "gpu-internals"; | |
| 119 const char kHistogramsPath[] = "histograms"; | |
| 120 const char kMemoryRedirectPath[] = "memory-redirect"; | |
| 121 const char kMemoryPath[] = "memory"; | |
| 122 const char kStatsPath[] = "stats"; | |
| 123 const char kTasksPath[] = "tasks"; | |
| 124 const char kTcmallocPath[] = "tcmalloc"; | |
| 125 const char kTermsPath[] = "terms"; | |
| 126 const char kVersionPath[] = "version"; | |
| 127 const char kAboutPath[] = "about"; | |
| 128 // Not about:* pages, but included to make about:about look nicer | |
| 129 const char kNetInternalsPath[] = "net-internals"; | |
| 130 const char kPluginsPath[] = "plugins"; | |
| 131 const char kSyncInternalsPath[] = "sync-internals"; | |
| 132 | |
| 133 #if defined(OS_LINUX) | 134 #if defined(OS_LINUX) |
| 134 const char kLinuxProxyConfigPath[] = "linux-proxy-config"; | 135 chrome::kChromeUISandboxHost, |
| 135 const char kSandboxPath[] = "sandbox"; | |
| 136 #endif | |
| 137 | |
| 138 #if defined(OS_CHROMEOS) | |
| 139 const char kNetworkPath[] = "network"; | |
| 140 const char kOSCreditsPath[] = "os-credits"; | |
| 141 const char kEULAPathFormat[] = "/usr/share/chromeos-assets/eula/%s/eula.html"; | |
| 142 #endif | |
| 143 | |
| 144 // Add path here to be included in about:about | |
| 145 const char *kAllAboutPaths[] = { | |
| 146 kAboutPath, | |
| 147 kAppCacheInternalsPath, | |
| 148 kBlobInternalsPath, | |
| 149 kCachePath, | |
| 150 kCreditsPath, | |
| 151 #if defined(OS_WIN) | |
| 152 kConflictsPath, | |
| 153 #endif | |
| 154 kDnsPath, | |
| 155 kFlagsPath, | |
| 156 kFlashPath, | |
| 157 kGpuPath, | |
| 158 kHistogramsPath, | |
| 159 kMemoryPath, | |
| 160 kNetInternalsPath, | |
| 161 kPluginsPath, | |
| 162 kStatsPath, | |
| 163 kSyncInternalsPath, | |
| 164 #ifdef TRACK_ALL_TASK_OBJECTS | |
| 165 kTasksPath, | |
| 166 #endif // TRACK_ALL_TASK_OBJECTS | |
| 167 kTcmallocPath, | |
| 168 kTermsPath, | |
| 169 kVersionPath, | |
| 170 #if defined(OS_LINUX) | |
| 171 kSandboxPath, | |
| 172 #endif | 136 #endif |
| 173 #if defined(OS_CHROMEOS) | 137 #if defined(OS_CHROMEOS) |
| 174 kNetworkPath, | 138 chrome::kChromeUINetworkHost, |
| 175 kOSCreditsPath, | 139 chrome::kChromeUIOSCreditsHost, |
| 176 #endif | 140 #endif |
| 177 }; | 141 }; |
| 178 | 142 |
| 179 // When you type about:memory, it actually loads an intermediate URL that | 143 // Debug about paths, presented without links in about:about. |
| 180 // redirects you to the final page. This avoids the problem where typing | 144 // These paths will not be suggested by BuiltinProvider. |
| 181 // "about:memory" on the new tab page or any other page where a process | 145 const char *kDebugAboutPaths[] = { |
| 182 // transition would occur to the about URL will cause some confusion. | 146 chrome::kChromeUICrashHost, |
| 183 // | 147 chrome::kChromeUIKillHost, |
| 184 // The problem is that during the processing of the memory page, there are two | 148 chrome::kChromeUIHangHost, |
| 185 // processes active, the original and the destination one. This can create the | 149 chrome::kChromeUIShorthangHost, |
| 186 // impression that we're using more resources than we actually are. This | 150 chrome::kChromeUIGpuCleanHost, |
| 187 // redirect solves the problem by eliminating the process transition during the | 151 chrome::kChromeUIGpuCrashHost, |
| 188 // time that about memory is being computed. | 152 chrome::kChromeUIGpuHangHost |
| 189 std::string GetAboutMemoryRedirectResponse() { | 153 }; |
| 190 return "<meta http-equiv=\"refresh\" " | 154 |
| 191 "content=\"0;chrome://about/memory\">"; | 155 // AboutSource handles these about: and chrome: paths. |
| 192 } | 156 const char *kAboutSourceNames[] = { |
| 157 chrome::kChromeUIAboutHost, | |
| 158 chrome::kChromeUICreditsHost, | |
| 159 chrome::kChromeUIDNSHost, | |
| 160 chrome::kChromeUIHistogramsHost, | |
| 161 #if defined(OS_LINUX) | |
| 162 chrome::kChromeUILinuxProxyConfigHost, | |
| 163 #endif | |
| 164 chrome::kChromeUIMemoryHost, | |
| 165 chrome::kChromeUIMemoryRedirectHost, | |
| 166 #if defined(OS_CHROMEOS) | |
| 167 chrome::kChromeUINetworkHost, | |
| 168 chrome::kChromeUIOSCreditsHost, | |
| 169 #endif | |
| 170 #if defined(OS_LINUX) | |
| 171 chrome::kChromeUISandboxHost, | |
| 172 #endif | |
| 173 chrome::kChromeUIStatsHost, | |
| 174 #ifdef TRACK_ALL_TASK_OBJECTS | |
| 175 chrome::kChromeUITasksHost, | |
| 176 #endif | |
| 177 #if defined(USE_TCMALLOC) | |
| 178 chrome::kChromeUITCMallocHost, | |
| 179 #endif | |
| 180 chrome::kChromeUITermsHost, | |
| 181 chrome::kChromeUIVersionHost | |
| 182 }; | |
| 193 | 183 |
| 194 class AboutSource : public ChromeURLDataManager::DataSource { | 184 class AboutSource : public ChromeURLDataManager::DataSource { |
| 195 public: | 185 public: |
| 196 // Creates our datasource. | 186 // Construct a data source for the specified |source_name|. |
| 197 AboutSource(); | 187 AboutSource(const std::string& source_name, Profile* profile); |
| 198 explicit AboutSource(Profile* profile); | |
| 199 | 188 |
| 200 // Called when the network layer has requested a resource underneath | 189 // Called when the network layer has requested a resource underneath |
| 201 // the path we registered. | 190 // the path we registered. |
| 202 virtual void StartDataRequest(const std::string& path, | 191 virtual void StartDataRequest(const std::string& path, |
| 203 bool is_incognito, | 192 bool is_incognito, |
| 204 int request_id); | 193 int request_id) OVERRIDE; |
| 205 | 194 |
| 206 virtual std::string GetMimeType(const std::string&) const { | 195 virtual std::string GetMimeType(const std::string&) const OVERRIDE { |
| 207 return "text/html"; | 196 return "text/html"; |
| 208 } | 197 } |
| 209 | 198 |
| 210 // Send the response data. | 199 // Send the response data. |
| 211 void FinishDataRequest(const std::string& html, int request_id); | 200 void FinishDataRequest(const std::string& html, int request_id); |
| 212 | 201 |
| 213 Profile* profile() { return profile_; } | 202 Profile* profile() { return profile_; } |
| 214 | 203 |
| 215 private: | 204 private: |
| 216 virtual ~AboutSource(); | 205 virtual ~AboutSource(); |
| 217 | 206 |
| 218 Profile* profile_; | 207 Profile* profile_; |
| 219 | 208 |
| 220 DISALLOW_COPY_AND_ASSIGN(AboutSource); | 209 DISALLOW_COPY_AND_ASSIGN(AboutSource); |
| 221 }; | 210 }; |
| 222 | 211 |
| 212 // Register a data source for a known source name. Safe to call multiple times. | |
| 213 // |name| may be an unkown host (e.g. "chrome://foo/"); only handle known hosts. | |
| 214 void InitializeAboutDataSource(const std::string& name, Profile* profile) { | |
| 215 ChromeURLDataManager* manager = profile->GetChromeURLDataManager(); | |
| 216 for (size_t i = 0; i < arraysize(kAboutSourceNames); i++) { | |
| 217 if (name == kAboutSourceNames[i]) { | |
| 218 manager->AddDataSource(new AboutSource(name, profile)); | |
| 219 return; | |
| 220 } | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 // When you type about:memory, it actually loads this intermediate URL that | |
| 225 // redirects you to the final page. This avoids the problem where typing | |
| 226 // "about:memory" on the new tab page or any other page where a process | |
| 227 // transition would occur to the about URL will cause some confusion. | |
| 228 // | |
| 229 // The problem is that during the processing of the memory page, there are two | |
| 230 // processes active, the original and the destination one. This can create the | |
| 231 // impression that we're using more resources than we actually are. This | |
| 232 // redirect solves the problem by eliminating the process transition during the | |
| 233 // time that about memory is being computed. | |
| 234 std::string GetAboutMemoryRedirectResponse(Profile* profile) { | |
| 235 InitializeAboutDataSource(chrome::kChromeUIMemoryRedirectHost, profile); | |
| 236 return StringPrintf("<meta http-equiv=\"refresh\" content=\"0;%s\">", | |
| 237 chrome::kChromeUIMemoryRedirectURL); | |
| 238 } | |
| 239 | |
| 223 // Handling about:memory is complicated enough to encapsulate its related | 240 // Handling about:memory is complicated enough to encapsulate its related |
| 224 // methods into a single class. The user should create it (on the heap) and call | 241 // methods into a single class. The user should create it (on the heap) and call |
| 225 // its |StartFetch()| method. | 242 // its |StartFetch()| method. |
| 226 class AboutMemoryHandler : public MemoryDetails { | 243 class AboutMemoryHandler : public MemoryDetails { |
| 227 public: | 244 public: |
| 228 AboutMemoryHandler(AboutSource* source, int request_id) | 245 AboutMemoryHandler(AboutSource* source, int request_id) |
| 229 : source_(source), request_id_(request_id) {} | 246 : source_(source), |
| 230 | 247 request_id_(request_id) { |
| 248 } | |
| 231 | 249 |
| 232 virtual void OnDetailsAvailable(); | 250 virtual void OnDetailsAvailable(); |
| 233 | 251 |
| 234 private: | 252 private: |
| 235 ~AboutMemoryHandler() {} | 253 ~AboutMemoryHandler() {} |
| 236 | 254 |
| 237 void BindProcessMetrics(DictionaryValue* data, | 255 void BindProcessMetrics(DictionaryValue* data, |
| 238 ProcessMemoryInformation* info); | 256 ProcessMemoryInformation* info); |
| 239 void AppendProcess(ListValue* child_data, ProcessMemoryInformation* info); | 257 void AppendProcess(ListValue* child_data, ProcessMemoryInformation* info); |
| 240 | 258 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 | 309 |
| 292 void StartOnUIThread() { | 310 void StartOnUIThread() { |
| 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 294 BrowserThread::PostTask( | 312 BrowserThread::PostTask( |
| 295 BrowserThread::FILE, FROM_HERE, | 313 BrowserThread::FILE, FROM_HERE, |
| 296 NewRunnableMethod(this, &ChromeOSTermsHandler::LoadFileOnFileThread)); | 314 NewRunnableMethod(this, &ChromeOSTermsHandler::LoadFileOnFileThread)); |
| 297 } | 315 } |
| 298 | 316 |
| 299 void LoadFileOnFileThread() { | 317 void LoadFileOnFileThread() { |
| 300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 301 std::string path = StringPrintf(kEULAPathFormat, locale_.c_str()); | 319 std::string path = StringPrintf(chrome::kEULAPathFormat, locale_.c_str()); |
| 302 if (!file_util::ReadFileToString(FilePath(path), &contents_)) { | 320 if (!file_util::ReadFileToString(FilePath(path), &contents_)) { |
| 303 // No EULA for given language - try en-US as default. | 321 // No EULA for given language - try en-US as default. |
| 304 path = StringPrintf(kEULAPathFormat, "en-US"); | 322 path = StringPrintf(chrome::kEULAPathFormat, "en-US"); |
| 305 if (!file_util::ReadFileToString(FilePath(path), &contents_)) { | 323 if (!file_util::ReadFileToString(FilePath(path), &contents_)) { |
| 306 // File with EULA not found, ResponseOnUIThread will load EULA from | 324 // File with EULA not found, ResponseOnUIThread will load EULA from |
| 307 // resources if contents_ is empty. | 325 // resources if contents_ is empty. |
| 308 contents_.clear(); | 326 contents_.clear(); |
| 309 } | 327 } |
| 310 } | 328 } |
| 311 BrowserThread::PostTask( | 329 BrowserThread::PostTask( |
| 312 BrowserThread::UI, FROM_HERE, | 330 BrowserThread::UI, FROM_HERE, |
| 313 NewRunnableMethod(this, &ChromeOSTermsHandler::ResponseOnUIThread)); | 331 NewRunnableMethod(this, &ChromeOSTermsHandler::ResponseOnUIThread)); |
| 314 } | 332 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 338 #endif | 356 #endif |
| 339 | 357 |
| 340 // Individual about handlers --------------------------------------------------- | 358 // Individual about handlers --------------------------------------------------- |
| 341 | 359 |
| 342 std::string AboutAbout() { | 360 std::string AboutAbout() { |
| 343 std::string html("<html><head><title>About Pages</title></head>\n" | 361 std::string html("<html><head><title>About Pages</title></head>\n" |
| 344 "<body><h2>List of About pages</h2>\n<ul>"); | 362 "<body><h2>List of About pages</h2>\n<ul>"); |
| 345 std::vector<std::string> paths(AboutPaths()); | 363 std::vector<std::string> paths(AboutPaths()); |
| 346 for (std::vector<std::string>::const_iterator i = paths.begin(); | 364 for (std::vector<std::string>::const_iterator i = paths.begin(); |
| 347 i != paths.end(); ++i) { | 365 i != paths.end(); ++i) { |
| 348 html += "<li><a href='chrome://"; | 366 html += "<li><a href='chrome://" + *i + "/'>about:" + *i + "</a></li>\n"; |
|
abarth-chromium
2011/05/31 19:27:54
It's strange that the link says "about:i" but the
msw
2011/05/31 20:58:25
Done. Further cleanup is slated for crbug.com/7392
| |
| 349 if ((*i != kAppCacheInternalsPath) && | |
| 350 (*i != kBlobInternalsPath) && | |
| 351 (*i != kCachePath) && | |
| 352 #if defined(OS_WIN) | |
| 353 (*i != kConflictsPath) && | |
| 354 #endif | |
| 355 (*i != kFlagsPath) && | |
| 356 (*i != kFlashPath) && | |
| 357 (*i != kGpuPath) && | |
| 358 (*i != kNetInternalsPath) && | |
| 359 (*i != kPluginsPath)) { | |
| 360 html += "about/"; | |
| 361 } | |
| 362 html += *i + "/'>about:" + *i + "</a></li>\n"; | |
| 363 } | 367 } |
| 364 const char *debug[] = { "crash", "kill", "hang", "shorthang", | |
| 365 "gpuclean", "gpucrash", "gpuhang" }; | |
| 366 html += "</ul>\n<h2>For Debug</h2>\n" | 368 html += "</ul>\n<h2>For Debug</h2>\n" |
| 367 "<p>The following pages are for debugging purposes only. Because they " | 369 "<p>The following pages are for debugging purposes only. Because they " |
| 368 "crash or hang the renderer, they're not linked directly; you can type " | 370 "crash or hang the renderer, they're not linked directly; you can type " |
| 369 "them into the address bar if you need them.</p>\n<ul>"; | 371 "them into the address bar if you need them.</p>\n<ul>"; |
| 370 for (size_t i = 0; i < arraysize(debug); i++) | 372 for (size_t i = 0; i < arraysize(kDebugAboutPaths); i++) |
| 371 html += "<li>about:" + std::string(debug[i]) + "</li>\n"; | 373 html += "<li>about:" + std::string(kDebugAboutPaths[i]) + "</li>\n"; |
| 372 html += "</ul>\n</body></html>"; | 374 html += "</ul>\n</body></html>"; |
| 373 return html; | 375 return html; |
| 374 } | 376 } |
| 375 | 377 |
| 376 #if defined(OS_CHROMEOS) | 378 #if defined(OS_CHROMEOS) |
| 377 | 379 |
| 378 // Html output helper functions | 380 // Html output helper functions |
| 379 // TODO(stevenjb): L10N this. | 381 // TODO(stevenjb): L10N this. |
| 380 | 382 |
| 381 // Helper function to wrap Html with <th> tag. | 383 // Helper function to wrap Html with <th> tag. |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 // Where the results are fed to. | 597 // Where the results are fed to. |
| 596 scoped_refptr<AboutSource> source_; | 598 scoped_refptr<AboutSource> source_; |
| 597 | 599 |
| 598 // ID identifying the request. | 600 // ID identifying the request. |
| 599 int request_id_; | 601 int request_id_; |
| 600 | 602 |
| 601 DISALLOW_COPY_AND_ASSIGN(AboutDnsHandler); | 603 DISALLOW_COPY_AND_ASSIGN(AboutDnsHandler); |
| 602 }; | 604 }; |
| 603 | 605 |
| 604 #if defined(USE_TCMALLOC) | 606 #if defined(USE_TCMALLOC) |
| 605 std::string AboutTcmalloc(const std::string& query) { | 607 std::string AboutTcmalloc() { |
| 606 std::string data; | 608 std::string data; |
| 607 AboutTcmallocOutputsType* outputs = | 609 AboutTcmallocOutputsType* outputs = |
| 608 AboutTcmallocOutputs::GetInstance()->outputs(); | 610 AboutTcmallocOutputs::GetInstance()->outputs(); |
| 609 | 611 |
| 610 // Display any stats for which we sent off requests the last time. | 612 // Display any stats for which we sent off requests the last time. |
| 611 data.append("<html><head><title>About tcmalloc</title></head><body>\n"); | 613 data.append("<html><head><title>About tcmalloc</title></head><body>\n"); |
| 612 data.append("<p>Stats as of last page load;"); | 614 data.append("<p>Stats as of last page load;"); |
| 613 data.append("reload to get stats as of this page load.</p>\n"); | 615 data.append("reload to get stats as of this page load.</p>\n"); |
| 614 data.append("<table width=\"100%\">\n"); | 616 data.append("<table width=\"100%\">\n"); |
| 615 for (AboutTcmallocOutputsType::const_iterator oit = outputs->begin(); | 617 for (AboutTcmallocOutputsType::const_iterator oit = outputs->begin(); |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1015 base::StringPiece version_html( | 1017 base::StringPiece version_html( |
| 1016 ResourceBundle::GetSharedInstance().GetRawDataResource( | 1018 ResourceBundle::GetSharedInstance().GetRawDataResource( |
| 1017 IDR_ABOUT_VERSION_HTML)); | 1019 IDR_ABOUT_VERSION_HTML)); |
| 1018 | 1020 |
| 1019 return jstemplate_builder::GetTemplatesHtml( | 1021 return jstemplate_builder::GetTemplatesHtml( |
| 1020 version_html, localized_strings, "t" /* template root node id */); | 1022 version_html, localized_strings, "t" /* template root node id */); |
| 1021 } | 1023 } |
| 1022 | 1024 |
| 1023 // AboutSource ----------------------------------------------------------------- | 1025 // AboutSource ----------------------------------------------------------------- |
| 1024 | 1026 |
| 1025 AboutSource::AboutSource() | 1027 AboutSource::AboutSource(const std::string& source_name, Profile* profile) |
| 1026 : DataSource(chrome::kAboutScheme, MessageLoop::current()) { | 1028 : DataSource(source_name, MessageLoop::current()), |
| 1027 } | |
| 1028 | |
| 1029 AboutSource::AboutSource(Profile* profile) | |
| 1030 : DataSource(chrome::kAboutScheme, MessageLoop::current()), | |
| 1031 profile_(profile) { | 1029 profile_(profile) { |
| 1032 } | 1030 } |
| 1033 | 1031 |
| 1034 AboutSource::~AboutSource() { | 1032 AboutSource::~AboutSource() { |
| 1035 } | 1033 } |
| 1036 | 1034 |
| 1037 void AboutSource::StartDataRequest(const std::string& path_raw, | 1035 void AboutSource::StartDataRequest(const std::string& path, |
| 1038 bool is_incognito, int request_id) { | 1036 bool is_incognito, |
| 1039 std::string path = path_raw; | 1037 int request_id) { |
| 1040 std::string info; | |
| 1041 if (path.find("/") != std::string::npos) { | |
| 1042 size_t pos = path.find("/"); | |
| 1043 info = path.substr(pos + 1, path.length() - (pos + 1)); | |
| 1044 path = path.substr(0, pos); | |
| 1045 } | |
| 1046 path = StringToLowerASCII(path); | |
| 1047 | |
| 1048 std::string response; | 1038 std::string response; |
| 1049 if (path == kDnsPath) { | 1039 std::string host = source_name(); |
| 1040 if (host == chrome::kChromeUIDNSHost) { | |
| 1050 AboutDnsHandler::Start(this, request_id); | 1041 AboutDnsHandler::Start(this, request_id); |
| 1051 return; | 1042 return; |
| 1052 } else if (path == kHistogramsPath) { | 1043 } else if (host == chrome::kChromeUIHistogramsHost) { |
| 1053 response = AboutHistograms(info); | 1044 response = AboutHistograms(path); |
| 1054 } else if (path == kMemoryPath) { | 1045 } else if (host == chrome::kChromeUIMemoryHost) { |
| 1046 response = GetAboutMemoryRedirectResponse(profile()); | |
| 1047 } else if (host == chrome::kChromeUIMemoryRedirectHost) { | |
| 1055 AboutMemory(this, request_id); | 1048 AboutMemory(this, request_id); |
| 1056 return; | 1049 return; |
| 1057 } else if (path == kMemoryRedirectPath) { | |
| 1058 response = GetAboutMemoryRedirectResponse(); | |
| 1059 #ifdef TRACK_ALL_TASK_OBJECTS | 1050 #ifdef TRACK_ALL_TASK_OBJECTS |
| 1060 } else if (path == kTasksPath) { | 1051 } else if (host == chrome::kChromeUITasksHost) { |
| 1061 response = AboutObjects(info); | 1052 response = AboutObjects(path); |
| 1062 #endif | 1053 #endif |
| 1063 } else if (path == kStatsPath) { | 1054 } else if (host == chrome::kChromeUIStatsHost) { |
| 1064 response = AboutStats(info); | 1055 response = AboutStats(path); |
| 1065 #if defined(USE_TCMALLOC) | 1056 #if defined(USE_TCMALLOC) |
| 1066 } else if (path == kTcmallocPath) { | 1057 } else if (host == chrome::kChromeUITCMallocHost) { |
| 1067 response = AboutTcmalloc(info); | 1058 response = AboutTcmalloc(); |
| 1068 #endif | 1059 #endif |
| 1069 } else if (path == kVersionPath || path.empty()) { | 1060 } else if (host == chrome::kChromeUIVersionHost) { |
| 1070 #if defined(OS_CHROMEOS) | 1061 #if defined(OS_CHROMEOS) |
| 1071 new ChromeOSAboutVersionHandler(this, request_id); | 1062 new ChromeOSAboutVersionHandler(this, request_id); |
| 1072 return; | 1063 return; |
| 1073 #else | 1064 #else |
| 1074 DictionaryValue localized_strings; | 1065 DictionaryValue localized_strings; |
| 1075 localized_strings.SetString("os_version", ""); | 1066 localized_strings.SetString("os_version", ""); |
| 1076 response = AboutVersion(&localized_strings, profile_); | 1067 response = AboutVersion(&localized_strings, profile_); |
| 1077 #endif | 1068 #endif |
| 1078 } else if (path == kCreditsPath) { | 1069 } else if (host == chrome::kChromeUICreditsHost) { |
| 1079 response = ResourceBundle::GetSharedInstance().GetRawDataResource( | 1070 response = ResourceBundle::GetSharedInstance().GetRawDataResource( |
| 1080 IDR_CREDITS_HTML).as_string(); | 1071 IDR_CREDITS_HTML).as_string(); |
| 1081 } else if (path == kAboutPath) { | 1072 } else if (host == chrome::kChromeUIAboutHost) { |
| 1082 response = AboutAbout(); | 1073 response = AboutAbout(); |
| 1083 #if defined(OS_CHROMEOS) | 1074 #if defined(OS_CHROMEOS) |
| 1084 } else if (path == kOSCreditsPath) { | 1075 } else if (host == chrome::kChromeUIOSCreditsHost) { |
| 1085 response = ResourceBundle::GetSharedInstance().GetRawDataResource( | 1076 response = ResourceBundle::GetSharedInstance().GetRawDataResource( |
| 1086 IDR_OS_CREDITS_HTML).as_string(); | 1077 IDR_OS_CREDITS_HTML).as_string(); |
| 1087 } else if (path == kNetworkPath) { | 1078 } else if (host == chrome::kChromeUINetworkHost) { |
| 1088 response = AboutNetwork(info); | 1079 response = AboutNetwork(path); |
| 1089 #endif | 1080 #endif |
| 1090 } else if (path == kTermsPath) { | 1081 } else if (host == chrome::kChromeUITermsHost) { |
| 1091 #if defined(OS_CHROMEOS) | 1082 #if defined(OS_CHROMEOS) |
| 1092 ChromeOSTermsHandler::Start(this, request_id); | 1083 ChromeOSTermsHandler::Start(this, request_id); |
| 1093 return; | 1084 return; |
| 1094 #else | 1085 #else |
| 1095 response = ResourceBundle::GetSharedInstance().GetRawDataResource( | 1086 response = ResourceBundle::GetSharedInstance().GetRawDataResource( |
| 1096 IDR_TERMS_HTML).as_string(); | 1087 IDR_TERMS_HTML).as_string(); |
| 1097 #endif | 1088 #endif |
| 1098 #if defined(OS_LINUX) | 1089 #if defined(OS_LINUX) |
| 1099 } else if (path == kLinuxProxyConfigPath) { | 1090 } else if (host == chrome::kChromeUILinuxProxyConfigHost) { |
| 1100 response = AboutLinuxProxyConfig(); | 1091 response = AboutLinuxProxyConfig(); |
| 1101 } else if (path == kSandboxPath) { | 1092 } else if (host == chrome::kChromeUISandboxHost) { |
| 1102 response = AboutSandbox(); | 1093 response = AboutSandbox(); |
| 1103 #endif | 1094 #endif |
| 1104 } | 1095 } |
| 1105 | 1096 |
| 1106 FinishDataRequest(response, request_id); | 1097 FinishDataRequest(response, request_id); |
| 1107 } | 1098 } |
| 1108 | 1099 |
| 1109 void AboutSource::FinishDataRequest(const std::string& response, | 1100 void AboutSource::FinishDataRequest(const std::string& html, int request_id) { |
| 1110 int request_id) { | |
| 1111 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); | 1101 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); |
| 1112 html_bytes->data.resize(response.size()); | 1102 html_bytes->data.resize(html.size()); |
| 1113 std::copy(response.begin(), response.end(), html_bytes->data.begin()); | 1103 std::copy(html.begin(), html.end(), html_bytes->data.begin()); |
| 1114 SendResponse(request_id, html_bytes); | 1104 SendResponse(request_id, html_bytes); |
| 1115 } | 1105 } |
| 1116 | 1106 |
| 1117 // AboutMemoryHandler ---------------------------------------------------------- | 1107 // AboutMemoryHandler ---------------------------------------------------------- |
| 1118 | 1108 |
| 1119 // Helper for AboutMemory to bind results from a ProcessMetrics object | 1109 // Helper for AboutMemory to bind results from a ProcessMetrics object |
| 1120 // to a DictionaryValue. Fills ws_usage and comm_usage so that the objects | 1110 // to a DictionaryValue. Fills ws_usage and comm_usage so that the objects |
| 1121 // can be used in caller's scope (e.g for appending to a net total). | 1111 // can be used in caller's scope (e.g for appending to a net total). |
| 1122 void AboutMemoryHandler::BindProcessMetrics(DictionaryValue* data, | 1112 void AboutMemoryHandler::BindProcessMetrics(DictionaryValue* data, |
| 1123 ProcessMemoryInformation* info) { | 1113 ProcessMemoryInformation* info) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1267 source_->FinishDataRequest(AboutVersion(&localized_strings, | 1257 source_->FinishDataRequest(AboutVersion(&localized_strings, |
| 1268 source_->profile()), request_id_); | 1258 source_->profile()), request_id_); |
| 1269 | 1259 |
| 1270 // CancelableRequestProvider isn't happy when it's deleted and servicing a | 1260 // CancelableRequestProvider isn't happy when it's deleted and servicing a |
| 1271 // task, so we delay the deletion. | 1261 // task, so we delay the deletion. |
| 1272 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1262 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 1273 } | 1263 } |
| 1274 | 1264 |
| 1275 #endif | 1265 #endif |
| 1276 | 1266 |
| 1277 // Returns true if |url|'s spec starts with |about_specifier|, and is | |
| 1278 // terminated by the start of a path. | |
| 1279 bool StartsWithAboutSpecifier(const GURL& url, const char* about_specifier) { | |
| 1280 return StartsWithASCII(url.spec(), about_specifier, true) && | |
| 1281 (url.spec().size() == strlen(about_specifier) || | |
| 1282 url.spec()[strlen(about_specifier)] == '/'); | |
| 1283 } | |
| 1284 | |
| 1285 // Transforms a URL of the form "about:foo/XXX" to <url_prefix> + "XXX". | |
| 1286 GURL RemapAboutURL(const std::string& url_prefix, const GURL& url) { | |
| 1287 std::string path; | |
| 1288 size_t split = url.spec().find('/'); | |
| 1289 if (split != std::string::npos) | |
| 1290 path = url.spec().substr(split + 1); | |
| 1291 return GURL(url_prefix + path); | |
| 1292 } | |
| 1293 | |
| 1294 } // namespace | 1267 } // namespace |
| 1295 | 1268 |
| 1296 // ----------------------------------------------------------------------------- | 1269 // ----------------------------------------------------------------------------- |
| 1297 | 1270 |
| 1298 bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) { | 1271 bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) { |
| 1299 // We only handle about: schemes. | 1272 if (!url->SchemeIs(chrome::kAboutScheme) && |
| 1300 if (!url->SchemeIs(chrome::kAboutScheme)) | 1273 !url->SchemeIs(chrome::kChromeUIScheme)) |
| 1301 return false; | 1274 return false; |
| 1302 | 1275 |
| 1303 // about:blank is special. Frames are allowed to access about:blank, | 1276 // about:blank is special. Frames are allowed to access about:blank, |
| 1304 // but they are not allowed to access other types of about pages. | 1277 // but they are not allowed to access other types of about pages. |
| 1305 // Just ignore the about:blank and let the TAB_CONTENTS_WEB handle it. | 1278 // Just ignore the about:blank and let the TAB_CONTENTS_WEB handle it. |
| 1306 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutBlankURL)) | 1279 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutBlankURL)) |
| 1307 return false; | 1280 return false; |
| 1308 | 1281 |
| 1309 // Rewrite about:cache/* URLs to chrome://view-http-cache/* | |
| 1310 if (StartsWithAboutSpecifier(*url, chrome::kAboutCacheURL)) { | |
| 1311 *url = RemapAboutURL(chrome::kNetworkViewCacheURL, *url); | |
| 1312 return true; | |
| 1313 } | |
| 1314 | |
| 1315 #if defined(OS_WIN) | |
| 1316 // Rewrite about:conflicts/* URLs to chrome://conflicts/* | |
| 1317 if (StartsWithAboutSpecifier(*url, chrome::kAboutConflicts)) { | |
| 1318 *url = GURL(chrome::kChromeUIConflictsURL); | |
| 1319 return true; | |
| 1320 } | |
| 1321 #endif | |
| 1322 | |
| 1323 // Rewrite about:flags to chrome://flags/. | |
| 1324 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutFlagsURL)) { | |
| 1325 *url = GURL(chrome::kChromeUIFlagsURL); | |
| 1326 return true; | |
| 1327 } | |
| 1328 | |
| 1329 // Rewrite about:flash to chrome://flash/. | |
| 1330 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutFlashURL)) { | |
| 1331 *url = GURL(chrome::kChromeUIFlashURL); | |
| 1332 return true; | |
| 1333 } | |
| 1334 | |
| 1335 // Rewrite about:net-internals/* URLs to chrome://net-internals/* | |
| 1336 if (StartsWithAboutSpecifier(*url, chrome::kAboutNetInternalsURL)) { | |
| 1337 *url = RemapAboutURL(chrome::kNetworkViewInternalsURL, *url); | |
| 1338 return true; | |
| 1339 } | |
| 1340 | |
| 1341 // Rewrite about:gpu/* URLs to chrome://gpu-internals/* | |
| 1342 if (StartsWithAboutSpecifier(*url, chrome::kAboutGpuURL)) { | |
| 1343 *url = RemapAboutURL(chrome::kGpuInternalsURL, *url); | |
| 1344 return true; | |
| 1345 } | |
| 1346 | |
| 1347 // Rewrite about:appcache-internals/* URLs to chrome://appcache/* | |
| 1348 if (StartsWithAboutSpecifier(*url, chrome::kAboutAppCacheInternalsURL)) { | |
| 1349 *url = RemapAboutURL(chrome::kAppCacheViewInternalsURL, *url); | |
| 1350 return true; | |
| 1351 } | |
| 1352 | |
| 1353 // Rewrite about:sync-internals/* URLs (and about:sync, too, for | |
| 1354 // legacy reasons) to chrome://sync-internals/* | |
| 1355 if (StartsWithAboutSpecifier(*url, chrome::kAboutSyncInternalsURL) || | |
| 1356 StartsWithAboutSpecifier(*url, chrome::kAboutSyncURL)) { | |
| 1357 *url = RemapAboutURL(chrome::kSyncViewInternalsURL, *url); | |
| 1358 return true; | |
| 1359 } | |
| 1360 | |
| 1361 // Rewrite about:plugins to chrome://plugins/. | |
| 1362 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutPluginsURL)) { | |
| 1363 *url = GURL(chrome::kChromeUIPluginsURL); | |
| 1364 return true; | |
| 1365 } | |
| 1366 | |
| 1367 // Handle URL to crash the browser process. | |
| 1368 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutBrowserCrash)) { | |
| 1369 // Induce an intentional crash in the browser process. | |
| 1370 int* bad_pointer = NULL; | |
| 1371 *bad_pointer = 42; | |
| 1372 return true; | |
| 1373 } | |
| 1374 | |
| 1375 // Handle URLs to wreck the gpu process. | |
| 1376 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutGpuCleanURL)) { | |
| 1377 GpuProcessHost::SendOnIO( | |
| 1378 0, content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, new GpuMsg_Clean()); | |
| 1379 } | |
| 1380 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutGpuCrashURL)) { | |
| 1381 GpuProcessHost::SendOnIO( | |
| 1382 0, content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUCRASH, new GpuMsg_Crash()); | |
| 1383 } | |
| 1384 if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutGpuHangURL)) { | |
| 1385 GpuProcessHost::SendOnIO( | |
| 1386 0, content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUHANG, new GpuMsg_Hang()); | |
| 1387 } | |
| 1388 | |
| 1389 // There are a few about: URLs that we hand over to the renderer. If the | 1282 // There are a few about: URLs that we hand over to the renderer. If the |
| 1390 // renderer wants them, don't do any rewriting. | 1283 // renderer wants them, don't do any rewriting. |
| 1391 if (chrome_about_handler::WillHandle(*url)) | 1284 if (chrome_about_handler::WillHandle(*url)) |
| 1392 return false; | 1285 return false; |
| 1393 | 1286 |
| 1394 // Anything else requires our special handler; make sure it's initialized. | 1287 // Set the scheme to chrome://. WebKit treats all about: URLS as about:blank, |
| 1395 InitializeAboutDataSource(profile); | 1288 // so we need another scheme to display content. Doing this scheme fixup in |
| 1289 // URLFixerUpper::FixupURL would break extensions that override about: URLs. | |
| 1290 *url = URLFixerUpper::FixupChromeURL(*url); | |
| 1396 | 1291 |
| 1397 // Special case about:memory to go through a redirect before ending up on | 1292 std::string host(url->host()); |
| 1398 // the final page. See GetAboutMemoryRedirectResponse above for why. | 1293 // Replace cache with view-http-cache. |
| 1399 if (LowerCaseEqualsASCII(url->path(), kMemoryPath)) { | 1294 if (host == chrome::kChromeUICacheHost) |
| 1400 *url = GURL("chrome://about/memory-redirect"); | 1295 host = chrome::kChromeUINetworkViewCacheHost; |
| 1296 // Replace gpu with gpu-internals. | |
| 1297 else if (host == chrome::kChromeUIGpuHost) | |
| 1298 host = chrome::kChromeUIGpuInternalsHost; | |
| 1299 // Replace sync with sync-internals (for legacy reasons). | |
| 1300 else if (host == chrome::kChromeUISyncHost) | |
| 1301 host = chrome::kChromeUISyncInternalsHost; | |
| 1302 GURL::Replacements replacements; | |
| 1303 replacements.SetHostStr(host); | |
| 1304 *url = url->ReplaceComponents(replacements); | |
|
abarth-chromium
2011/05/31 19:27:54
Do we need to do all the replacements? It would b
msw
2011/05/31 20:58:25
Only the host may need replacement here. The schem
| |
| 1305 | |
| 1306 // Handle URLs to crash the browser or wreck the gpu process. | |
| 1307 if (host == chrome::kChromeUIBrowserCrashHost) { | |
| 1308 // Induce an intentional crash in the browser process. | |
| 1309 int* bad_pointer = NULL; | |
|
abarth-chromium
2011/05/31 19:27:54
This needs to be "volatile" right?
msw
2011/05/31 20:58:25
I'm following pkasting's offline suggestion to cha
| |
| 1310 *bad_pointer = 42; | |
| 1401 return true; | 1311 return true; |
| 1312 } else if (host == chrome::kChromeUIGpuCleanHost) { | |
| 1313 GpuProcessHost::SendOnIO( | |
| 1314 0, content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, new GpuMsg_Clean()); | |
| 1315 } else if (host == chrome::kChromeUIGpuCrashHost) { | |
| 1316 GpuProcessHost::SendOnIO( | |
| 1317 0, content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUCRASH, new GpuMsg_Crash()); | |
| 1318 } else if (host == chrome::kChromeUIGpuHangHost) { | |
| 1319 GpuProcessHost::SendOnIO( | |
| 1320 0, content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUHANG, new GpuMsg_Hang()); | |
| 1402 } | 1321 } |
| 1403 | 1322 |
| 1404 // Rewrite the about URL to use chrome:. WebKit treats all about URLS the | 1323 // Initialize any potentially corresponding AboutSource handler. |
| 1405 // same (blank page), so if we want to display content, we need another | 1324 InitializeAboutDataSource(host, profile); |
| 1406 // scheme. | |
| 1407 std::string about_url = "chrome://about/"; | |
| 1408 about_url.append(url->path()); | |
| 1409 *url = GURL(about_url); | |
| 1410 return true; | 1325 return true; |
| 1411 } | 1326 } |
| 1412 | 1327 |
| 1413 void InitializeAboutDataSource(Profile* profile) { | |
| 1414 profile->GetChromeURLDataManager()->AddDataSource(new AboutSource(profile)); | |
| 1415 } | |
| 1416 | |
| 1417 // This function gets called with the fixed-up chrome: URLs, so we have to | 1328 // This function gets called with the fixed-up chrome: URLs, so we have to |
| 1418 // compare against those instead of "about:blah". | 1329 // compare against those instead of "about:blah". |
| 1419 bool HandleNonNavigationAboutURL(const GURL& url) { | 1330 bool HandleNonNavigationAboutURL(const GURL& url) { |
| 1420 // about:ipc is currently buggy, so we disable it for official builds. | 1331 // about:ipc is currently buggy, so we disable it for official builds. |
| 1421 #if !defined(OFFICIAL_BUILD) | 1332 #if !defined(OFFICIAL_BUILD) |
| 1422 | 1333 |
| 1423 #if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED) | 1334 #if (defined(OS_MACOSX) || defined(OS_WIN)) && defined(IPC_MESSAGE_LOG_ENABLED) |
| 1424 if (LowerCaseEqualsASCII(url.spec(), chrome::kChromeUIIPCURL)) { | 1335 if (LowerCaseEqualsASCII(url.spec(), chrome::kChromeUIIPCURL)) { |
| 1425 // Run the dialog. This will re-use the existing one if it's already up. | 1336 // Run the dialog. This will re-use the existing one if it's already up. |
| 1426 browser::ShowAboutIPCDialog(); | 1337 browser::ShowAboutIPCDialog(); |
| 1427 return true; | 1338 return true; |
| 1428 } | 1339 } |
| 1429 #endif | 1340 #endif |
| 1430 | 1341 |
| 1431 #endif // OFFICIAL_BUILD | 1342 #endif // OFFICIAL_BUILD |
| 1432 | 1343 |
| 1433 return false; | 1344 return false; |
| 1434 } | 1345 } |
| 1435 | 1346 |
| 1436 std::vector<std::string> AboutPaths() { | 1347 std::vector<std::string> AboutPaths() { |
| 1437 std::vector<std::string> paths; | 1348 std::vector<std::string> paths; |
| 1438 paths.reserve(arraysize(kAllAboutPaths)); | 1349 paths.reserve(arraysize(kAllAboutPaths)); |
| 1439 for (size_t i = 0; i < arraysize(kAllAboutPaths); i++) | 1350 for (size_t i = 0; i < arraysize(kAllAboutPaths); i++) |
| 1440 paths.push_back(kAllAboutPaths[i]); | 1351 paths.push_back(kAllAboutPaths[i]); |
| 1441 return paths; | 1352 return paths; |
| 1442 } | 1353 } |
| OLD | NEW |