[M85 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / chrome / browser / memory_details_linux.cc
1 // Copyright (c) 2012 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/memory_details.h"
6
7 #include <stddef.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10
11 #include <map>
12 #include <memory>
13 #include <set>
14
15 #include "base/bind.h"
16 #include "base/files/file_util.h"
17 #include "base/process/process_iterator.h"
18 #include "base/process/process_metrics.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/threading/scoped_blocking_call.h"
23 #include "build/build_config.h"
24 #include "chrome/common/chrome_constants.h"
25 #include "chrome/grit/chromium_strings.h"
26 #include "content/public/browser/browser_task_traits.h"
27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/common/process_type.h"
29 #include "ui/base/l10n/l10n_util.h"
30
31 using base::ProcessEntry;
32 namespace {
33
34 struct Process {
35   pid_t pid;
36   pid_t parent;
37 };
38
39 typedef std::map<pid_t, Process> ProcessMap;
40
41 // Get information on all the processes running on the system.
42 ProcessMap GetProcesses() {
43   ProcessMap map;
44
45   base::ProcessIterator process_iter(NULL);
46   while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
47     Process process;
48     process.pid = process_entry->pid();
49     process.parent = process_entry->parent_pid();
50     map.insert(std::make_pair(process.pid, process));
51   }
52   return map;
53 }
54
55 // For each of a list of pids, collect memory information about that process.
56 ProcessData GetProcessDataMemoryInformation(
57     const std::vector<pid_t>& pids) {
58   ProcessData process_data;
59   for (pid_t pid : pids) {
60     ProcessMemoryInformation pmi;
61
62     pmi.pid = pid;
63     pmi.num_processes = 1;
64
65     if (pmi.pid == base::GetCurrentProcId())
66       pmi.process_type = content::PROCESS_TYPE_BROWSER;
67     else
68       pmi.process_type = content::PROCESS_TYPE_UNKNOWN;
69
70     std::unique_ptr<base::ProcessMetrics> metrics(
71         base::ProcessMetrics::CreateProcessMetrics(pid));
72     pmi.num_open_fds = metrics->GetOpenFdCount();
73     pmi.open_fds_soft_limit = metrics->GetOpenFdSoftLimit();
74
75     process_data.processes.push_back(pmi);
76   }
77   return process_data;
78 }
79
80 // Find all children of the given process with pid |root|.
81 std::vector<pid_t> GetAllChildren(const ProcessMap& processes, pid_t root) {
82   std::vector<pid_t> children;
83   children.push_back(root);
84
85   std::set<pid_t> wavefront, next_wavefront;
86   wavefront.insert(root);
87
88   while (wavefront.size()) {
89     for (const auto& entry : processes) {
90       const Process& process = entry.second;
91       if (wavefront.count(process.parent)) {
92         children.push_back(process.pid);
93         next_wavefront.insert(process.pid);
94       }
95     }
96
97     wavefront.clear();
98     wavefront.swap(next_wavefront);
99   }
100   return children;
101 }
102
103 }  // namespace
104
105 MemoryDetails::MemoryDetails() {
106 }
107
108 ProcessData* MemoryDetails::ChromeBrowser() {
109   return &process_data_[0];
110 }
111
112 void MemoryDetails::CollectProcessData(
113     const std::vector<ProcessMemoryInformation>& child_info) {
114   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
115                                                 base::BlockingType::MAY_BLOCK);
116
117   ProcessMap process_map = GetProcesses();
118   std::set<pid_t> browsers_found;
119
120   ProcessData current_browser =
121       GetProcessDataMemoryInformation(GetAllChildren(process_map, getpid()));
122   current_browser.name = l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME);
123   current_browser.process_name = base::ASCIIToUTF16("chrome");
124
125   for (auto i = current_browser.processes.begin();
126        i != current_browser.processes.end(); ++i) {
127     // Check if this is one of the child processes whose data we collected
128     // on the IO thread, and if so copy over that data.
129     for (size_t child = 0; child < child_info.size(); child++) {
130       if (child_info[child].pid != i->pid)
131         continue;
132       i->titles = child_info[child].titles;
133       i->process_type = child_info[child].process_type;
134       break;
135     }
136   }
137
138   process_data_.push_back(current_browser);
139
140 #if defined(OS_CHROMEOS)
141   base::GetSwapInfo(&swap_info_);
142 #endif
143
144   // Finally return to the browser thread.
145   content::GetUIThreadTaskRunner({})->PostTask(
146       FROM_HERE,
147       base::BindOnce(&MemoryDetails::CollectChildInfoOnUIThread, this));
148 }