1 /*
2  * Copyright (C) 2018 The Android Open Source Project
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 //#define LOG_NDEBUG 0
18 #include <vector>
19 #define LOG_TAG "hidl_ClearKeyDrmFactory"
20 #include <utils/Log.h>
21 
22 #include <utils/Errors.h>
23 
24 #include "DrmFactory.h"
25 
26 #include "DrmPlugin.h"
27 #include "ClearKeyUUID.h"
28 #include "MimeType.h"
29 #include "SessionLibrary.h"
30 
31 namespace android {
32 namespace hardware {
33 namespace drm {
34 namespace V1_3 {
35 namespace clearkey {
36 
37 using ::android::hardware::drm::V1_0::Status;
38 using ::android::hardware::drm::V1_1::SecurityLevel;
39 using ::android::hardware::drm::V1_2::clearkey::DrmPlugin;
40 using ::android::hardware::drm::V1_2::clearkey::SessionLibrary;
41 using ::android::hardware::Void;
42 
isCryptoSchemeSupported(const hidl_array<uint8_t,16> & uuid)43 Return<bool> DrmFactory::isCryptoSchemeSupported(
44         const hidl_array<uint8_t, 16>& uuid) {
45     return clearkeydrm::isClearKeyUUID(uuid.data());
46 }
47 
isCryptoSchemeSupported_1_2(const hidl_array<uint8_t,16> & uuid,const hidl_string & mimeType,SecurityLevel level)48 Return<bool> DrmFactory::isCryptoSchemeSupported_1_2(const hidl_array<uint8_t, 16>& uuid,
49                                                      const hidl_string &mimeType,
50                                                      SecurityLevel level) {
51     return isCryptoSchemeSupported(uuid) && isContentTypeSupported(mimeType) &&
52             level == SecurityLevel::SW_SECURE_CRYPTO;
53 }
54 
isContentTypeSupported(const hidl_string & mimeType)55 Return<bool> DrmFactory::isContentTypeSupported(const hidl_string &mimeType) {
56     // This should match the mimeTypes handed by InitDataParser.
57     return mimeType == kIsoBmffVideoMimeType ||
58             mimeType == kIsoBmffAudioMimeType ||
59             mimeType == kCencInitDataFormat ||
60             mimeType == kWebmVideoMimeType ||
61             mimeType == kWebmAudioMimeType ||
62             mimeType == kWebmInitDataFormat;
63 }
64 
createPlugin(const hidl_array<uint8_t,16> & uuid,const hidl_string & appPackageName,createPlugin_cb _hidl_cb)65 Return<void> DrmFactory::createPlugin(
66     const hidl_array<uint8_t, 16>& uuid,
67     const hidl_string& appPackageName,
68     createPlugin_cb _hidl_cb) {
69     UNUSED(appPackageName);
70 
71     DrmPlugin *plugin = NULL;
72     if (!isCryptoSchemeSupported(uuid.data())) {
73         ALOGE("Clear key Drm HAL: failed to create drm plugin, " \
74                 "invalid crypto scheme");
75         _hidl_cb(Status::BAD_VALUE, plugin);
76         return Void();
77     }
78 
79     plugin = new DrmPlugin(SessionLibrary::get());
80     _hidl_cb(Status::OK, plugin);
81     return Void();
82 }
83 
getSupportedCryptoSchemes(getSupportedCryptoSchemes_cb _hidl_cb)84 Return<void> DrmFactory::getSupportedCryptoSchemes(
85         getSupportedCryptoSchemes_cb _hidl_cb) {
86     std::vector<hidl_array<uint8_t, 16>> schemes;
87     for (const auto &scheme : clearkeydrm::getSupportedCryptoSchemes()) {
88         schemes.push_back(scheme);
89     }
90     _hidl_cb(schemes);
91     return Void();
92 }
93 
debug(const hidl_handle & fd,const hidl_vec<hidl_string> &)94 Return<void> DrmFactory::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /*args*/) {
95     if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
96         ALOGE("%s: missing fd for writing", __FUNCTION__);
97         return Void();
98     }
99 
100     FILE* out = fdopen(dup(fd->data[0]), "w");
101     uint32_t currentSessions = SessionLibrary::get()->numOpenSessions();
102     fprintf(out, "current open sessions: %u\n", currentSessions);
103     fclose(out);
104     return Void();
105 }
106 
107 } // namespace clearkey
108 } // namespace V1_3
109 } // namespace drm
110 } // namespace hardware
111 } // namespace android
112