1 // Copyright 2020 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 "chromeos/components/cdm_factory_daemon/cdm_storage_adapter.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "mojo/public/cpp/bindings/callback_helpers.h"
11
12 namespace chromeos {
13
14 namespace {
15
16 // Helper function to adapt Exists using Read since CdmStorage doesn't have an
17 // Exists implementation. We test it by seeing if the file is non-empty.
ReadToExists(cdm::mojom::CdmStorage::ExistsCallback callback,bool success,const std::vector<uint8_t> & data)18 void ReadToExists(cdm::mojom::CdmStorage::ExistsCallback callback,
19 bool success,
20 const std::vector<uint8_t>& data) {
21 std::move(callback).Run(success && !data.empty());
22 }
23
24 // Helper function to adapt GetSize using Read since CdmFile doesn't have a
25 // GetSize implementation. We get the size by reading the file contents and
26 // determining the length. These files will be small in size and are accessed
27 // infrequently, so this isn't that much of a penalty to pay.
ReadToGetSize(cdm::mojom::CdmStorage::GetSizeCallback callback,bool success,const std::vector<uint8_t> & data)28 void ReadToGetSize(cdm::mojom::CdmStorage::GetSizeCallback callback,
29 bool success,
30 const std::vector<uint8_t>& data) {
31 std::move(callback).Run(success, data.size());
32 }
33
34 } // namespace
35
CdmStorageAdapter(media::mojom::FrameInterfaceFactory * frame_interfaces,mojo::PendingAssociatedReceiver<chromeos::cdm::mojom::CdmStorage> receiver)36 CdmStorageAdapter::CdmStorageAdapter(
37 media::mojom::FrameInterfaceFactory* frame_interfaces,
38 mojo::PendingAssociatedReceiver<chromeos::cdm::mojom::CdmStorage> receiver)
39 : receiver_(this, std::move(receiver)) {
40 CHECK(frame_interfaces);
41 frame_interfaces->CreateCdmStorage(
42 cdm_storage_remote_.BindNewPipeAndPassReceiver());
43 }
44
45 CdmStorageAdapter::~CdmStorageAdapter() = default;
46
Read(const std::string & file_name,ReadCallback callback)47 void CdmStorageAdapter::Read(const std::string& file_name,
48 ReadCallback callback) {
49 DVLOG(1) << "Read " << file_name;
50 CHECK(!cdm_file_);
51 auto wrapped_callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
52 std::move(callback), false, std::vector<uint8_t>());
53 cdm_storage_remote_->Open(
54 file_name,
55 base::BindOnce(&CdmStorageAdapter::OnOpenForRead,
56 weak_factory_.GetWeakPtr(), std::move(wrapped_callback)));
57 }
58
OnOpenForRead(ReadCallback callback,media::mojom::CdmStorage::Status status,mojo::PendingAssociatedRemote<media::mojom::CdmFile> cdm_file)59 void CdmStorageAdapter::OnOpenForRead(
60 ReadCallback callback,
61 media::mojom::CdmStorage::Status status,
62 mojo::PendingAssociatedRemote<media::mojom::CdmFile> cdm_file) {
63 if (status != media::mojom::CdmStorage::Status::kSuccess) {
64 std::move(callback).Run(false, {});
65 return;
66 }
67 cdm_file_.Bind(std::move(cdm_file));
68 cdm_file_->Read(base::BindOnce(&CdmStorageAdapter::OnReadComplete,
69 weak_factory_.GetWeakPtr(),
70 std::move(callback)));
71 }
72
OnReadComplete(ReadCallback callback,media::mojom::CdmFile::Status status,const std::vector<uint8_t> & data)73 void CdmStorageAdapter::OnReadComplete(ReadCallback callback,
74 media::mojom::CdmFile::Status status,
75 const std::vector<uint8_t>& data) {
76 cdm_file_.reset();
77 if (status != media::mojom::CdmFile::Status::kSuccess) {
78 std::move(callback).Run(false, {});
79 return;
80 }
81 std::move(callback).Run(true, data);
82 }
83
Write(const std::string & file_name,const std::vector<uint8_t> & data,WriteCallback callback)84 void CdmStorageAdapter::Write(const std::string& file_name,
85 const std::vector<uint8_t>& data,
86 WriteCallback callback) {
87 DVLOG(1) << "Write " << file_name;
88 CHECK(!cdm_file_);
89 auto wrapped_callback =
90 mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), false);
91 cdm_storage_remote_->Open(file_name,
92 base::BindOnce(&CdmStorageAdapter::OnOpenForWrite,
93 weak_factory_.GetWeakPtr(), data,
94 std::move(wrapped_callback)));
95 }
96
OnOpenForWrite(const std::vector<uint8_t> & data,WriteCallback callback,media::mojom::CdmStorage::Status status,mojo::PendingAssociatedRemote<media::mojom::CdmFile> cdm_file)97 void CdmStorageAdapter::OnOpenForWrite(
98 const std::vector<uint8_t>& data,
99 WriteCallback callback,
100 media::mojom::CdmStorage::Status status,
101 mojo::PendingAssociatedRemote<media::mojom::CdmFile> cdm_file) {
102 if (status != media::mojom::CdmStorage::Status::kSuccess) {
103 std::move(callback).Run(false);
104 return;
105 }
106 cdm_file_.Bind(std::move(cdm_file));
107 cdm_file_->Write(
108 data, base::BindOnce(&CdmStorageAdapter::OnWriteComplete,
109 weak_factory_.GetWeakPtr(), std::move(callback)));
110 }
111
OnWriteComplete(WriteCallback callback,media::mojom::CdmFile::Status status)112 void CdmStorageAdapter::OnWriteComplete(WriteCallback callback,
113 media::mojom::CdmFile::Status status) {
114 cdm_file_.reset();
115 std::move(callback).Run(status == media::mojom::CdmFile::Status::kSuccess);
116 }
117
Exists(const std::string & file_name,ExistsCallback callback)118 void CdmStorageAdapter::Exists(const std::string& file_name,
119 ExistsCallback callback) {
120 DVLOG(1) << "Exists " << file_name;
121 Read(file_name, base::BindOnce(&ReadToExists, std::move(callback)));
122 }
123
GetSize(const std::string & file_name,GetSizeCallback callback)124 void CdmStorageAdapter::GetSize(const std::string& file_name,
125 GetSizeCallback callback) {
126 DVLOG(1) << "GetSize " << file_name;
127 Read(file_name, base::BindOnce(&ReadToGetSize, std::move(callback)));
128 }
129
Remove(const std::string & file_name,RemoveCallback callback)130 void CdmStorageAdapter::Remove(const std::string& file_name,
131 RemoveCallback callback) {
132 DVLOG(1) << "Remove " << file_name;
133 // Writing a zero length array to the file removes it.
134 Write(file_name, {}, std::move(callback));
135 }
136
137 } // namespace chromeos