/* * 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 #include #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 DrmPlugin::openSession(openSession_cb _hidl_cb) { Vector legacySessionId; status_t status = mLegacyPlugin->openSession(legacySessionId); _hidl_cb(toStatus(status), toHidlVec(legacySessionId)); return Void(); } Return DrmPlugin::closeSession(const hidl_vec& sessionId) { return toStatus(mLegacyPlugin->closeSession(toVector(sessionId))); } Return DrmPlugin::getKeyRequest(const hidl_vec& scope, const hidl_vec& initData, const hidl_string& mimeType, KeyType keyType, const hidl_vec& 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 legacyRequest; KeyRequestType requestType = KeyRequestType::UNKNOWN; String8 defaultUrl; if (status == android::OK) { android::KeyedVector 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.string()); return Void(); } Return DrmPlugin::provideKeyResponse(const hidl_vec& scope, const hidl_vec& response, provideKeyResponse_cb _hidl_cb) { Vector keySetId; status_t status = mLegacyPlugin->provideKeyResponse(toVector(scope), toVector(response), keySetId); _hidl_cb(toStatus(status), toHidlVec(keySetId)); return Void(); } Return DrmPlugin::removeKeys(const hidl_vec& sessionId) { return toStatus(mLegacyPlugin->removeKeys(toVector(sessionId))); } Return DrmPlugin::restoreKeys(const hidl_vec& sessionId, const hidl_vec& keySetId) { status_t legacyStatus = mLegacyPlugin->restoreKeys(toVector(sessionId), toVector(keySetId)); return toStatus(legacyStatus); } Return DrmPlugin::queryKeyStatus(const hidl_vec& sessionId, queryKeyStatus_cb _hidl_cb) { android::KeyedVector legacyInfoMap; status_t status = mLegacyPlugin->queryKeyStatus(toVector(sessionId), legacyInfoMap); Vector infoMapVec; for (size_t i = 0; i < legacyInfoMap.size(); i++) { KeyValue keyValuePair; keyValuePair.key = String8(legacyInfoMap.keyAt(i)); keyValuePair.value = String8(legacyInfoMap.valueAt(i)); infoMapVec.push_back(keyValuePair); } _hidl_cb(toStatus(status), toHidlVec(infoMapVec)); return Void(); } Return DrmPlugin::getProvisionRequest( const hidl_string& certificateType, const hidl_string& certificateAuthority, getProvisionRequest_cb _hidl_cb) { Vector 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 DrmPlugin::provideProvisionResponse( const hidl_vec& response, provideProvisionResponse_cb _hidl_cb) { Vector certificate; Vector wrappedKey; status_t legacyStatus = mLegacyPlugin->provideProvisionResponse( toVector(response), certificate, wrappedKey); _hidl_cb(toStatus(legacyStatus), toHidlVec(certificate), toHidlVec(wrappedKey)); return Void(); } Return DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) { List > legacySecureStops; status_t status = mLegacyPlugin->getSecureStops(legacySecureStops); Vector secureStopsVec; List >::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 DrmPlugin::getSecureStop(const hidl_vec& secureStopId, getSecureStop_cb _hidl_cb) { Vector legacySecureStop; status_t status = mLegacyPlugin->getSecureStop(toVector(secureStopId), legacySecureStop); SecureStop secureStop; secureStop.opaqueData = toHidlVec(legacySecureStop); _hidl_cb(toStatus(status), secureStop); return Void(); } Return DrmPlugin::releaseAllSecureStops() { return toStatus(mLegacyPlugin->releaseAllSecureStops()); } Return DrmPlugin::releaseSecureStop( const hidl_vec& secureStopId) { status_t legacyStatus = mLegacyPlugin->releaseSecureStops(toVector(secureStopId)); return toStatus(legacyStatus); } Return 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.string()); return Void(); } Return DrmPlugin::getPropertyByteArray(const hidl_string& propertyName, getPropertyByteArray_cb _hidl_cb) { Vector legacyValue; status_t status = mLegacyPlugin->getPropertyByteArray( String8(propertyName.c_str()), legacyValue); _hidl_cb(toStatus(status), toHidlVec(legacyValue)); return Void(); } Return 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 DrmPlugin::setPropertyByteArray( const hidl_string& propertyName, const hidl_vec& value) { status_t legacyStatus = mLegacyPlugin->setPropertyByteArray(String8(propertyName.c_str()), toVector(value)); return toStatus(legacyStatus); } Return DrmPlugin::setCipherAlgorithm( const hidl_vec& sessionId, const hidl_string& algorithm) { status_t legacyStatus = mLegacyPlugin->setCipherAlgorithm(toVector(sessionId), String8(algorithm.c_str())); return toStatus(legacyStatus); } Return DrmPlugin::setMacAlgorithm( const hidl_vec& sessionId, const hidl_string& algorithm) { status_t legacyStatus = mLegacyPlugin->setMacAlgorithm(toVector(sessionId), String8(algorithm.c_str())); return toStatus(legacyStatus); } Return DrmPlugin::encrypt(const hidl_vec& sessionId, const hidl_vec& keyId, const hidl_vec& input, const hidl_vec& iv, encrypt_cb _hidl_cb) { Vector legacyOutput; status_t status = mLegacyPlugin->encrypt(toVector(sessionId), toVector(keyId), toVector(input), toVector(iv), legacyOutput); _hidl_cb(toStatus(status), toHidlVec(legacyOutput)); return Void(); } Return DrmPlugin::decrypt(const hidl_vec& sessionId, const hidl_vec& keyId, const hidl_vec& input, const hidl_vec& iv, decrypt_cb _hidl_cb) { Vector legacyOutput; status_t status = mLegacyPlugin->decrypt(toVector(sessionId), toVector(keyId), toVector(input), toVector(iv), legacyOutput); _hidl_cb(toStatus(status), toHidlVec(legacyOutput)); return Void(); } Return DrmPlugin::sign(const hidl_vec& sessionId, const hidl_vec& keyId, const hidl_vec& message, sign_cb _hidl_cb) { Vector legacySignature; status_t status = mLegacyPlugin->sign(toVector(sessionId), toVector(keyId), toVector(message), legacySignature); _hidl_cb(toStatus(status), toHidlVec(legacySignature)); return Void(); } Return DrmPlugin::verify(const hidl_vec& sessionId, const hidl_vec& keyId, const hidl_vec& message, const hidl_vec& 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 DrmPlugin::signRSA(const hidl_vec& sessionId, const hidl_string& algorithm, const hidl_vec& message, const hidl_vec& wrappedKey, signRSA_cb _hidl_cb) { Vector 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 DrmPlugin::setListener(const sp& listener) { mListener = listener; mLegacyPlugin->setListener(listener == NULL ? NULL : this); return Void(); } Return DrmPlugin::sendEvent(EventType eventType, const hidl_vec& sessionId, const hidl_vec& data) { if (mListener != nullptr) { mListener->sendEvent(eventType, sessionId, data); } return Void(); } Return DrmPlugin::sendExpirationUpdate( const hidl_vec& sessionId, int64_t expiryTimeInMS) { if (mListener != nullptr) { mListener->sendExpirationUpdate(sessionId, expiryTimeInMS); } return Void(); } Return DrmPlugin::sendKeysChange(const hidl_vec& sessionId, const hidl_vec& 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 const *sessionId, Vector 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 emptyVector; mListener->sendEvent(eventType, toHidlVec(sessionId == NULL ? emptyVector: *sessionId), toHidlVec(data == NULL ? emptyVector: *data)); } } void DrmPlugin::sendExpirationUpdate(Vector const *sessionId, int64_t expiryTimeInMS) { mListener->sendExpirationUpdate(toHidlVec(*sessionId), expiryTimeInMS); } void DrmPlugin::sendKeysChange(Vector const *sessionId, Vector const *legacyKeyStatusList, bool hasNewUsableKey) { Vector 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