Source release 17.1.0
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#include "test_host.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "cdm_version.h"
|
||||
#include "device_cert.h"
|
||||
#include "file_store.h"
|
||||
#include "log.h"
|
||||
|
||||
using namespace widevine;
|
||||
@@ -15,28 +18,40 @@ namespace {
|
||||
|
||||
constexpr char kCertificateFilename[] = "cert.bin";
|
||||
|
||||
// Some files are expected to go in global storage. All other files are expected
|
||||
// to go in per-origin storage. To help us enforce this in tests, this set
|
||||
// tracks the filenames that belong in global storage. TestHost::Storage will
|
||||
// reject attempts to access these files via per-origin storage or to access
|
||||
// files not in this list via global storage.
|
||||
const std::unordered_set<std::string> kGlobalFilenames = {
|
||||
"usgtable.bin",
|
||||
"StoredUsageTime.dat",
|
||||
"GenerationNumber.dat",
|
||||
"persistent.dat",
|
||||
"okp.bin",
|
||||
"keybox.dat",
|
||||
wvutil::kOemCertificateFileName,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TestHost::TestHost() { Reset(); }
|
||||
TestHost::~TestHost() { wvcdm::TestSleep::set_callback(nullptr); }
|
||||
TestHost::TestHost() : global_storage_(true), per_origin_storage_(false) {
|
||||
Reset();
|
||||
}
|
||||
TestHost::~TestHost() { wvutil::TestSleep::set_callback(nullptr); }
|
||||
|
||||
void TestHost::Reset() {
|
||||
auto now = std::chrono::steady_clock().now();
|
||||
auto now = std::chrono::system_clock().now();
|
||||
now_ = now.time_since_epoch() / std::chrono::milliseconds(1);
|
||||
wvcdm::TestSleep::set_callback(this);
|
||||
|
||||
save_device_cert_ = false;
|
||||
wvutil::TestSleep::set_callback(this);
|
||||
|
||||
// Surprisingly, std::priority_queue has no clear().
|
||||
while (!timers_.empty()) {
|
||||
timers_.pop();
|
||||
}
|
||||
|
||||
files_.clear();
|
||||
files_[kCertificateFilename] =
|
||||
(device_cert_.size() > 0)
|
||||
? device_cert_
|
||||
: std::string((const char*)kDeviceCert, kDeviceCertSize);
|
||||
global_storage_.Reset();
|
||||
per_origin_storage_.Reset();
|
||||
}
|
||||
|
||||
void TestHost::ElapseTime(int64_t milliseconds) {
|
||||
@@ -64,58 +79,7 @@ void TestHost::ElapseTime(int64_t milliseconds) {
|
||||
now_ = goal_time;
|
||||
}
|
||||
|
||||
int TestHost::NumTimers() const { return timers_.size(); }
|
||||
|
||||
bool TestHost::read(const std::string& name, std::string* data) {
|
||||
StorageMap::iterator it = files_.find(name);
|
||||
bool ok = it != files_.end();
|
||||
LOGV("read file: %s: %s", name.c_str(), ok ? "ok" : "fail");
|
||||
if (!ok) return false;
|
||||
*data = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestHost::write(const std::string& name, const std::string& data) {
|
||||
LOGV("write file: %s", name.c_str());
|
||||
files_[name] = data;
|
||||
if (save_device_cert_ && name.compare(kCertificateFilename) == 0) {
|
||||
device_cert_ = data;
|
||||
save_device_cert_ = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestHost::exists(const std::string& name) {
|
||||
StorageMap::iterator it = files_.find(name);
|
||||
bool ok = it != files_.end();
|
||||
LOGV("exists? %s: %s", name.c_str(), ok ? "true" : "false");
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TestHost::remove(const std::string& name) {
|
||||
LOGV("remove: %s", name.c_str());
|
||||
if (name.empty()) {
|
||||
// If no name, delete all files (see DeviceFiles::DeleteAllFiles())
|
||||
files_.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return files_.erase(name) > 0;
|
||||
}
|
||||
|
||||
int32_t TestHost::size(const std::string& name) {
|
||||
StorageMap::iterator it = files_.find(name);
|
||||
if (it == files_.end()) return -1;
|
||||
return it->second.size();
|
||||
}
|
||||
|
||||
bool TestHost::list(std::vector<std::string>* names) {
|
||||
names->clear();
|
||||
for (StorageMap::iterator it = files_.begin(); it != files_.end(); it++) {
|
||||
names->push_back(it->first);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
size_t TestHost::NumTimers() const { return timers_.size(); }
|
||||
|
||||
int64_t TestHost::now() { return now_; }
|
||||
|
||||
@@ -140,3 +104,77 @@ void TestHost::cancel(IClient* client) {
|
||||
// Now swap the queues.
|
||||
std::swap(timers_, others);
|
||||
}
|
||||
|
||||
TestHost::Storage::Storage(bool is_global) : is_global_(is_global) { Reset(); }
|
||||
|
||||
void TestHost::Storage::Reset() {
|
||||
files_.clear();
|
||||
if (!is_global_) {
|
||||
files_[kCertificateFilename] =
|
||||
std::string((const char*)kDeviceCert, kDeviceCertSize);
|
||||
}
|
||||
}
|
||||
|
||||
bool TestHost::Storage::read(const std::string& name, std::string* data) {
|
||||
StorageMap::iterator it = files_.find(name);
|
||||
bool ok = it != files_.end();
|
||||
LOGV("read file: %s: %s", name.c_str(), ok ? "ok" : "fail");
|
||||
if (!CheckFilename(name) || !ok) return false;
|
||||
*data = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestHost::Storage::write(const std::string& name,
|
||||
const std::string& data) {
|
||||
LOGV("write file: %s", name.c_str());
|
||||
if (!CheckFilename(name)) return false;
|
||||
files_[name] = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestHost::Storage::exists(const std::string& name) {
|
||||
StorageMap::iterator it = files_.find(name);
|
||||
bool ok = it != files_.end();
|
||||
LOGV("exists? %s: %s", name.c_str(), ok ? "true" : "false");
|
||||
if (!CheckFilename(name)) return false;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TestHost::Storage::remove(const std::string& name) {
|
||||
if (name.empty()) {
|
||||
// If no name, delete all files (see DeviceFiles::DeleteAllFiles())
|
||||
LOGV("remove all files");
|
||||
files_.clear();
|
||||
return true;
|
||||
}
|
||||
LOGV("remove: %s", name.c_str());
|
||||
if (!CheckFilename(name)) return false;
|
||||
return files_.erase(name) > 0;
|
||||
}
|
||||
|
||||
int32_t TestHost::Storage::size(const std::string& name) {
|
||||
StorageMap::iterator it = files_.find(name);
|
||||
bool ok = (it != files_.end());
|
||||
LOGV("size? %s: %s", name.c_str(), ok ? "ok" : "fail");
|
||||
if (!CheckFilename(name) || !ok) return -1;
|
||||
return static_cast<int32_t>(it->second.size());
|
||||
}
|
||||
|
||||
bool TestHost::Storage::list(std::vector<std::string>* names) {
|
||||
names->clear();
|
||||
for (StorageMap::iterator it = files_.begin(); it != files_.end(); it++) {
|
||||
names->push_back(it->first);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestHost::Storage::CheckFilename(const std::string& name) {
|
||||
const bool is_global_filename =
|
||||
(kGlobalFilenames.find(name) != kGlobalFilenames.end());
|
||||
if (is_global_ != is_global_filename) {
|
||||
LOGE("Attempt to access %s in %s storage rejected.", name.c_str(),
|
||||
is_global_ ? "global" : "per-origin");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user