diff --git a/media/cdm/cdm_adapter_unittest.cc b/media/cdm/cdm_adapter_unittest.cc
index 280b37bdd1a98..0426ea655d281 100644
--- a/media/cdm/cdm_adapter_unittest.cc
+++ b/media/cdm/cdm_adapter_unittest.cc
@@ -143,7 +143,8 @@ class MockFileIOClient : public cdm::FileIOClient {
   ~MockFileIOClient() override = default;
 
   MOCK_METHOD1(OnOpenComplete, void(Status));
-  MOCK_METHOD3(OnReadComplete, void(Status, const uint8_t*, uint32_t));
+  MOCK_METHOD2(OnReadComplete,
+               void(Status, base::span<const uint8_t>));
   MOCK_METHOD1(OnWriteComplete, void(Status));
 };
 
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.cc b/media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.cc
index f20350bd80f36..33b369244a00d 100644
--- a/media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.cc
+++ b/media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "base/containers/span.h"
 #include "base/compiler_specific.h"
 #include "base/functional/bind.h"
 #include "base/logging.h"
@@ -56,7 +57,7 @@ void CdmFileAdapter::Read(ReadCB read_cb) {
 void CdmFileAdapter::Write(const std::vector<uint8_t>& data, WriteCB write_cb) {
   DVLOG(2) << __func__;
   write_cb_ = std::move(write_cb);
-  file_io_->Write(data.data(), data.size());
+  file_io_->Write(data);
 }
 
 void CdmFileAdapter::OnOpenComplete(cdm::FileIOClient::Status status) {
@@ -64,11 +65,9 @@ void CdmFileAdapter::OnOpenComplete(cdm::FileIOClient::Status status) {
 }
 
 void CdmFileAdapter::OnReadComplete(cdm::FileIOClient::Status status,
-                                    const uint8_t* data,
-                                    uint32_t data_size) {
-  std::move(read_cb_).Run(
-      status == FileIOClient::Status::kSuccess && data_size > 0,
-      std::vector<uint8_t>(data, UNSAFE_TODO(data + data_size)));
+                                    base::span<const uint8_t> data) {
+  std::move(read_cb_).Run(status == FileIOClient::Status::kSuccess && !data.empty(),
+                           std::vector<uint8_t>(data.begin(), data.end()));
 }
 
 void CdmFileAdapter::OnWriteComplete(cdm::FileIOClient::Status status) {
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.h b/media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.h
index 48889182ff02d..6ed51d91f2ff1 100644
--- a/media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.h
+++ b/media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.h
@@ -10,6 +10,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/span.h"
 #include "base/compiler_specific.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
@@ -55,8 +56,7 @@ class CdmFileAdapter : public cdm::FileIOClient {
   // implementation only.
   void OnOpenComplete(cdm::FileIOClient::Status status) override;
   void OnReadComplete(cdm::FileIOClient::Status status,
-                      const uint8_t* data,
-                      uint32_t data_size) override;
+                      base::span<const uint8_t> data) override;
   void OnWriteComplete(cdm::FileIOClient::Status status) override;
 
   FileOpenedCB open_cb_;
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.cc b/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.cc
index 31b01eb20c7cb..e965cc0e5ff6e 100644
--- a/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.cc
+++ b/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <limits>
 
+#include "base/containers/span.h"
 #include "base/compiler_specific.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -19,13 +20,13 @@ namespace media {
 
 const uint8_t kData[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
-const uint32_t kDataSize = std::size(kData);
+
 
 const uint8_t kBigData[] = {
     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
     0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
     0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00};
-const uint32_t kBigDataSize = std::size(kBigData);
+
 
 // Must be > kReadSize in cdm_file_io_impl.cc.
 const uint32_t kLargeDataSize = 20 * 1024 + 7;
@@ -40,41 +41,41 @@ const uint32_t kLargeDataSize = 20 * 1024 + 7;
         std::make_unique<FileIOTest>(create_file_io_cb_, test_name); \
   CREATE_FILE_IO  // Create FileIO for each test case.
 
-#define ADD_TEST_STEP(type, status, data, data_size)                          \
+#define ADD_TEST_STEP(type, status, data)                                      \
   test_case->AddTestStep(FileIOTest::type, cdm::FileIOClient::Status::status, \
-                         (data), (data_size));
+                         (data));
 
 #define END_TEST_CASE                                 \
-    remaining_tests_.push_back(std::move(test_case)); \
-  } while(0);
+  remaining_tests_.push_back(std::move(test_case)); \
+  }                                                                           \
+  while (0)                                                                   \
+    ;
 
 #define CREATE_FILE_IO \
-  ADD_TEST_STEP(ACTION_CREATE, kSuccess, nullptr, 0)
+  ADD_TEST_STEP(ACTION_CREATE, kSuccess, base::span<const uint8_t>())
 
 #define OPEN_FILE \
-  ADD_TEST_STEP(ACTION_OPEN, kSuccess, nullptr, 0)
+  ADD_TEST_STEP(ACTION_OPEN, kSuccess, base::span<const uint8_t>())
 
 #define EXPECT_FILE_OPENED(status) \
-  ADD_TEST_STEP(RESULT_OPEN, status, nullptr, 0)
+  ADD_TEST_STEP(RESULT_OPEN, status, base::span<const uint8_t>())
 
 #define READ_FILE \
-  ADD_TEST_STEP(ACTION_READ, kSuccess, nullptr, 0)
+  ADD_TEST_STEP(ACTION_READ, kSuccess, base::span<const uint8_t>())
 
-#define EXPECT_FILE_READ(status, data, data_size) \
-  ADD_TEST_STEP(RESULT_READ, status, data, data_size)
+#define EXPECT_FILE_READ(status, data) ADD_TEST_STEP(RESULT_READ, status, data)
 
-#define EXPECT_FILE_READ_EITHER(status, data, data_size, data2, data2_size) \
+#define EXPECT_FILE_READ_EITHER(status, data, data2) \
   test_case->AddResultReadEither(cdm::FileIOClient::Status::status, (data), \
-                                 (data_size), (data2), (data2_size));
+                                 (data2));
 
-#define WRITE_FILE(data, data_size) \
-  ADD_TEST_STEP(ACTION_WRITE, kSuccess, data, data_size)
+#define WRITE_FILE(data) ADD_TEST_STEP(ACTION_WRITE, kSuccess, data)
 
 #define EXPECT_FILE_WRITTEN(status) \
-  ADD_TEST_STEP(RESULT_WRITE, status, nullptr, 0)
+  ADD_TEST_STEP(RESULT_WRITE, status, base::span<const uint8_t>())
 
 #define CLOSE_FILE \
-  ADD_TEST_STEP(ACTION_CLOSE, kSuccess, nullptr, 0)
+  ADD_TEST_STEP(ACTION_CLOSE, kSuccess, base::span<const uint8_t>())
 
 // FileIOTestRunner implementation.
 
@@ -156,11 +157,11 @@ void FileIOTestRunner::AddTests() {
 
   START_TEST_CASE("ReadBeforeOpeningFile")
     READ_FILE
-    EXPECT_FILE_READ(kError, nullptr, 0)
+    EXPECT_FILE_READ(kError, base::span<const uint8_t>())
   END_TEST_CASE
 
   START_TEST_CASE("WriteBeforeOpeningFile")
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kError)
   END_TEST_CASE
 
@@ -168,190 +169,190 @@ void FileIOTestRunner::AddTests() {
     OPEN_FILE
     READ_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    EXPECT_FILE_READ(kError, nullptr, 0)
+    EXPECT_FILE_READ(kError, base::span<const uint8_t>())
     // After file opened, we can still do normal operations.
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("WriteBeforeFileOpened")
     OPEN_FILE
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kError)
     EXPECT_FILE_OPENED(kSuccess)
     // After file opened, we can still do normal operations.
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("ReadDuringPendingRead")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
     READ_FILE
-    EXPECT_FILE_READ(kInUse, nullptr, 0)
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kInUse, base::span<const uint8_t>())
+    EXPECT_FILE_READ(kSuccess, kData)
     // Read again.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("ReadDuringPendingWrite")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     READ_FILE
-    EXPECT_FILE_READ(kInUse, nullptr, 0)
+    EXPECT_FILE_READ(kInUse, base::span<const uint8_t>())
     EXPECT_FILE_WRITTEN(kSuccess)
     // Read again.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("WriteDuringPendingRead")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
     READ_FILE
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kInUse)
-    EXPECT_FILE_READ(kSuccess, nullptr, 0)
+    EXPECT_FILE_READ(kSuccess, base::span<const uint8_t>())
     // We can still do normal operations.
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("WriteDuringPendingWrite")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
-    WRITE_FILE(kBigData, kBigDataSize)
+    WRITE_FILE(kData)
+    WRITE_FILE(kBigData)
     EXPECT_FILE_WRITTEN(kInUse)
     EXPECT_FILE_WRITTEN(kSuccess)
     // Read to make sure original data (kData) is written.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("ReadFileThatDoesNotExist")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, nullptr, 0)
+    EXPECT_FILE_READ(kSuccess, base::span<const uint8_t>())
   END_TEST_CASE
 
   START_TEST_CASE("WriteAndRead")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("WriteAndReadEmptyFile")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(nullptr, 0)
+    WRITE_FILE(base::span<const uint8_t>())
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, nullptr, 0)
+    EXPECT_FILE_READ(kSuccess, base::span<const uint8_t>())
   END_TEST_CASE
 
   START_TEST_CASE("WriteAndReadLargeData")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(&large_data_[0], kLargeDataSize)
+    WRITE_FILE(large_data_)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, &large_data_[0], kLargeDataSize)
+    EXPECT_FILE_READ(kSuccess, large_data_)
   END_TEST_CASE
 
   START_TEST_CASE("OverwriteZeroBytes")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
-    WRITE_FILE(nullptr, 0)
+    EXPECT_FILE_READ(kSuccess, kData)
+    WRITE_FILE(base::span<const uint8_t>())
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, nullptr, 0)
+    EXPECT_FILE_READ(kSuccess, base::span<const uint8_t>())
   END_TEST_CASE
 
   START_TEST_CASE("OverwriteWithSmallerData")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kBigData, kBigDataSize)
+    WRITE_FILE(kBigData)
     EXPECT_FILE_WRITTEN(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("OverwriteWithLargerData")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
-    WRITE_FILE(kBigData, kBigDataSize)
+    WRITE_FILE(kBigData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kBigData, kBigDataSize)
+    EXPECT_FILE_READ(kSuccess, kBigData)
   END_TEST_CASE
 
   START_TEST_CASE("ReadExistingFile")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     CLOSE_FILE
     CREATE_FILE_IO
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("WriteExistingFile")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
     // Write big data first
-    WRITE_FILE(kBigData, kBigDataSize)
+    WRITE_FILE(kBigData)
     EXPECT_FILE_WRITTEN(kSuccess)
     CLOSE_FILE
     CREATE_FILE_IO
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kBigData, kBigDataSize)
+    EXPECT_FILE_READ(kSuccess, kBigData)
     // Now overwrite the file with normal data
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     CLOSE_FILE
     CREATE_FILE_IO
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
     // Now overwrite the file with big data again
-    WRITE_FILE(kBigData, kBigDataSize)
+    WRITE_FILE(kBigData)
     EXPECT_FILE_WRITTEN(kSuccess)
     CLOSE_FILE
     CREATE_FILE_IO
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kBigData, kBigDataSize)
+    EXPECT_FILE_READ(kSuccess, kBigData)
   END_TEST_CASE
 
   START_TEST_CASE("MultipleReadsAndWrites")
@@ -359,34 +360,34 @@ void FileIOTestRunner::AddTests() {
     EXPECT_FILE_OPENED(kSuccess)
     // Read file which doesn't exist.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, nullptr, 0)
+    EXPECT_FILE_READ(kSuccess, base::span<const uint8_t>())
     // Write kData to file.
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     // Read file.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
     // Read file again.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
     // Overwrite file with large data.
-    WRITE_FILE(&large_data_[0], kLargeDataSize)
+    WRITE_FILE(large_data_)
     EXPECT_FILE_WRITTEN(kSuccess)
     // Read file.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, &large_data_[0], kLargeDataSize)
+    EXPECT_FILE_READ(kSuccess, large_data_)
     // Overwrite file with kData.
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     // Read file.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
     // Overwrite file with zero bytes.
-    WRITE_FILE(nullptr, 0)
+    WRITE_FILE(base::span<const uint8_t>())
     EXPECT_FILE_WRITTEN(kSuccess)
     // Read file.
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, nullptr, 0)
+    EXPECT_FILE_READ(kSuccess, base::span<const uint8_t>())
   END_TEST_CASE
 
   START_TEST_CASE("OpenAfterOpen")
@@ -406,7 +407,7 @@ void FileIOTestRunner::AddTests() {
   START_TEST_CASE("ReopenFileInSeparateFileIO")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     CREATE_FILE_IO  // Create a second FileIO without closing the first one.
     OPEN_FILE
@@ -425,16 +426,16 @@ void FileIOTestRunner::AddTests() {
   START_TEST_CASE("CloseDuringPendingWrite")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     CLOSE_FILE
   END_TEST_CASE
 
   START_TEST_CASE("CloseDuringPendingOverwriteWithLargerData")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
-    WRITE_FILE(kBigData, kBigDataSize)
+    WRITE_FILE(kBigData)
     CLOSE_FILE
     // Write() is async, so it may or may not modify the content of the file.
     CREATE_FILE_IO
@@ -444,17 +445,15 @@ void FileIOTestRunner::AddTests() {
     // As Write() is async, it is possible that the second write above
     // succeeds before the file is closed. So check that the contents
     // is either data set.
-    EXPECT_FILE_READ_EITHER(kSuccess,
-                            kData, kDataSize,
-                            kBigData, kBigDataSize)
+    EXPECT_FILE_READ_EITHER(kSuccess, kData, kBigData)
   END_TEST_CASE
 
   START_TEST_CASE("CloseDuringPendingOverwriteWithSmallerData")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kBigData, kBigDataSize)
+    WRITE_FILE(kBigData)
     EXPECT_FILE_WRITTEN(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     CLOSE_FILE
     // Write() is async, so it may or may not modify the content of the file.
     CREATE_FILE_IO
@@ -464,15 +463,13 @@ void FileIOTestRunner::AddTests() {
     // As Write() is async, it is possible that the second write above
     // succeeds before the file is closed. So check that the contents
     // is either data set.
-    EXPECT_FILE_READ_EITHER(kSuccess,
-                            kBigData, kBigDataSize,
-                            kData, kDataSize)
+    EXPECT_FILE_READ_EITHER(kSuccess, kBigData, kData)
   END_TEST_CASE
 
   START_TEST_CASE("CloseDuringPendingRead")
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
-    WRITE_FILE(kData, kDataSize)
+    WRITE_FILE(kData)
     EXPECT_FILE_WRITTEN(kSuccess)
     READ_FILE
     CLOSE_FILE
@@ -481,7 +478,7 @@ void FileIOTestRunner::AddTests() {
     OPEN_FILE
     EXPECT_FILE_OPENED(kSuccess)
     READ_FILE
-    EXPECT_FILE_READ(kSuccess, kData, kDataSize)
+    EXPECT_FILE_READ(kSuccess, kData)
   END_TEST_CASE
 
   START_TEST_CASE("StressTest")
@@ -489,9 +486,9 @@ void FileIOTestRunner::AddTests() {
       CREATE_FILE_IO
       OPEN_FILE
       EXPECT_FILE_OPENED(kSuccess)
-      WRITE_FILE(kData, kDataSize)
+      WRITE_FILE(kData)
       EXPECT_FILE_WRITTEN(kSuccess)
-      WRITE_FILE(kBigData, kBigDataSize)
+      WRITE_FILE(kBigData)
       CLOSE_FILE
       // Make sure the file is not modified.
       CREATE_FILE_IO
@@ -501,9 +498,7 @@ void FileIOTestRunner::AddTests() {
       // As Write() is async, it is possible that the second write above
       // succeeds before the file is closed. So check that the contents
       // is either data set.
-      EXPECT_FILE_READ_EITHER(kSuccess,
-                              kData, kDataSize,
-                              kBigData, kBigDataSize)
+      EXPECT_FILE_READ_EITHER(kSuccess, kData, kBigData)
       CLOSE_FILE
     }
   END_TEST_CASE
@@ -546,19 +541,16 @@ FileIOTest::~FileIOTest() = default;
 
 void FileIOTest::AddTestStep(StepType type,
                              Status status,
-                             const uint8_t* data,
-                             uint32_t data_size) {
-  test_steps_.push_back(TestStep(type, status, data, data_size));
+                             base::span<const uint8_t> data) {
+  test_steps_.push_back(TestStep(type, status, data));
 }
 
 void FileIOTest::AddResultReadEither(Status status,
-                                     const uint8_t* data,
-                                     uint32_t data_size,
-                                     const uint8_t* data2,
-                                     uint32_t data2_size) {
-  DCHECK_NE(data_size, data2_size);
-  test_steps_.push_back(TestStep(FileIOTest::RESULT_READ, status, data,
-                                 data_size, data2, data2_size));
+                                     base::span<const uint8_t> data,
+                                     base::span<const uint8_t> data2) {
+  DCHECK_NE(data.size(), data2.size());
+  test_steps_.push_back(
+      TestStep(FileIOTest::RESULT_READ, status, data, data2));
 }
 
 void FileIOTest::Run(CompletionCB completion_cb) {
@@ -572,10 +564,8 @@ void FileIOTest::OnOpenComplete(Status status) {
   OnResult(TestStep(RESULT_OPEN, status));
 }
 
-void FileIOTest::OnReadComplete(Status status,
-                                const uint8_t* data,
-                                uint32_t data_size) {
-  OnResult(TestStep(RESULT_READ, status, data, data_size));
+void FileIOTest::OnReadComplete(Status status, base::span<const uint8_t> data) {
+  OnResult(TestStep(RESULT_READ, status, data));
 }
 
 void FileIOTest::OnWriteComplete(Status status) {
@@ -600,7 +590,7 @@ bool FileIOTest::IsResult(const TestStep& test_step) {
 
 bool FileIOTest::MatchesResult(const TestStep& a, const TestStep& b) {
   DCHECK(IsResult(a) && IsResult(b));
-  DCHECK(!b.data2);
+  DCHECK(b.data2.empty());
 
   if (a.type != b.type || a.status != b.status)
     return false;
@@ -608,13 +598,11 @@ bool FileIOTest::MatchesResult(const TestStep& a, const TestStep& b) {
   if (a.type != RESULT_READ || a.status != cdm::FileIOClient::Status::kSuccess)
     return true;
 
-  // If |a| specifies a data2, compare it first. If the size matches, compare
-  // the contents.
-  if (a.data2 && b.data_size == a.data2_size)
-    return std::equal(a.data2, UNSAFE_TODO(a.data2 + a.data2_size), b.data);
+  // If |a| specifies a data2, compare it first.
+  if (!a.data2.empty() && b.data.size() == a.data2.size())
+    return std::equal(a.data2.begin(), a.data2.end(), b.data.begin());
 
-  return (a.data_size == b.data_size &&
-          std::equal(a.data, UNSAFE_TODO(a.data + a.data_size), b.data));
+  return std::equal(a.data.begin(), a.data.end(), b.data.begin());
 }
 
 void FileIOTest::RunNextStep() {
@@ -627,7 +615,7 @@ void FileIOTest::RunNextStep() {
     TestStep test_step = test_steps_.front();
     test_steps_.pop_front();
 
-    cdm::FileIO* file_io =
+    cdm::FileIO* file_io = 
         file_io_stack_.empty() ? nullptr : file_io_stack_.top();
 
     switch (test_step.type) {
@@ -648,7 +636,7 @@ void FileIOTest::RunNextStep() {
         file_io->Read();
         break;
       case ACTION_WRITE:
-        file_io->Write(test_step.data, test_step.data_size);
+        file_io->Write(test_step.data);
         break;
       case ACTION_CLOSE:
         file_io->Close();
@@ -667,15 +655,15 @@ void FileIOTest::OnResult(const TestStep& result) {
   if (!CheckResult(result)) {
     LOG(WARNING) << test_name_ << " got unexpected result. type=" << result.type
                  << ", status=" << (uint32_t)result.status
-                 << ", data_size=" << result.data_size << ", received data="
-                 << (result.data
-                         ? base::HexEncode(result.data, result.data_size)
+                 << ", data_size=" << result.data.size() << ", received data="
+                 << (!result.data.empty()
+                         ? base::HexEncode(result.data)
                          : "<null>");
     for (const auto& step : test_steps_) {
       if (IsResult(step)) {
         LOG(WARNING) << test_name_ << " expected type=" << step.type
                      << ", status=" << (uint32_t)step.status
-                     << ", data_size=" << step.data_size;
+                     << ", data_size=" << step.data.size();
       }
     }
     OnTestComplete(false);
@@ -715,4 +703,4 @@ void FileIOTest::OnTestComplete(bool success) {
   std::move(completion_cb_).Run(success);
 }
 
-}  // namespace media
+}  // namespace media
\ No newline at end of file
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.h b/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.h
index 455dd875b23c7..a27c3ffbf7532 100644
--- a/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.h
+++ b/media/cdm/library_cdm/clear_key_cdm/cdm_file_io_test.h
@@ -13,10 +13,12 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/span.h"
 #include "base/compiler_specific.h"
 #include "base/containers/stack.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "media/cdm/api/content_decryption_module.h"
 
 namespace media {
@@ -78,16 +80,13 @@ class FileIOTest : public cdm::FileIOClient {
   // |data|, which should be valid throughout the lifetime of |this| object.
   void AddTestStep(StepType type,
                    Status status,
-                   const uint8_t* data,
-                   uint32_t data_size);
+                   base::span<const uint8_t> data);
   // Adds a test step in this test that expects a successful read of either
   // |data| or |data2|. |this| object doesn't take the ownership of |data| or
   // |data2|, which should be valid throughout the lifetime of |this| object.
   void AddResultReadEither(Status status,
-                           const uint8_t* data,
-                           uint32_t data_size,
-                           const uint8_t* data2,
-                           uint32_t data2_size);
+                           base::span<const uint8_t> data,
+                           base::span<const uint8_t> data2);
 
   // Runs this test case and returns the test result through |completion_cb|.
   void Run(CompletionCB completion_cb);
@@ -98,16 +97,12 @@ class FileIOTest : public cdm::FileIOClient {
     // should be valid throughout the lifetime of |this| object.
     TestStep(StepType type,
              Status status,
-             const uint8_t* data = nullptr,
-             uint32_t data_size = 0,
-             const uint8_t* data2 = nullptr,
-             uint32_t data2_size = 0)
+             base::span<const uint8_t> data = {},
+             base::span<const uint8_t> data2 = {})
         : type(type),
           status(status),
           data(data),
-          data_size(data_size),
-          data2(data2),
-          data2_size(data2_size) {}
+          data2(data2) {}
 
     StepType type;
 
@@ -115,12 +110,10 @@ class FileIOTest : public cdm::FileIOClient {
     Status status;
 
     // Data to write in ACTION_WRITE, or read data in RESULT_READ.
-    const uint8_t* data;
-    uint32_t data_size;
+    base::raw_span<const uint8_t> data;
 
-    // Alternate read data in RESULT_READ, if |data2| != nullptr.
-    const uint8_t* data2;
-    uint32_t data2_size;
+    // Alternate read data in RESULT_READ, if |data2| is not empty.
+    base::raw_span<const uint8_t> data2;
   };
 
   // Returns whether |test_step| is a RESULT_* step.
@@ -131,9 +124,7 @@ class FileIOTest : public cdm::FileIOClient {
 
   // cdm::FileIOClient implementation.
   void OnOpenComplete(Status status) override;
-  void OnReadComplete(Status status,
-                      const uint8_t* data,
-                      uint32_t data_size) override;
+  void OnReadComplete(Status status, base::span<const uint8_t> data) override;
   void OnWriteComplete(Status status) override;
 
   // Runs the next step in this test case.
diff --git a/media/mojo/services/mojo_cdm_file_io.cc b/media/mojo/services/mojo_cdm_file_io.cc
index 409d1db374334..4425b38279c2b 100644
--- a/media/mojo/services/mojo_cdm_file_io.cc
+++ b/media/mojo/services/mojo_cdm_file_io.cc
@@ -181,11 +181,11 @@ void MojoCdmFileIO::OnFileRead(FileStatus status,
 
   state_ = State::kOpened;
   TRACE_EVENT0("media", "FileIOClient::OnReadComplete");
-  client_->OnReadComplete(ClientStatus::kSuccess, data.data(), data.size());
+  client_->OnReadComplete(ClientStatus::kSuccess, data);
 }
 
-void MojoCdmFileIO::Write(const uint8_t* data, uint32_t data_size) {
-  DVLOG(3) << __func__ << " file: " << file_name_ << ", bytes: " << data_size;
+void MojoCdmFileIO::Write(base::span<const uint8_t> data) {
+  DVLOG(3) << __func__ << " file: " << file_name_ << ", bytes: " << data.size();
 
   // If another operation is in progress, fail.
   if (state_ == State::kReading || state_ == State::kWriting) {
@@ -200,19 +200,19 @@ void MojoCdmFileIO::Write(const uint8_t* data, uint32_t data_size) {
   }
 
   // Files are limited in size, so fail if file too big.
-  if (data_size > kMaxFileSizeBytes) {
+  if (data.size() > kMaxFileSizeBytes) {
     DLOG(WARNING) << __func__
-                  << " Too much data to write. #bytes = " << data_size;
+                  << " Too much data to write. #bytes = " << data.size();
     OnError(ErrorType::kWriteError);
     return;
   }
 
   UMA_HISTOGRAM_CUSTOM_COUNTS("Media.EME.CdmFileIO.WriteFile.DataSizeKB",
-                              data_size / 1024, kSizeKBMin, kMaxFileSizeKB,
+                              data.size() / 1024, kSizeKBMin, kMaxFileSizeKB,
                               kSizeKBBuckets);
 
   TRACE_EVENT_ASYNC_BEGIN2("media", "MojoCdmFileIO::Write", this, "file_name",
-                           file_name_, "bytes_to_write", data_size);
+                           file_name_, "bytes_to_write", data.size());
 
   state_ = State::kWriting;
 
@@ -223,7 +223,7 @@ void MojoCdmFileIO::Write(const uint8_t* data, uint32_t data_size) {
   auto callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
       base::BindOnce(&MojoCdmFileIO::OnFileWritten, weak_factory_.GetWeakPtr()),
       FileStatus::kFailure);
-  cdm_file_->Write(std::vector<uint8_t>(data, UNSAFE_TODO(data + data_size)),
+  cdm_file_->Write(std::vector<uint8_t>(data.begin(), data.end()),
                    std::move(callback));
 }
 
@@ -273,10 +273,10 @@ void MojoCdmFileIO::NotifyClientOfError(ErrorType error) {
       client_->OnOpenComplete(ClientStatus::kInUse);
       break;
     case ErrorType::kReadError:
-      client_->OnReadComplete(ClientStatus::kError, nullptr, 0);
+      client_->OnReadComplete(ClientStatus::kError, {});
       break;
     case ErrorType::kReadInUse:
-      client_->OnReadComplete(ClientStatus::kInUse, nullptr, 0);
+      client_->OnReadComplete(ClientStatus::kInUse, {});
       break;
     case ErrorType::kWriteError:
       client_->OnWriteComplete(ClientStatus::kError);
diff --git a/media/mojo/services/mojo_cdm_file_io.h b/media/mojo/services/mojo_cdm_file_io.h
index f6b7c519e3b62..0b2dd5ee8c67b 100644
--- a/media/mojo/services/mojo_cdm_file_io.h
+++ b/media/mojo/services/mojo_cdm_file_io.h
@@ -10,6 +10,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/span.h"
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -48,7 +49,7 @@ class MEDIA_MOJO_EXPORT MojoCdmFileIO : public cdm::FileIO {
   // cdm::FileIO implementation.
   void Open(const char* file_name, uint32_t file_name_size) final;
   void Read() final;
-  void Write(const uint8_t* data, uint32_t data_size) final;
+  void Write(base::span<const uint8_t> data) final;
   void Close() final;
 
  private:
diff --git a/media/mojo/services/mojo_cdm_file_io_unittest.cc b/media/mojo/services/mojo_cdm_file_io_unittest.cc
index 660caf07bcdfb..ea315be2fa8ff 100644
--- a/media/mojo/services/mojo_cdm_file_io_unittest.cc
+++ b/media/mojo/services/mojo_cdm_file_io_unittest.cc
@@ -29,7 +29,8 @@ class MockFileIOClient : public cdm::FileIOClient {
   ~MockFileIOClient() override = default;
 
   MOCK_METHOD1(OnOpenComplete, void(Status));
-  MOCK_METHOD3(OnReadComplete, void(Status, const uint8_t*, uint32_t));
+  MOCK_METHOD2(OnReadComplete,
+               void(Status, base::span<const uint8_t>));
   MOCK_METHOD1(OnWriteComplete, void(Status));
 };
 
@@ -159,14 +160,14 @@ TEST_F(MojoCdmFileIOTest, Read) {
       .WillOnce([](mojom::CdmFile::ReadCallback callback) {
         std::move(callback).Run(mojom::CdmFile::Status::kSuccess, {1, 2, 3});
       });
-  EXPECT_CALL(*client_.get(), OnReadComplete(Status::kSuccess, _, 3));
+  EXPECT_CALL(*client_.get(), OnReadComplete(Status::kSuccess, _));
   file_io_->Read();
   base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(MojoCdmFileIOTest, ReadBeforeOpen) {
   // File not open, so reading should fail.
-  EXPECT_CALL(*client_.get(), OnReadComplete(Status::kError, _, _));
+  EXPECT_CALL(*client_.get(), OnReadComplete(Status::kError, _));
   file_io_->Read();
   base::RunLoop().RunUntilIdle();
 }
@@ -181,8 +182,8 @@ TEST_F(MojoCdmFileIOTest, TwoReads) {
       .WillOnce([](mojom::CdmFile::ReadCallback callback) {
         std::move(callback).Run(mojom::CdmFile::Status::kSuccess, {1, 2, 3, 4});
       });
-  EXPECT_CALL(*client_.get(), OnReadComplete(Status::kSuccess, _, 4));
-  EXPECT_CALL(*client_.get(), OnReadComplete(Status::kInUse, _, 0));
+  EXPECT_CALL(*client_.get(), OnReadComplete(Status::kSuccess, _));
+  EXPECT_CALL(*client_.get(), OnReadComplete(Status::kInUse, _));
   file_io_->Read();
   file_io_->Read();
   base::RunLoop().RunUntilIdle();
@@ -202,7 +203,7 @@ TEST_F(MojoCdmFileIOTest, Write) {
         std::move(callback).Run(mojom::CdmFile::Status::kSuccess);
       });
   EXPECT_CALL(*client_.get(), OnWriteComplete(Status::kSuccess));
-  file_io_->Write(data.data(), data.size());
+  file_io_->Write(data);
   base::RunLoop().RunUntilIdle();
 }
 
@@ -211,7 +212,7 @@ TEST_F(MojoCdmFileIOTest, WriteBeforeOpen) {
 
   // File not open, so writing should fail.
   EXPECT_CALL(*client_.get(), OnWriteComplete(Status::kError));
-  file_io_->Write(data.data(), data.size());
+  file_io_->Write(data);
   base::RunLoop().RunUntilIdle();
 }
 
@@ -229,8 +230,8 @@ TEST_F(MojoCdmFileIOTest, TwoWrites) {
       });
   EXPECT_CALL(*client_.get(), OnWriteComplete(Status::kSuccess));
   EXPECT_CALL(*client_.get(), OnWriteComplete(Status::kInUse));
-  file_io_->Write(data.data(), data.size());
-  file_io_->Write(data.data(), data.size());
+  file_io_->Write(data);
+  file_io_->Write(data);
   base::RunLoop().RunUntilIdle();
 }
 
diff --git a/media/mojo/services/mojo_cdm_helper_unittest.cc b/media/mojo/services/mojo_cdm_helper_unittest.cc
index ab3307a2a99c0..c3beff7eff99b 100644
--- a/media/mojo/services/mojo_cdm_helper_unittest.cc
+++ b/media/mojo/services/mojo_cdm_helper_unittest.cc
@@ -29,7 +29,8 @@ class MockFileIOClient : public cdm::FileIOClient {
   ~MockFileIOClient() override = default;
 
   MOCK_METHOD1(OnOpenComplete, void(Status));
-  MOCK_METHOD3(OnReadComplete, void(Status, const uint8_t*, uint32_t));
+  MOCK_METHOD2(OnReadComplete,
+               void(Status, base::span<const uint8_t>));
   MOCK_METHOD1(OnWriteComplete, void(Status));
 };
 
