Introduce net::CompletionOnceCallback.

Also convert net::FileStreamContext to use it, as a sample use case with
few consumers.

This CL does not add a OnceCallback version of TestCompletionCallback,
as the repeating version works for use with methods that take
OnceCallbacks.  I think not creating a new test class will make updating
interfaces take a lot less effort.

Also, I expect that all net::CompletionCallbacks are effectively used
as OnceCallbacks, so we can make TestCompletionCallback return
OnceCallbacks when/if we ever finish converting all of net to use
CompletionOnceCallbacks.

Bug: 714018
Change-Id: Iec76deae075b32fe0c65eb18596859f5e6413647
Reviewed-on: https://chromium-review.googlesource.com/853092
Commit-Queue: Matt Menke <[email protected]>
Reviewed-by: Randy Smith <[email protected]>
Cr-Commit-Position: refs/heads/master@{#533061}
diff --git a/content/browser/loader/redirect_to_file_resource_handler_unittest.cc b/content/browser/loader/redirect_to_file_resource_handler_unittest.cc
index ae7a525f..afdb0ef 100644
--- a/content/browser/loader/redirect_to_file_resource_handler_unittest.cc
+++ b/content/browser/loader/redirect_to_file_resource_handler_unittest.cc
@@ -28,6 +28,7 @@
 #include "content/browser/loader/test_resource_handler.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "net/base/completion_callback.h"
+#include "net/base/completion_once_callback.h"
 #include "net/base/file_stream.h"
 #include "net/base/io_buffer.h"
 #include "net/base/mime_sniffer.h"
@@ -91,16 +92,16 @@
 
   int Open(const base::FilePath& path,
            int open_flags,
-           const net::CompletionCallback& callback) override {
-    return ReturnResult(open_result_, callback);
+           net::CompletionOnceCallback callback) override {
+    return ReturnResult(open_result_, std::move(callback));
   }
 
-  int Close(const net::CompletionCallback& callback) override {
+  int Close(net::CompletionOnceCallback callback) override {
     EXPECT_FALSE(closed_);
     int result = ReturnResult(
         close_result_,
-        base::BindRepeating(&MockFileStream::SetClosedAndRunCallback,
-                            base::Unretained(this), callback));
+        base::BindOnce(&MockFileStream::SetClosedAndRunCallback,
+                       base::Unretained(this), std::move(callback)));
     if (result != net::ERR_IO_PENDING)
       closed_ = true;
     return result;
@@ -111,22 +112,21 @@
     return false;
   }
 
-  int Seek(int64_t offset,
-           const net::Int64CompletionCallback& callback) override {
+  int Seek(int64_t offset, net::Int64CompletionOnceCallback callback) override {
     NOTREACHED();
     return net::ERR_UNEXPECTED;
   }
 
   int Read(net::IOBuffer* buf,
            int buf_len,
-           const net::CompletionCallback& callback) override {
+           net::CompletionOnceCallback callback) override {
     NOTREACHED();
     return net::ERR_UNEXPECTED;
   }
 
   int Write(net::IOBuffer* buf,
             int buf_len,
-            const net::CompletionCallback& callback) override {
+            net::CompletionOnceCallback callback) override {
     // 0-byte writes aren't allowed.
     EXPECT_GT(buf_len, 0);
 
@@ -137,10 +137,10 @@
     if (write_result.result > 0)
       written_data_ += std::string(buf->data(), write_result.result);
 
-    return ReturnResult(write_result, callback);
+    return ReturnResult(write_result, std::move(callback));
   }
 
-  int Flush(const net::CompletionCallback& callback) override {
+  int Flush(net::CompletionOnceCallback callback) override {
     NOTREACHED();
     return net::ERR_UNEXPECTED;
   }
@@ -172,19 +172,19 @@
   void set_expect_closed(bool expect_closed) { expect_closed_ = expect_closed; }
 
  private:
-  void SetClosedAndRunCallback(const net::CompletionCallback& callback,
+  void SetClosedAndRunCallback(net::CompletionOnceCallback callback,
                                int result) {
     EXPECT_FALSE(closed_);
     closed_ = true;
-    callback.Run(result);
+    std::move(callback).Run(result);
   }
 
   int ReturnResult(OperationResult result,
-                   const net::CompletionCallback& callback) {
+                   net::CompletionOnceCallback callback) {
     if (result.completion_mode == CompletionMode::SYNC)
       return result.result;
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(callback, result.result));
+        FROM_HERE, base::BindOnce(std::move(callback), result.result));
     return net::ERR_IO_PENDING;
   }
 
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 89dfbe7..bbd62c1e 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -108,6 +108,7 @@
     "base/auth.cc",
     "base/auth.h",
     "base/completion_callback.h",
+    "base/completion_once_callback.h",
     "base/escape.cc",
     "base/escape.h",
     "base/hash_value.cc",
diff --git a/net/base/completion_callback.h b/net/base/completion_callback.h
index a41caa5..78658bd8 100644
--- a/net/base/completion_callback.h
+++ b/net/base/completion_callback.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef NET_BASE_COMPLETION_CALLBACK_H__
-#define NET_BASE_COMPLETION_CALLBACK_H__
+#ifndef NET_BASE_COMPLETION_CALLBACK_H_
+#define NET_BASE_COMPLETION_CALLBACK_H_
 
 #include <stdint.h>
 
@@ -25,4 +25,4 @@
 
 }  // namespace net
 
-#endif  // NET_BASE_COMPLETION_CALLBACK_H__
+#endif  // NET_BASE_COMPLETION_CALLBACK_H_
diff --git a/net/base/completion_once_callback.h b/net/base/completion_once_callback.h
new file mode 100644
index 0000000..bfe4e7c7
--- /dev/null
+++ b/net/base/completion_once_callback.h
@@ -0,0 +1,29 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_COMPLETION_ONCE_CALLBACK_H_
+#define NET_BASE_COMPLETION_ONCE_CALLBACK_H_
+
+#include <stdint.h>
+
+#include "base/callback.h"
+#include "base/cancelable_callback.h"
+
+namespace net {
+
+// A OnceCallback specialization that takes a single int parameter. Usually this
+// is used to report a byte count or network error code.
+typedef base::OnceCallback<void(int)> CompletionOnceCallback;
+
+// 64bit version of the OnceCallback specialization that takes a single int64_t
+// parameter. Usually this is used to report a file offset, size or network
+// error code.
+typedef base::OnceCallback<void(int64_t)> Int64CompletionOnceCallback;
+
+typedef base::CancelableOnceCallback<void(int)>
+    CancelableCompletionOnceCallback;
+
+}  // namespace net
+
+#endif  // NET_BASE_COMPLETION_ONCE_CALLBACK_H_
diff --git a/net/base/file_stream.cc b/net/base/file_stream.cc
index fe05146..038f60c 100644
--- a/net/base/file_stream.cc
+++ b/net/base/file_stream.cc
@@ -22,20 +22,21 @@
   context_.release()->Orphan();
 }
 
-int FileStream::Open(const base::FilePath& path, int open_flags,
-                     const CompletionCallback& callback) {
+int FileStream::Open(const base::FilePath& path,
+                     int open_flags,
+                     CompletionOnceCallback callback) {
   if (IsOpen()) {
     DLOG(FATAL) << "File is already open!";
     return ERR_UNEXPECTED;
   }
 
   DCHECK(open_flags & base::File::FLAG_ASYNC);
-  context_->Open(path, open_flags, callback);
+  context_->Open(path, open_flags, std::move(callback));
   return ERR_IO_PENDING;
 }
 
-int FileStream::Close(const CompletionCallback& callback) {
-  context_->Close(callback);
+int FileStream::Close(CompletionOnceCallback callback) {
+  context_->Close(std::move(callback));
   return ERR_IO_PENDING;
 }
 
@@ -43,50 +44,50 @@
   return context_->IsOpen();
 }
 
-int FileStream::Seek(int64_t offset, const Int64CompletionCallback& callback) {
+int FileStream::Seek(int64_t offset, Int64CompletionOnceCallback callback) {
   if (!IsOpen())
     return ERR_UNEXPECTED;
 
-  context_->Seek(offset, callback);
+  context_->Seek(offset, std::move(callback));
   return ERR_IO_PENDING;
 }
 
 int FileStream::Read(IOBuffer* buf,
                      int buf_len,
-                     const CompletionCallback& callback) {
+                     CompletionOnceCallback callback) {
   if (!IsOpen())
     return ERR_UNEXPECTED;
 
   // read(..., 0) will return 0, which indicates end-of-file.
   DCHECK_GT(buf_len, 0);
 
-  return context_->Read(buf, buf_len, callback);
+  return context_->Read(buf, buf_len, std::move(callback));
 }
 
 int FileStream::Write(IOBuffer* buf,
                       int buf_len,
-                      const CompletionCallback& callback) {
+                      CompletionOnceCallback callback) {
   if (!IsOpen())
     return ERR_UNEXPECTED;
 
   DCHECK_GE(buf_len, 0);
-  return context_->Write(buf, buf_len, callback);
+  return context_->Write(buf, buf_len, std::move(callback));
 }
 
 int FileStream::GetFileInfo(base::File::Info* file_info,
-                            const CompletionCallback& callback) {
+                            CompletionOnceCallback callback) {
   if (!IsOpen())
     return ERR_UNEXPECTED;
 
-  context_->GetFileInfo(file_info, callback);
+  context_->GetFileInfo(file_info, std::move(callback));
   return ERR_IO_PENDING;
 }
 
-int FileStream::Flush(const CompletionCallback& callback) {
+int FileStream::Flush(CompletionOnceCallback callback) {
   if (!IsOpen())
     return ERR_UNEXPECTED;
 
-  context_->Flush(callback);
+  context_->Flush(std::move(callback));
   return ERR_IO_PENDING;
 }
 
diff --git a/net/base/file_stream.h b/net/base/file_stream.h
index 925f1250..501bc975 100644
--- a/net/base/file_stream.h
+++ b/net/base/file_stream.h
@@ -16,7 +16,7 @@
 
 #include "base/files/file.h"
 #include "base/macros.h"
-#include "net/base/completion_callback.h"
+#include "net/base/completion_once_callback.h"
 #include "net/base/net_export.h"
 
 namespace base {
@@ -56,14 +56,15 @@
   // automatically closed when FileStream is destructed in an asynchronous
   // manner (i.e. the file stream is closed in the background but you don't
   // know when).
-  virtual int Open(const base::FilePath& path, int open_flags,
-                   const CompletionCallback& callback);
+  virtual int Open(const base::FilePath& path,
+                   int open_flags,
+                   CompletionOnceCallback callback);
 
   // Returns ERR_IO_PENDING and closes the file asynchronously, calling
   // |callback| when done.
   // It is invalid to request any asynchronous operations while there is an
   // in-flight asynchronous operation.
-  virtual int Close(const CompletionCallback& callback);
+  virtual int Close(CompletionOnceCallback callback);
 
   // Returns true if Open succeeded and Close has not been called.
   virtual bool IsOpen() const;
@@ -74,7 +75,7 @@
   // position relative to the start of the file.  Otherwise, an error code is
   // returned. It is invalid to request any asynchronous operations while there
   // is an in-flight asynchronous operation.
-  virtual int Seek(int64_t offset, const Int64CompletionCallback& callback);
+  virtual int Seek(int64_t offset, Int64CompletionOnceCallback callback);
 
   // Call this method to read data from the current stream position
   // asynchronously. Up to buf_len bytes will be copied into buf.  (In
@@ -96,8 +97,7 @@
   // in-flight asynchronous operation.
   //
   // This method must not be called if the stream was opened WRITE_ONLY.
-  virtual int Read(IOBuffer* buf, int buf_len,
-                   const CompletionCallback& callback);
+  virtual int Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback);
 
   // Call this method to write data at the current stream position
   // asynchronously.  Up to buf_len bytes will be written from buf. (In
@@ -121,8 +121,9 @@
   // This method must not be called if the stream was opened READ_ONLY.
   //
   // Zero byte writes are not allowed.
-  virtual int Write(IOBuffer* buf, int buf_len,
-                    const CompletionCallback& callback);
+  virtual int Write(IOBuffer* buf,
+                    int buf_len,
+                    CompletionOnceCallback callback);
 
   // Gets status information about File. May fail synchronously, but never
   // succeeds synchronously.
@@ -132,7 +133,7 @@
   //
   // |file_info| must remain valid until |callback| is invoked.
   virtual int GetFileInfo(base::File::Info* file_info,
-                          const CompletionCallback& callback);
+                          CompletionOnceCallback callback);
 
   // Forces out a filesystem sync on this file to make sure that the file was
   // written out to disk and is not currently sitting in the buffer. This does
@@ -153,7 +154,7 @@
   // in-flight asynchronous operation.
   //
   // This method should not be called if the stream was opened READ_ONLY.
-  virtual int Flush(const CompletionCallback& callback);
+  virtual int Flush(CompletionOnceCallback callback);
 
  private:
   class Context;
diff --git a/net/base/file_stream_context.cc b/net/base/file_stream_context.cc
index 9745e291..ecb497b0 100644
--- a/net/base/file_stream_context.cc
+++ b/net/base/file_stream_context.cc
@@ -23,8 +23,8 @@
 
 namespace {
 
-void CallInt64ToInt(const CompletionCallback& callback, int64_t result) {
-  callback.Run(static_cast<int>(result));
+void CallInt64ToInt(CompletionOnceCallback callback, int64_t result) {
+  std::move(callback).Run(static_cast<int>(result));
 }
 
 }  // namespace
@@ -81,30 +81,28 @@
 
 void FileStream::Context::Open(const base::FilePath& path,
                                int open_flags,
-                               const CompletionCallback& callback) {
+                               CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
 
   bool posted = base::PostTaskAndReplyWithResult(
-      task_runner_.get(),
-      FROM_HERE,
-      base::Bind(
-          &Context::OpenFileImpl, base::Unretained(this), path, open_flags),
-      base::Bind(&Context::OnOpenCompleted, base::Unretained(this), callback));
+      task_runner_.get(), FROM_HERE,
+      base::BindOnce(&Context::OpenFileImpl, base::Unretained(this), path,
+                     open_flags),
+      base::BindOnce(&Context::OnOpenCompleted, base::Unretained(this),
+                     std::move(callback)));
   DCHECK(posted);
 
   last_operation_ = OPEN;
   async_in_progress_ = true;
 }
 
-void FileStream::Context::Close(const CompletionCallback& callback) {
+void FileStream::Context::Close(CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
   bool posted = base::PostTaskAndReplyWithResult(
-      task_runner_.get(),
-      FROM_HERE,
-      base::Bind(&Context::CloseFileImpl, base::Unretained(this)),
-      base::Bind(&Context::OnAsyncCompleted,
-                 base::Unretained(this),
-                 IntToInt64(callback)));
+      task_runner_.get(), FROM_HERE,
+      base::BindOnce(&Context::CloseFileImpl, base::Unretained(this)),
+      base::BindOnce(&Context::OnAsyncCompleted, base::Unretained(this),
+                     IntToInt64(std::move(callback))));
   DCHECK(posted);
 
   last_operation_ = CLOSE;
@@ -112,13 +110,14 @@
 }
 
 void FileStream::Context::Seek(int64_t offset,
-                               const Int64CompletionCallback& callback) {
+                               Int64CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
 
   bool posted = base::PostTaskAndReplyWithResult(
       task_runner_.get(), FROM_HERE,
-      base::Bind(&Context::SeekFileImpl, base::Unretained(this), offset),
-      base::Bind(&Context::OnAsyncCompleted, base::Unretained(this), callback));
+      base::BindOnce(&Context::SeekFileImpl, base::Unretained(this), offset),
+      base::BindOnce(&Context::OnAsyncCompleted, base::Unretained(this),
+                     std::move(callback)));
   DCHECK(posted);
 
   last_operation_ = SEEK;
@@ -126,29 +125,27 @@
 }
 
 void FileStream::Context::GetFileInfo(base::File::Info* file_info,
-                                      const CompletionCallback& callback) {
+                                      CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
 
   base::PostTaskAndReplyWithResult(
       task_runner_.get(), FROM_HERE,
-      base::Bind(&Context::GetFileInfoImpl, base::Unretained(this),
-                 base::Unretained(file_info)),
-      base::Bind(&Context::OnAsyncCompleted, base::Unretained(this),
-                 IntToInt64(callback)));
+      base::BindOnce(&Context::GetFileInfoImpl, base::Unretained(this),
+                     base::Unretained(file_info)),
+      base::BindOnce(&Context::OnAsyncCompleted, base::Unretained(this),
+                     IntToInt64(std::move(callback))));
 
   async_in_progress_ = true;
 }
 
-void FileStream::Context::Flush(const CompletionCallback& callback) {
+void FileStream::Context::Flush(CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
 
   bool posted = base::PostTaskAndReplyWithResult(
-      task_runner_.get(),
-      FROM_HERE,
-      base::Bind(&Context::FlushFileImpl, base::Unretained(this)),
-      base::Bind(&Context::OnAsyncCompleted,
-                 base::Unretained(this),
-                 IntToInt64(callback)));
+      task_runner_.get(), FROM_HERE,
+      base::BindOnce(&Context::FlushFileImpl, base::Unretained(this)),
+      base::BindOnce(&Context::OnAsyncCompleted, base::Unretained(this),
+                     IntToInt64(std::move(callback))));
   DCHECK(posted);
 
   last_operation_ = FLUSH;
@@ -223,13 +220,13 @@
   return IOResult::FromOSError(logging::GetLastSystemErrorCode());
 }
 
-void FileStream::Context::OnOpenCompleted(const CompletionCallback& callback,
+void FileStream::Context::OnOpenCompleted(CompletionOnceCallback callback,
                                           OpenResult open_result) {
   file_ = std::move(open_result.file);
   if (file_.IsValid() && !orphaned_)
     OnFileOpened();
 
-  OnAsyncCompleted(IntToInt64(callback), open_result.error_code);
+  OnAsyncCompleted(IntToInt64(std::move(callback)), open_result.error_code);
 }
 
 void FileStream::Context::CloseAndDelete() {
@@ -240,31 +237,31 @@
 
   if (file_.IsValid()) {
     bool posted = task_runner_.get()->PostTask(
-        FROM_HERE, base::Bind(base::IgnoreResult(&Context::CloseFileImpl),
-                              base::Owned(this)));
+        FROM_HERE, base::BindOnce(base::IgnoreResult(&Context::CloseFileImpl),
+                                  base::Owned(this)));
     DCHECK(posted);
   } else {
     delete this;
   }
 }
 
-Int64CompletionCallback FileStream::Context::IntToInt64(
-    const CompletionCallback& callback) {
-  return base::Bind(&CallInt64ToInt, callback);
+Int64CompletionOnceCallback FileStream::Context::IntToInt64(
+    CompletionOnceCallback callback) {
+  return base::BindOnce(&CallInt64ToInt, std::move(callback));
 }
 
-void FileStream::Context::OnAsyncCompleted(
-    const Int64CompletionCallback& callback,
-    const IOResult& result) {
+void FileStream::Context::OnAsyncCompleted(Int64CompletionOnceCallback callback,
+                                           const IOResult& result) {
   // Reset this before Run() as Run() may issue a new async operation. Also it
   // should be reset before Close() because it shouldn't run if any async
   // operation is in progress.
   async_in_progress_ = false;
   last_operation_ = NONE;
-  if (orphaned_)
+  if (orphaned_) {
     CloseAndDelete();
-  else
-    callback.Run(result.result);
+  } else {
+    std::move(callback).Run(result.result);
+  }
 }
 
 }  // namespace net
diff --git a/net/base/file_stream_context.h b/net/base/file_stream_context.h
index 105cbd4..7a34aad 100644
--- a/net/base/file_stream_context.h
+++ b/net/base/file_stream_context.h
@@ -35,7 +35,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/task_runner.h"
-#include "net/base/completion_callback.h"
+#include "net/base/completion_once_callback.h"
 #include "net/base/file_stream.h"
 
 #if defined(OS_POSIX)
@@ -69,13 +69,9 @@
   ~Context();
 #endif
 
-  int Read(IOBuffer* buf,
-           int buf_len,
-           const CompletionCallback& callback);
+  int Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback);
 
-  int Write(IOBuffer* buf,
-            int buf_len,
-            const CompletionCallback& callback);
+  int Write(IOBuffer* buf, int buf_len, CompletionOnceCallback callback);
 
   bool async_in_progress() const { return async_in_progress_; }
 
@@ -90,17 +86,17 @@
 
   void Open(const base::FilePath& path,
             int open_flags,
-            const CompletionCallback& callback);
+            CompletionOnceCallback callback);
 
-  void Close(const CompletionCallback& callback);
+  void Close(CompletionOnceCallback callback);
 
   // Seeks |offset| bytes from the start of the file.
-  void Seek(int64_t offset, const Int64CompletionCallback& callback);
+  void Seek(int64_t offset, Int64CompletionOnceCallback callback);
 
   void GetFileInfo(base::File::Info* file_info,
-                   const CompletionCallback& callback);
+                   CompletionOnceCallback callback);
 
-  void Flush(const CompletionCallback& callback);
+  void Flush(CompletionOnceCallback callback);
 
   bool IsOpen() const;
 
@@ -161,16 +157,15 @@
 
   IOResult FlushFileImpl();
 
-  void OnOpenCompleted(const CompletionCallback& callback,
-                       OpenResult open_result);
+  void OnOpenCompleted(CompletionOnceCallback callback, OpenResult open_result);
 
   void CloseAndDelete();
 
-  Int64CompletionCallback IntToInt64(const CompletionCallback& callback);
+  Int64CompletionOnceCallback IntToInt64(CompletionOnceCallback callback);
 
   // Called when Open() or Seek() completes. |result| contains the result or a
   // network error code.
-  void OnAsyncCompleted(const Int64CompletionCallback& callback,
+  void OnAsyncCompleted(Int64CompletionOnceCallback callback,
                         const IOResult& result);
 
   ////////////////////////////////////////////////////////////////////////////
@@ -184,7 +179,7 @@
   void OnFileOpened();
 
 #if defined(OS_WIN)
-  void IOCompletionIsPending(const CompletionCallback& callback, IOBuffer* buf);
+  void IOCompletionIsPending(CompletionOnceCallback callback, IOBuffer* buf);
 
   // Implementation of MessageLoopForIO::IOHandler.
   void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
@@ -252,7 +247,7 @@
 
 #if defined(OS_WIN)
   base::MessageLoopForIO::IOContext io_context_;
-  CompletionCallback callback_;
+  CompletionOnceCallback callback_;
   scoped_refptr<IOBuffer> in_flight_buf_;
   // This flag is set to true when we receive a Read request which is queued to
   // the thread pool.
diff --git a/net/base/file_stream_context_posix.cc b/net/base/file_stream_context_posix.cc
index 20dc04d..1880b95a 100644
--- a/net/base/file_stream_context_posix.cc
+++ b/net/base/file_stream_context_posix.cc
@@ -39,17 +39,16 @@
 
 int FileStream::Context::Read(IOBuffer* in_buf,
                               int buf_len,
-                              const CompletionCallback& callback) {
+                              CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
 
   scoped_refptr<IOBuffer> buf = in_buf;
   const bool posted = base::PostTaskAndReplyWithResult(
-      task_runner_.get(),
-      FROM_HERE,
-      base::Bind(&Context::ReadFileImpl, base::Unretained(this), buf, buf_len),
-      base::Bind(&Context::OnAsyncCompleted,
-                 base::Unretained(this),
-                 IntToInt64(callback)));
+      task_runner_.get(), FROM_HERE,
+      base::BindOnce(&Context::ReadFileImpl, base::Unretained(this), buf,
+                     buf_len),
+      base::BindOnce(&Context::OnAsyncCompleted, base::Unretained(this),
+                     IntToInt64(std::move(callback))));
   DCHECK(posted);
 
   async_in_progress_ = true;
@@ -59,17 +58,16 @@
 
 int FileStream::Context::Write(IOBuffer* in_buf,
                                int buf_len,
-                               const CompletionCallback& callback) {
+                               CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
 
   scoped_refptr<IOBuffer> buf = in_buf;
   const bool posted = base::PostTaskAndReplyWithResult(
-      task_runner_.get(),
-      FROM_HERE,
-      base::Bind(&Context::WriteFileImpl, base::Unretained(this), buf, buf_len),
-      base::Bind(&Context::OnAsyncCompleted,
-                 base::Unretained(this),
-                 IntToInt64(callback)));
+      task_runner_.get(), FROM_HERE,
+      base::BindOnce(&Context::WriteFileImpl, base::Unretained(this), buf,
+                     buf_len),
+      base::BindOnce(&Context::OnAsyncCompleted, base::Unretained(this),
+                     IntToInt64(std::move(callback))));
   DCHECK(posted);
 
   async_in_progress_ = true;
diff --git a/net/base/file_stream_context_win.cc b/net/base/file_stream_context_win.cc
index 974835a1..cf4947f 100644
--- a/net/base/file_stream_context_win.cc
+++ b/net/base/file_stream_context_win.cc
@@ -68,7 +68,7 @@
 
 int FileStream::Context::Read(IOBuffer* buf,
                               int buf_len,
-                              const CompletionCallback& callback) {
+                              CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
 
   DCHECK(!async_read_initiated_);
@@ -76,7 +76,7 @@
   DCHECK(!io_complete_for_read_received_);
 
   last_operation_ = READ;
-  IOCompletionIsPending(callback, buf);
+  IOCompletionIsPending(std::move(callback), buf);
 
   async_read_initiated_ = true;
   result_ = 0;
@@ -91,7 +91,7 @@
 
 int FileStream::Context::Write(IOBuffer* buf,
                                int buf_len,
-                               const CompletionCallback& callback) {
+                               CompletionOnceCallback callback) {
   CheckNoAsyncInProgress();
 
   last_operation_ = WRITE;
@@ -101,14 +101,15 @@
   if (!WriteFile(file_.GetPlatformFile(), buf->data(), buf_len,
                  &bytes_written, &io_context_.overlapped)) {
     IOResult error = IOResult::FromOSError(GetLastError());
-    if (error.os_error == ERROR_IO_PENDING)
-      IOCompletionIsPending(callback, buf);
-    else
+    if (error.os_error == ERROR_IO_PENDING) {
+      IOCompletionIsPending(std::move(callback), buf);
+    } else {
       LOG(WARNING) << "WriteFile failed: " << error.os_error;
+    }
     return static_cast<int>(error.result);
   }
 
-  IOCompletionIsPending(callback, buf);
+  IOCompletionIsPending(std::move(callback), buf);
   return ERR_IO_PENDING;
 }
 
@@ -125,11 +126,10 @@
                                                        this);
 }
 
-void FileStream::Context::IOCompletionIsPending(
-    const CompletionCallback& callback,
-    IOBuffer* buf) {
+void FileStream::Context::IOCompletionIsPending(CompletionOnceCallback callback,
+                                                IOBuffer* buf) {
   DCHECK(callback_.is_null());
-  callback_ = callback;
+  callback_ = std::move(callback);
   in_flight_buf_ = buf;  // Hold until the async operation ends.
   async_in_progress_ = true;
 }
@@ -188,11 +188,9 @@
     last_operation_ = NONE;
     async_in_progress_ = false;
   }
-  CompletionCallback temp_callback = callback_;
-  callback_.Reset();
   scoped_refptr<IOBuffer> temp_buf = in_flight_buf_;
   in_flight_buf_ = NULL;
-  temp_callback.Run(result_);
+  std::move(callback_).Run(result_);
 }
 
 void FileStream::Context::DeleteOrphanedContext() {
diff --git a/net/base/mock_file_stream.cc b/net/base/mock_file_stream.cc
index 67b8eff..4cff945 100644
--- a/net/base/mock_file_stream.cc
+++ b/net/base/mock_file_stream.cc
@@ -35,45 +35,44 @@
 
 MockFileStream::~MockFileStream() = default;
 
-int MockFileStream::Seek(int64_t offset,
-                         const Int64CompletionCallback& callback) {
-  Int64CompletionCallback wrapped_callback =
-      base::Bind(&MockFileStream::DoCallback64,
-                 weak_factory_.GetWeakPtr(), callback);
+int MockFileStream::Seek(int64_t offset, Int64CompletionOnceCallback callback) {
+  Int64CompletionOnceCallback wrapped_callback =
+      base::BindOnce(&MockFileStream::DoCallback64, weak_factory_.GetWeakPtr(),
+                     std::move(callback));
   if (forced_error_ == OK)
-    return FileStream::Seek(offset, wrapped_callback);
-  return ErrorCallback64(wrapped_callback);
+    return FileStream::Seek(offset, std::move(wrapped_callback));
+  return ErrorCallback64(std::move(wrapped_callback));
 }
 
 int MockFileStream::Read(IOBuffer* buf,
                          int buf_len,
-                         const CompletionCallback& callback) {
-  CompletionCallback wrapped_callback = base::Bind(&MockFileStream::DoCallback,
-                                                   weak_factory_.GetWeakPtr(),
-                                                   callback);
+                         CompletionOnceCallback callback) {
+  CompletionOnceCallback wrapped_callback =
+      base::BindOnce(&MockFileStream::DoCallback, weak_factory_.GetWeakPtr(),
+                     std::move(callback));
   if (forced_error_ == OK)
-    return FileStream::Read(buf, buf_len, wrapped_callback);
-  return ErrorCallback(wrapped_callback);
+    return FileStream::Read(buf, buf_len, std::move(wrapped_callback));
+  return ErrorCallback(std::move(wrapped_callback));
 }
 
 int MockFileStream::Write(IOBuffer* buf,
                           int buf_len,
-                          const CompletionCallback& callback) {
-  CompletionCallback wrapped_callback = base::Bind(&MockFileStream::DoCallback,
-                                                   weak_factory_.GetWeakPtr(),
-                                                   callback);
+                          CompletionOnceCallback callback) {
+  CompletionOnceCallback wrapped_callback =
+      base::BindOnce(&MockFileStream::DoCallback, weak_factory_.GetWeakPtr(),
+                     std::move(callback));
   if (forced_error_ == OK)
-    return FileStream::Write(buf, buf_len, wrapped_callback);
-  return ErrorCallback(wrapped_callback);
+    return FileStream::Write(buf, buf_len, std::move(wrapped_callback));
+  return ErrorCallback(std::move(wrapped_callback));
 }
 
-int MockFileStream::Flush(const CompletionCallback& callback) {
-  CompletionCallback wrapped_callback = base::Bind(&MockFileStream::DoCallback,
-                                                   weak_factory_.GetWeakPtr(),
-                                                   callback);
+int MockFileStream::Flush(CompletionOnceCallback callback) {
+  CompletionOnceCallback wrapped_callback =
+      base::BindOnce(&MockFileStream::DoCallback, weak_factory_.GetWeakPtr(),
+                     std::move(callback));
   if (forced_error_ == OK)
-    return FileStream::Flush(wrapped_callback);
-  return ErrorCallback(wrapped_callback);
+    return FileStream::Flush(std::move(wrapped_callback));
+  return ErrorCallback(std::move(wrapped_callback));
 }
 
 void MockFileStream::ThrottleCallbacks() {
@@ -86,37 +85,35 @@
   throttled_ = false;
 
   if (!throttled_task_.is_null()) {
-    base::Closure throttled_task = throttled_task_;
-    throttled_task_.Reset();
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, throttled_task);
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  std::move(throttled_task_));
   }
 }
 
-void MockFileStream::DoCallback(const CompletionCallback& callback,
-                                int result) {
+void MockFileStream::DoCallback(CompletionOnceCallback callback, int result) {
   if (!throttled_) {
-    callback.Run(result);
+    std::move(callback).Run(result);
     return;
   }
   CHECK(throttled_task_.is_null());
-  throttled_task_ = base::Bind(callback, result);
+  throttled_task_ = base::BindOnce(std::move(callback), result);
 }
 
-void MockFileStream::DoCallback64(const Int64CompletionCallback& callback,
+void MockFileStream::DoCallback64(Int64CompletionOnceCallback callback,
                                   int64_t result) {
   if (!throttled_) {
-    callback.Run(result);
+    std::move(callback).Run(result);
     return;
   }
   CHECK(throttled_task_.is_null());
-  throttled_task_ = base::Bind(callback, result);
+  throttled_task_ = base::BindOnce(std::move(callback), result);
 }
 
-int MockFileStream::ErrorCallback(const CompletionCallback& callback) {
+int MockFileStream::ErrorCallback(CompletionOnceCallback callback) {
   CHECK_NE(OK, forced_error_);
   if (async_error_) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(callback, forced_error_));
+        FROM_HERE, base::BindOnce(std::move(callback), forced_error_));
     clear_forced_error();
     return ERR_IO_PENDING;
   }
@@ -125,12 +122,11 @@
   return ret;
 }
 
-int64_t MockFileStream::ErrorCallback64(
-    const Int64CompletionCallback& callback) {
+int64_t MockFileStream::ErrorCallback64(Int64CompletionOnceCallback callback) {
   CHECK_NE(OK, forced_error_);
   if (async_error_) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(callback, forced_error_));
+        FROM_HERE, base::BindOnce(std::move(callback), forced_error_));
     clear_forced_error();
     return ERR_IO_PENDING;
   }
diff --git a/net/base/mock_file_stream.h b/net/base/mock_file_stream.h
index ca5e030..9f1eb98 100644
--- a/net/base/mock_file_stream.h
+++ b/net/base/mock_file_stream.h
@@ -12,6 +12,7 @@
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
+#include "net/base/completion_once_callback.h"
 #include "net/base/file_stream.h"
 #include "net/base/net_errors.h"
 
@@ -29,14 +30,14 @@
   ~MockFileStream() override;
 
   // FileStream methods.
-  int Seek(int64_t offset, const Int64CompletionCallback& callback) override;
+  int Seek(int64_t offset, Int64CompletionOnceCallback callback) override;
   int Read(IOBuffer* buf,
            int buf_len,
-           const CompletionCallback& callback) override;
+           CompletionOnceCallback callback) override;
   int Write(IOBuffer* buf,
             int buf_len,
-            const CompletionCallback& callback) override;
-  int Flush(const CompletionCallback& callback) override;
+            CompletionOnceCallback callback) override;
+  int Flush(CompletionOnceCallback callback) override;
 
   void set_forced_error_async(int error) {
     forced_error_ = error;
@@ -83,18 +84,18 @@
 
   // Wrappers for callbacks to make them honor ThrottleCallbacks and
   // ReleaseCallbacks.
-  void DoCallback(const CompletionCallback& callback, int result);
-  void DoCallback64(const Int64CompletionCallback& callback, int64_t result);
+  void DoCallback(CompletionOnceCallback callback, int result);
+  void DoCallback64(Int64CompletionOnceCallback callback, int64_t result);
 
   // Depending on |async_error_|, either synchronously returns |forced_error_|
   // asynchronously calls |callback| with |async_error_|.
-  int ErrorCallback(const CompletionCallback& callback);
-  int64_t ErrorCallback64(const Int64CompletionCallback& callback);
+  int ErrorCallback(CompletionOnceCallback callback);
+  int64_t ErrorCallback64(Int64CompletionOnceCallback callback);
 
   int forced_error_;
   bool async_error_;
   bool throttled_;
-  base::Closure throttled_task_;
+  base::OnceClosure throttled_task_;
   base::FilePath path_;
 
   base::WeakPtrFactory<MockFileStream> weak_factory_;