Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / chromeos / system_logs / touch_log_source_ozone.cc
blobe812047f498b0c1d03ecb3b9835ebc023f216dce
1 // Copyright (c) 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.
5 #include "chrome/browser/chromeos/system_logs/touch_log_source.h"
7 #include "ash/touch/touch_hud_debug.h"
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/callback.h"
11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/json/json_string_value_serializer.h"
15 #include "base/logging.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/process/launch.h"
18 #include "components/feedback/feedback_util.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "ui/ozone/public/input_controller.h"
21 #include "ui/ozone/public/ozone_platform.h"
23 using content::BrowserThread;
25 namespace {
27 const char kHUDLogDataKey[] = "hud_log";
29 // The prefix "hack-33025" was historically chosen in http://crbug.com/139715.
30 // We continue to go with it in order to be compatible with the existing touch
31 // log processing toolchain.
32 const char kDeviceStatusLogDataKey[] = "hack-33025-touchpad";
33 const char kTouchpadEventLogDataKey[] = "hack-33025-touchpad_activity";
34 const char kTouchscreenEventLogDataKey[] = "hack-33025-touchscreen_activity";
36 // Directory for temp touch event logs.
37 const char kTouchEventLogDir[] = "/home/chronos/user/log";
39 // Prefixes of touch event logs.
40 const char kTouchpadGestureLogPrefix[] = "touchpad_activity_";
41 const char kTouchscreenLogPrefix[] = "evdev_input_events_";
42 const char kTouchpadEvdevLogPrefix[] = "cmt_input_events_";
44 // Binary paths.
45 const char kShellCommand[] = "/bin/sh";
46 const char kTarCommand[] = "/bin/tar cf -";
47 const char kUuencodeCommand[] = "/usr/bin/uuencode";
49 const int kMaxDeviceTouchEventLogs = 7;
51 // Clean up intermediate log files dumped during feedback creation.
52 void CleanupEventLog(scoped_ptr<std::vector<base::FilePath>> log_paths) {
53 for (size_t i = 0; i < log_paths->size(); ++i)
54 base::DeleteFile((*log_paths)[i], false);
57 // Check for all known log paths and find the ones whose filenames match a
58 // prefix. Concatenate their filenames into one string. |max_log_count| is
59 // the maximum number of logs that we will collect.
61 // This is used to distinguish touchpad/mice logs from touchscreen logs.
62 std::string GetEventLogListOfOnePrefix(
63 const std::vector<base::FilePath>& log_paths,
64 const std::string& prefix,
65 const int max_log_count) {
66 int collected = 0;
67 std::string log_list;
68 for (size_t i = 0; i < log_paths.size(); ++i) {
69 const std::string basename = log_paths[i].BaseName().value();
70 if (base::StartsWith(basename, prefix, base::CompareCase::SENSITIVE)) {
71 log_list.append(" " + log_paths[i].value());
73 // Limit the max number of collected logs to shorten the log collection
74 // process.
75 if (++collected >= max_log_count)
76 break;
80 return log_list;
83 // Pack the collected event logs in a way that is compatible with the log
84 // analysis tools.
85 void PackEventLog(system_logs::SystemLogsResponse* response,
86 scoped_ptr<std::vector<base::FilePath>> log_paths) {
87 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
89 // Combine logs with a command line call that tars them up and uuencode the
90 // result in one string. This is to be compatible with the X11 behavior.
91 std::vector<std::pair<std::string, base::CommandLine>> commands;
92 base::CommandLine command = base::CommandLine(base::FilePath(kShellCommand));
93 command.AppendArg("-c");
95 // Make a list that contains touchpad (and mouse) event logs only.
96 const std::string touchpad_log_list =
97 GetEventLogListOfOnePrefix(*log_paths, kTouchpadGestureLogPrefix,
98 kMaxDeviceTouchEventLogs) +
99 GetEventLogListOfOnePrefix(*log_paths, kTouchpadEvdevLogPrefix,
100 kMaxDeviceTouchEventLogs);
101 command.AppendArg(std::string(kTarCommand) + touchpad_log_list +
102 " 2>/dev/null | " + kUuencodeCommand +
103 " -m touchpad_activity_log.tar");
105 commands.push_back(std::make_pair(kTouchpadEventLogDataKey, command));
107 base::CommandLine ts_command =
108 base::CommandLine(base::FilePath(kShellCommand));
109 ts_command.AppendArg("-c");
111 // Make a list that contains touchscreen event logs only.
112 const std::string touchscreen_log_list = GetEventLogListOfOnePrefix(
113 *log_paths, kTouchscreenLogPrefix, kMaxDeviceTouchEventLogs);
114 ts_command.AppendArg(std::string(kTarCommand) + touchscreen_log_list +
115 " 2>/dev/null | " + kUuencodeCommand +
116 " -m touchscreen_activity_log.tar");
118 commands.push_back(std::make_pair(kTouchscreenEventLogDataKey, ts_command));
120 // For now only touchpad (and mouse) logs are actually collected.
121 for (size_t i = 0; i < commands.size(); ++i) {
122 std::string output;
123 base::GetAppOutput(commands[i].second, &output);
124 (*response)[commands[i].first] = output;
127 // Cleanup these temporary log files.
128 BrowserThread::PostBlockingPoolTask(
129 FROM_HERE, base::Bind(CleanupEventLog, base::Passed(&log_paths)));
132 // Callback for handing the outcome of GetTouchEventLog().
134 // This is the end of the whole touch log collection process.
135 void OnEventLogCollected(scoped_ptr<system_logs::SystemLogsResponse> response,
136 const system_logs::SysLogsSourceCallback& callback,
137 scoped_ptr<std::vector<base::FilePath>> log_paths) {
138 DCHECK_CURRENTLY_ON(BrowserThread::UI);
140 // We cannot eliminate these temporaries and inline these closures because the
141 // compiler may call release() before get().
142 const base::Closure pack_closure =
143 base::Bind(&PackEventLog, base::Unretained(response.get()),
144 base::Passed(&log_paths));
145 const base::Closure callback_closure =
146 base::Bind(callback, base::Owned(response.release()));
147 BrowserThread::PostBlockingPoolTaskAndReply(FROM_HERE, pack_closure,
148 callback_closure);
151 // Callback for handing the outcome of GetTouchDeviceStatus().
153 // Appends the collected log to the SystemLogsResponse map. Also goes on to
154 // collect touch event logs.
155 void OnStatusLogCollected(scoped_ptr<system_logs::SystemLogsResponse> response,
156 const system_logs::SysLogsSourceCallback& callback,
157 scoped_ptr<std::string> log) {
158 DCHECK_CURRENTLY_ON(BrowserThread::UI);
159 (*response)[kDeviceStatusLogDataKey] = *log;
161 // Collect touch event logs.
162 const base::FilePath kBaseLogPath(kTouchEventLogDir);
163 ui::OzonePlatform::GetInstance()->GetInputController()->GetTouchEventLog(
164 kBaseLogPath,
165 base::Bind(&OnEventLogCollected, base::Passed(&response), callback));
168 // Collect touch HUD debug logs. This needs to be done on the UI thread.
169 void CollectTouchHudDebugLog(system_logs::SystemLogsResponse* response) {
170 scoped_ptr<base::DictionaryValue> dictionary =
171 ash::TouchHudDebug::GetAllAsDictionary();
172 if (!dictionary->empty()) {
173 std::string touch_log;
174 JSONStringValueSerializer json(&touch_log);
175 json.set_pretty_print(true);
176 if (json.Serialize(*dictionary) && !touch_log.empty())
177 (*response)[kHUDLogDataKey] = touch_log;
181 } // namespace
183 namespace system_logs {
185 void TouchLogSource::Fetch(const SysLogsSourceCallback& callback) {
186 DCHECK_CURRENTLY_ON(BrowserThread::UI);
187 DCHECK(!callback.is_null());
189 scoped_ptr<SystemLogsResponse> response(new SystemLogsResponse);
190 CollectTouchHudDebugLog(response.get());
192 // Collect touch device status logs.
193 ui::OzonePlatform::GetInstance()->GetInputController()->GetTouchDeviceStatus(
194 base::Bind(&OnStatusLogCollected, base::Passed(&response), callback));
197 } // namespace system_logs