ClearKeyStorage.cpp (5805B)
1 /* 2 * Copyright 2015, Mozilla Foundation and contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "ClearKeyStorage.h" 18 19 #include <assert.h> 20 // This include is required in order for content_decryption_module to work 21 // on Unix systems. 22 23 #include <vector> 24 25 #include "ClearKeyUtils.h" 26 #include "content_decryption_module.h" 27 28 using namespace cdm; 29 30 using std::function; 31 using std::string; 32 using std::vector; 33 34 class WriteRecordClient : public FileIOClient { 35 public: 36 /* 37 * This function will take the memory ownership of the parameters and 38 * delete them when done. 39 */ 40 static void Write(Host_11* aHost, string& aRecordName, 41 const vector<uint8_t>& aData, function<void()>&& aOnSuccess, 42 function<void()>&& aOnFailure) { 43 WriteRecordClient* client = new WriteRecordClient( 44 aData, std::move(aOnSuccess), std::move(aOnFailure)); 45 client->Do(aRecordName, aHost); 46 } 47 48 void OnOpenComplete(Status aStatus) override { 49 // If we hit an error, fail. 50 if (aStatus != Status::kSuccess) { 51 Done(aStatus); 52 } else if (mFileIO) { // Otherwise, write our data to the file. 53 mFileIO->Write(mData.data(), mData.size()); 54 } 55 } 56 57 void OnReadComplete(Status aStatus, const uint8_t* aData, 58 uint32_t aDataSize) override { 59 // This function should never be called, we only ever write data with this 60 // client. 61 assert(false); 62 } 63 64 void OnWriteComplete(Status aStatus) override { Done(aStatus); } 65 66 private: 67 explicit WriteRecordClient(const vector<uint8_t>& aData, 68 function<void()>&& aOnSuccess, 69 function<void()>&& aOnFailure) 70 : mFileIO(nullptr), 71 mOnSuccess(std::move(aOnSuccess)), 72 mOnFailure(std::move(aOnFailure)), 73 mData(aData) {} 74 75 void Do(const string& aName, Host_11* aHost) { 76 // Initialize the FileIO. 77 mFileIO = aHost->CreateFileIO(this); 78 mFileIO->Open(aName.c_str(), aName.size()); 79 } 80 81 void Done(cdm::FileIOClient::Status aStatus) { 82 // Note: Call Close() before running continuation, in case the 83 // continuation tries to open the same record; if we call Close() 84 // after running the continuation, the Close() call will arrive 85 // just after the Open() call succeeds, immediately closing the 86 // record we just opened. 87 if (mFileIO) { 88 mFileIO->Close(); 89 } 90 91 if (IO_SUCCEEDED(aStatus)) { 92 mOnSuccess(); 93 } else { 94 mOnFailure(); 95 } 96 97 delete this; 98 } 99 100 FileIO* mFileIO = nullptr; 101 102 function<void()> mOnSuccess; 103 function<void()> mOnFailure; 104 105 const vector<uint8_t> mData; 106 }; 107 108 void WriteData(Host_11* aHost, string& aRecordName, 109 const vector<uint8_t>& aData, function<void()>&& aOnSuccess, 110 function<void()>&& aOnFailure) { 111 WriteRecordClient::Write(aHost, aRecordName, aData, std::move(aOnSuccess), 112 std::move(aOnFailure)); 113 } 114 115 class ReadRecordClient : public FileIOClient { 116 public: 117 /* 118 * This function will take the memory ownership of the parameters and 119 * delete them when done. 120 */ 121 static void Read(Host_11* aHost, string& aRecordName, 122 function<void(const uint8_t*, uint32_t)>&& aOnSuccess, 123 function<void()>&& aOnFailure) { 124 (new ReadRecordClient(std::move(aOnSuccess), std::move(aOnFailure))) 125 ->Do(aRecordName, aHost); 126 } 127 128 void OnOpenComplete(Status aStatus) override { 129 auto err = aStatus; 130 if (aStatus != Status::kSuccess) { 131 Done(err, nullptr, 0); 132 } else { 133 mFileIO->Read(); 134 } 135 } 136 137 void OnReadComplete(Status aStatus, const uint8_t* aData, 138 uint32_t aDataSize) override { 139 Done(aStatus, aData, aDataSize); 140 } 141 142 void OnWriteComplete(Status aStatus) override { 143 // We should never reach here, this client only ever reads data. 144 assert(false); 145 } 146 147 private: 148 explicit ReadRecordClient( 149 function<void(const uint8_t*, uint32_t)>&& aOnSuccess, 150 function<void()>&& aOnFailure) 151 : mFileIO(nullptr), 152 mOnSuccess(std::move(aOnSuccess)), 153 mOnFailure(std::move(aOnFailure)) {} 154 155 void Do(const string& aName, Host_11* aHost) { 156 mFileIO = aHost->CreateFileIO(this); 157 mFileIO->Open(aName.c_str(), aName.size()); 158 } 159 160 void Done(cdm::FileIOClient::Status aStatus, const uint8_t* aData, 161 uint32_t aDataSize) { 162 // Note: Call Close() before running continuation, in case the 163 // continuation tries to open the same record; if we call Close() 164 // after running the continuation, the Close() call will arrive 165 // just after the Open() call succeeds, immediately closing the 166 // record we just opened. 167 if (mFileIO) { 168 mFileIO->Close(); 169 } 170 171 if (IO_SUCCEEDED(aStatus)) { 172 mOnSuccess(aData, aDataSize); 173 } else { 174 mOnFailure(); 175 } 176 177 delete this; 178 } 179 180 FileIO* mFileIO = nullptr; 181 182 function<void(const uint8_t*, uint32_t)> mOnSuccess; 183 function<void()> mOnFailure; 184 }; 185 186 void ReadData(Host_11* aHost, string& aRecordName, 187 function<void(const uint8_t*, uint32_t)>&& aOnSuccess, 188 function<void()>&& aOnFailure) { 189 ReadRecordClient::Read(aHost, aRecordName, std::move(aOnSuccess), 190 std::move(aOnFailure)); 191 }