[go: nahoru, domu]

Fix for flow control in terminalPrivate API

Fixes problem where terminalPrivate API floods IPC channel by sending
crosh extension too many onProcessOutput events in short amount of
time.

The API uses chromeos/process_proxy/process_output_watcher to observe
stdout of terminal process. Whenever some data is detected a
chrome.terminalPrivate.onProcessOutput event is dispatched to crosh
extension with the observed data. This may overwhelm communication
channel to the extension when there is too much output from the
process.

To fix this the following is done:
- When process_output_watcher sends some data, further process output
  observation/reporting is paused until the sent data is acknowledged
  by the receiver.
- Callback used by process_output_watcher is passed a closure that
  unpauses the process_output_watcher. The callback is cached before
  sending chrome.terminalPrivate.onProcessOutput event.
- chrome.terminalPrivate.ackOutput(int terminalId) is introduced that
  invokes cached (if it exists) the closure for the terminal process
  identified by terminalId.
- When chrome.terminalPrivate.onProcessOutput is dispatched to the
  extension code, terminalPrivate.ackOutput is called for the target
  terminal. This is done internally in the APIs custom bindings
  (from the extension renderer process).
- To ensure process output is acknowledged at most once,
  terminalPrivate.onProcessOutput is internally passed target tab ID
  as an argument. The tab ID is passed back as an argument of ackOutput,
  and the method is ignored if called from web contents with different
  tab ID. The tab ID is stripped from the argument list before
  dispatching onProcessOutput event to the extension.

BUG=527475, 398901

Review URL: https://codereview.chromium.org/1455793003

Cr-Commit-Position: refs/heads/master@{#368277}
diff --git a/chromeos/process_proxy/process_output_watcher_unittest.cc b/chromeos/process_proxy/process_output_watcher_unittest.cc
index 75373812..306113b 100644
--- a/chromeos/process_proxy/process_output_watcher_unittest.cc
+++ b/chromeos/process_proxy/process_output_watcher_unittest.cc
@@ -105,7 +105,9 @@
       output_watch_thread_->Stop();
   }
 
-  void OnRead(ProcessOutputType type, const std::string& output) {
+  void OnRead(ProcessOutputType type,
+              const std::string& output,
+              const base::Closure& ack_callback) {
     ASSERT_FALSE(failed_);
     // There may be an EXIT signal sent during test tear down (which is sent
     // by process output watcher when master end of test pseudo-terminal is
@@ -123,6 +125,9 @@
                                             test_case_done_callback_);
       test_case_done_callback_.Reset();
     }
+
+    ASSERT_FALSE(ack_callback.is_null());
+    message_loop_.task_runner()->PostTask(FROM_HERE, ack_callback);
   }
 
  protected: