| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #define LOG_TAG "android.hardware.drm@1.0-impl" |
| |
| #include <utils/KeyedVector.h> |
| #include <utils/String8.h> |
| |
| #include "DrmPlugin.h" |
| #include "TypeConvert.h" |
| |
| namespace android { |
| namespace hardware { |
| namespace drm { |
| namespace V1_0 { |
| namespace implementation { |
| |
| // Methods from ::android::hardware::drm::V1_0::IDrmPlugin follow. |
| |
| Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) { |
| Vector<uint8_t> legacySessionId; |
| status_t status = mLegacyPlugin->openSession(legacySessionId); |
| _hidl_cb(toStatus(status), toHidlVec(legacySessionId)); |
| return Void(); |
| } |
| |
| Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) { |
| return toStatus(mLegacyPlugin->closeSession(toVector(sessionId))); |
| } |
| |
| Return<void> DrmPlugin::getKeyRequest(const hidl_vec<uint8_t>& scope, |
| const hidl_vec<uint8_t>& initData, const hidl_string& mimeType, |
| KeyType keyType, const hidl_vec<KeyValue>& optionalParameters, |
| getKeyRequest_cb _hidl_cb) { |
| |
| status_t status = android::OK; |
| |
| android::DrmPlugin::KeyType legacyKeyType; |
| switch(keyType) { |
| case KeyType::OFFLINE: |
| legacyKeyType = android::DrmPlugin::kKeyType_Offline; |
| break; |
| case KeyType::STREAMING: |
| legacyKeyType = android::DrmPlugin::kKeyType_Streaming; |
| break; |
| case KeyType::RELEASE: |
| legacyKeyType = android::DrmPlugin::kKeyType_Release; |
| break; |
| default: |
| status = android::BAD_VALUE; |
| break; |
| } |
| |
| Vector<uint8_t> legacyRequest; |
| KeyRequestType requestType = KeyRequestType::UNKNOWN; |
| String8 defaultUrl; |
| |
| if (status == android::OK) { |
| android::KeyedVector<String8, String8> legacyOptionalParameters; |
| for (size_t i = 0; i < optionalParameters.size(); i++) { |
| legacyOptionalParameters.add(String8(optionalParameters[i].key.c_str()), |
| String8(optionalParameters[i].value.c_str())); |
| } |
| |
| android::DrmPlugin::KeyRequestType legacyRequestType = |
| android::DrmPlugin::kKeyRequestType_Unknown; |
| |
| status = mLegacyPlugin->getKeyRequest(toVector(scope), |
| toVector(initData), String8(mimeType.c_str()), legacyKeyType, |
| legacyOptionalParameters, legacyRequest, defaultUrl, |
| &legacyRequestType); |
| |
| switch(legacyRequestType) { |
| case android::DrmPlugin::kKeyRequestType_Initial: |
| requestType = KeyRequestType::INITIAL; |
| break; |
| case android::DrmPlugin::kKeyRequestType_Renewal: |
| requestType = KeyRequestType::RENEWAL; |
| break; |
| case android::DrmPlugin::kKeyRequestType_Release: |
| requestType = KeyRequestType::RELEASE; |
| break; |
| case android::DrmPlugin::kKeyRequestType_Unknown: |
| default: |
| requestType = KeyRequestType::UNKNOWN; |
| break; |
| } |
| } |
| _hidl_cb(toStatus(status), toHidlVec(legacyRequest), requestType, defaultUrl.c_str()); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::provideKeyResponse(const hidl_vec<uint8_t>& scope, |
| const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb) { |
| |
| Vector<uint8_t> keySetId; |
| status_t status = mLegacyPlugin->provideKeyResponse(toVector(scope), |
| toVector(response), keySetId); |
| _hidl_cb(toStatus(status), toHidlVec(keySetId)); |
| return Void(); |
| } |
| |
| Return<Status> DrmPlugin::removeKeys(const hidl_vec<uint8_t>& sessionId) { |
| return toStatus(mLegacyPlugin->removeKeys(toVector(sessionId))); |
| } |
| |
| Return<Status> DrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId, |
| const hidl_vec<uint8_t>& keySetId) { |
| status_t legacyStatus = mLegacyPlugin->restoreKeys(toVector(sessionId), |
| toVector(keySetId)); |
| return toStatus(legacyStatus); |
| } |
| |
| Return<void> DrmPlugin::queryKeyStatus(const hidl_vec<uint8_t>& sessionId, |
| queryKeyStatus_cb _hidl_cb) { |
| |
| android::KeyedVector<String8, String8> legacyInfoMap; |
| status_t status = mLegacyPlugin->queryKeyStatus(toVector(sessionId), |
| legacyInfoMap); |
| |
| Vector<KeyValue> infoMapVec; |
| for (size_t i = 0; i < legacyInfoMap.size(); i++) { |
| KeyValue keyValuePair; |
| keyValuePair.key = legacyInfoMap.keyAt(i); |
| keyValuePair.value = legacyInfoMap.valueAt(i); |
| infoMapVec.push_back(keyValuePair); |
| } |
| _hidl_cb(toStatus(status), toHidlVec(infoMapVec)); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::getProvisionRequest( |
| const hidl_string& certificateType, |
| const hidl_string& certificateAuthority, |
| getProvisionRequest_cb _hidl_cb) { |
| |
| Vector<uint8_t> legacyRequest; |
| String8 legacyDefaultUrl; |
| status_t status = mLegacyPlugin->getProvisionRequest( |
| String8(certificateType.c_str()), String8(certificateAuthority.c_str()), |
| legacyRequest, legacyDefaultUrl); |
| |
| _hidl_cb(toStatus(status), toHidlVec(legacyRequest), |
| hidl_string(legacyDefaultUrl)); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::provideProvisionResponse( |
| const hidl_vec<uint8_t>& response, |
| provideProvisionResponse_cb _hidl_cb) { |
| |
| Vector<uint8_t> certificate; |
| Vector<uint8_t> wrappedKey; |
| |
| status_t legacyStatus = mLegacyPlugin->provideProvisionResponse( |
| toVector(response), certificate, wrappedKey); |
| |
| _hidl_cb(toStatus(legacyStatus), toHidlVec(certificate), |
| toHidlVec(wrappedKey)); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) { |
| List<Vector<uint8_t> > legacySecureStops; |
| status_t status = mLegacyPlugin->getSecureStops(legacySecureStops); |
| |
| Vector<SecureStop> secureStopsVec; |
| List<Vector<uint8_t> >::iterator iter = legacySecureStops.begin(); |
| |
| while (iter != legacySecureStops.end()) { |
| SecureStop secureStop; |
| secureStop.opaqueData = toHidlVec(*iter++); |
| secureStopsVec.push_back(secureStop); |
| } |
| |
| _hidl_cb(toStatus(status), toHidlVec(secureStopsVec)); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId, |
| getSecureStop_cb _hidl_cb) { |
| |
| Vector<uint8_t> legacySecureStop; |
| status_t status = mLegacyPlugin->getSecureStop(toVector(secureStopId), |
| legacySecureStop); |
| |
| SecureStop secureStop; |
| secureStop.opaqueData = toHidlVec(legacySecureStop); |
| _hidl_cb(toStatus(status), secureStop); |
| return Void(); |
| } |
| |
| Return<Status> DrmPlugin::releaseAllSecureStops() { |
| return toStatus(mLegacyPlugin->releaseAllSecureStops()); |
| } |
| |
| Return<Status> DrmPlugin::releaseSecureStop( |
| const hidl_vec<uint8_t>& secureStopId) { |
| status_t legacyStatus = |
| mLegacyPlugin->releaseSecureStops(toVector(secureStopId)); |
| return toStatus(legacyStatus); |
| } |
| |
| Return<void> DrmPlugin::getPropertyString(const hidl_string& propertyName, |
| getPropertyString_cb _hidl_cb) { |
| String8 legacyValue; |
| status_t status = mLegacyPlugin->getPropertyString( |
| String8(propertyName.c_str()), legacyValue); |
| _hidl_cb(toStatus(status), legacyValue.c_str()); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::getPropertyByteArray(const hidl_string& propertyName, |
| getPropertyByteArray_cb _hidl_cb) { |
| Vector<uint8_t> legacyValue; |
| status_t status = mLegacyPlugin->getPropertyByteArray( |
| String8(propertyName.c_str()), legacyValue); |
| _hidl_cb(toStatus(status), toHidlVec(legacyValue)); |
| return Void(); |
| } |
| |
| Return<Status> DrmPlugin::setPropertyString(const hidl_string& propertyName, |
| const hidl_string& value) { |
| status_t legacyStatus = |
| mLegacyPlugin->setPropertyString(String8(propertyName.c_str()), |
| String8(value.c_str())); |
| return toStatus(legacyStatus); |
| } |
| |
| Return<Status> DrmPlugin::setPropertyByteArray( |
| const hidl_string& propertyName, const hidl_vec<uint8_t>& value) { |
| status_t legacyStatus = |
| mLegacyPlugin->setPropertyByteArray(String8(propertyName.c_str()), |
| toVector(value)); |
| return toStatus(legacyStatus); |
| } |
| |
| Return<Status> DrmPlugin::setCipherAlgorithm( |
| const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) { |
| status_t legacyStatus = |
| mLegacyPlugin->setCipherAlgorithm(toVector(sessionId), |
| String8(algorithm.c_str())); |
| return toStatus(legacyStatus); |
| } |
| |
| Return<Status> DrmPlugin::setMacAlgorithm( |
| const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) { |
| status_t legacyStatus = |
| mLegacyPlugin->setMacAlgorithm(toVector(sessionId), |
| String8(algorithm.c_str())); |
| return toStatus(legacyStatus); |
| } |
| |
| Return<void> DrmPlugin::encrypt(const hidl_vec<uint8_t>& sessionId, |
| const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input, |
| const hidl_vec<uint8_t>& iv, encrypt_cb _hidl_cb) { |
| |
| Vector<uint8_t> legacyOutput; |
| status_t status = mLegacyPlugin->encrypt(toVector(sessionId), |
| toVector(keyId), toVector(input), toVector(iv), legacyOutput); |
| _hidl_cb(toStatus(status), toHidlVec(legacyOutput)); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::decrypt(const hidl_vec<uint8_t>& sessionId, |
| const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input, |
| const hidl_vec<uint8_t>& iv, decrypt_cb _hidl_cb) { |
| |
| Vector<uint8_t> legacyOutput; |
| status_t status = mLegacyPlugin->decrypt(toVector(sessionId), |
| toVector(keyId), toVector(input), toVector(iv), legacyOutput); |
| _hidl_cb(toStatus(status), toHidlVec(legacyOutput)); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::sign(const hidl_vec<uint8_t>& sessionId, |
| const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message, |
| sign_cb _hidl_cb) { |
| Vector<uint8_t> legacySignature; |
| status_t status = mLegacyPlugin->sign(toVector(sessionId), |
| toVector(keyId), toVector(message), legacySignature); |
| _hidl_cb(toStatus(status), toHidlVec(legacySignature)); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::verify(const hidl_vec<uint8_t>& sessionId, |
| const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message, |
| const hidl_vec<uint8_t>& signature, verify_cb _hidl_cb) { |
| |
| bool match; |
| status_t status = mLegacyPlugin->verify(toVector(sessionId), |
| toVector(keyId), toVector(message), toVector(signature), |
| match); |
| _hidl_cb(toStatus(status), match); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::signRSA(const hidl_vec<uint8_t>& sessionId, |
| const hidl_string& algorithm, const hidl_vec<uint8_t>& message, |
| const hidl_vec<uint8_t>& wrappedKey, signRSA_cb _hidl_cb) { |
| |
| Vector<uint8_t> legacySignature; |
| status_t status = mLegacyPlugin->signRSA(toVector(sessionId), |
| String8(algorithm.c_str()), toVector(message), toVector(wrappedKey), |
| legacySignature); |
| _hidl_cb(toStatus(status), toHidlVec(legacySignature)); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::setListener(const sp<IDrmPluginListener>& listener) { |
| mListener = listener; |
| mLegacyPlugin->setListener(listener == NULL ? NULL : this); |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::sendEvent(EventType eventType, |
| const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) { |
| if (mListener != nullptr) { |
| mListener->sendEvent(eventType, sessionId, data); |
| } |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::sendExpirationUpdate( |
| const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) { |
| if (mListener != nullptr) { |
| mListener->sendExpirationUpdate(sessionId, expiryTimeInMS); |
| } |
| return Void(); |
| } |
| |
| Return<void> DrmPlugin::sendKeysChange(const hidl_vec<uint8_t>& sessionId, |
| const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) { |
| if (mListener != nullptr) { |
| mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey); |
| } |
| return Void(); |
| } |
| |
| |
| // Methods from android::DrmPluginListener |
| |
| void DrmPlugin::sendEvent(android::DrmPlugin::EventType legacyEventType, |
| int /*unused*/, Vector<uint8_t> const *sessionId, |
| Vector<uint8_t> const *data) { |
| |
| EventType eventType; |
| bool sendEvent = true; |
| switch(legacyEventType) { |
| case android::DrmPlugin::kDrmPluginEventProvisionRequired: |
| eventType = EventType::PROVISION_REQUIRED; |
| break; |
| case android::DrmPlugin::kDrmPluginEventKeyNeeded: |
| eventType = EventType::KEY_NEEDED; |
| break; |
| case android::DrmPlugin::kDrmPluginEventKeyExpired: |
| eventType = EventType::KEY_EXPIRED; |
| break; |
| case android::DrmPlugin::kDrmPluginEventVendorDefined: |
| eventType = EventType::VENDOR_DEFINED; |
| break; |
| case android::DrmPlugin::kDrmPluginEventSessionReclaimed: |
| eventType = EventType::SESSION_RECLAIMED; |
| break; |
| default: |
| sendEvent = false; |
| break; |
| } |
| if (sendEvent) { |
| Vector<uint8_t> emptyVector; |
| mListener->sendEvent(eventType, |
| toHidlVec(sessionId == NULL ? emptyVector: *sessionId), |
| toHidlVec(data == NULL ? emptyVector: *data)); |
| } |
| } |
| |
| void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId, |
| int64_t expiryTimeInMS) { |
| mListener->sendExpirationUpdate(toHidlVec(*sessionId), expiryTimeInMS); |
| } |
| |
| void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId, |
| Vector<android::DrmPlugin::KeyStatus> const *legacyKeyStatusList, |
| bool hasNewUsableKey) { |
| |
| Vector<KeyStatus> keyStatusVec; |
| for (size_t i = 0; i < legacyKeyStatusList->size(); i++) { |
| const android::DrmPlugin::KeyStatus &legacyKeyStatus = |
| legacyKeyStatusList->itemAt(i); |
| |
| KeyStatus keyStatus; |
| |
| switch(legacyKeyStatus.mType) { |
| case android::DrmPlugin::kKeyStatusType_Usable: |
| keyStatus.type = KeyStatusType::USABLE; |
| break; |
| case android::DrmPlugin::kKeyStatusType_Expired: |
| keyStatus.type = KeyStatusType::EXPIRED; |
| break; |
| case android::DrmPlugin::kKeyStatusType_OutputNotAllowed: |
| keyStatus.type = KeyStatusType::OUTPUTNOTALLOWED; |
| break; |
| case android::DrmPlugin::kKeyStatusType_StatusPending: |
| keyStatus.type = KeyStatusType::STATUSPENDING; |
| break; |
| case android::DrmPlugin::kKeyStatusType_InternalError: |
| default: |
| keyStatus.type = KeyStatusType::INTERNALERROR; |
| break; |
| } |
| |
| keyStatus.keyId = toHidlVec(legacyKeyStatus.mKeyId); |
| keyStatusVec.push_back(keyStatus); |
| } |
| mListener->sendKeysChange(toHidlVec(*sessionId), |
| toHidlVec(keyStatusVec), hasNewUsableKey); |
| } |
| |
| } // namespace implementation |
| } // namespace V1_0 |
| } // namespace drm |
| } // namespace hardware |
| } // namespace android |