1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
media / cdm / cdm_host_files.cc [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/cdm/cdm_host_files.h"
#include <memory>
#include <vector>
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/scoped_native_library.h"
#include "build/build_config.h"
#include "media/cdm/api/content_decryption_module_ext.h"
namespace media {
namespace {
// TODO(xhwang): Move this to a common place if needed.
const base::FilePath::CharType kSignatureFileExtension[] =
FILE_PATH_LITERAL(".sig");
// Returns the signature file path given the |file_path|. This function should
// only be used when the signature file and the file are located in the same
// directory, which is the case for the CDM.
base::FilePath GetSigFilePath(const base::FilePath& file_path) {
return file_path.AddExtension(kSignatureFileExtension);
}
} // namespace
CdmHostFiles::CdmHostFiles() {
DVLOG(1) << __func__;
}
CdmHostFiles::~CdmHostFiles() {
DVLOG(1) << __func__;
}
void CdmHostFiles::Initialize(
const base::FilePath& cdm_path,
const std::vector<CdmHostFilePath>& cdm_host_file_paths) {
OpenCdmFile(cdm_path);
OpenCommonFiles(cdm_host_file_paths);
}
CdmHostFiles::Status CdmHostFiles::InitVerification(
base::NativeLibrary cdm_library) {
DVLOG(1) << __func__;
DCHECK(cdm_library);
// Get function pointer exported by the CDM.
// See media/cdm/api/content_decryption_module_ext.h.
using InitVerificationFunc =
bool (*)(const cdm::HostFile* cdm_host_files, uint32_t num_files);
static const char kInitVerificationFuncName[] = "VerifyCdmHost_0";
InitVerificationFunc init_verification_func =
reinterpret_cast<InitVerificationFunc>(
base::GetFunctionPointerFromNativeLibrary(cdm_library,
kInitVerificationFuncName));
if (!init_verification_func) {
LOG(ERROR) << "Function " << kInitVerificationFuncName << " not found.";
CloseAllFiles();
return Status::kGetFunctionFailed;
}
// Fills |cdm_host_files| with common and CDM specific files.
std::vector<cdm::HostFile> cdm_host_files;
TakePlatformFiles(&cdm_host_files);
// std::vector::data() is not guaranteed to be nullptr when empty().
const cdm::HostFile* cdm_host_files_ptr =
cdm_host_files.empty() ? nullptr : cdm_host_files.data();
// Call |init_verification_func| on the CDM with |cdm_host_files|. Note that
// the ownership of these files are transferred to the CDM, which will close
// the files immediately after use.
VLOG(1) << __func__ << ": Calling " << kInitVerificationFuncName << "() with "
<< cdm_host_files.size() << " files.";
for (const auto& host_file : cdm_host_files) {
VLOG(1) << " - File Path: " << host_file.file_path;
VLOG(1) << " - File: " << host_file.file;
VLOG(1) << " - Sig File: " << host_file.sig_file;
}
if (!init_verification_func(cdm_host_files_ptr, cdm_host_files.size())) {
LOG(ERROR) << "Failed to verify CDM host.";
CloseAllFiles();
return Status::kInitVerificationFailed;
}
// Close all files not passed to the CDM.
CloseAllFiles();
return Status::kSuccess;
}
void CdmHostFiles::CloseAllFiles() {
common_files_.clear();
cdm_specific_files_.clear();
}
void CdmHostFiles::OpenCommonFiles(
const std::vector<CdmHostFilePath>& cdm_host_file_paths) {
DCHECK(common_files_.empty());
for (const auto& value : cdm_host_file_paths) {
common_files_.push_back(
CdmHostFile::Create(value.file_path, value.sig_file_path));
}
}
void CdmHostFiles::OpenCdmFile(const base::FilePath& cdm_path) {
DCHECK(!cdm_path.empty());
cdm_specific_files_.push_back(
CdmHostFile::Create(cdm_path, GetSigFilePath(cdm_path)));
}
void CdmHostFiles::TakePlatformFiles(
std::vector<cdm::HostFile>* cdm_host_files) {
DCHECK(cdm_host_files->empty());
// Populate an array of cdm::HostFile.
for (const auto& file : common_files_)
cdm_host_files->push_back(file->TakePlatformFile());
for (const auto& file : cdm_specific_files_)
cdm_host_files->push_back(file->TakePlatformFile());
}
} // namespace media