/* * Copyright (C) 2018 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. */ #ifndef CLEARKEY_DRM_PLUGIN_H_ #define CLEARKEY_DRM_PLUGIN_H_ #include <android/hardware/drm/1.1/IDrmPlugin.h> #include <stdio.h> #include <map> #include "SessionLibrary.h" #include "Utils.h" namespace android { namespace hardware { namespace drm { namespace V1_1 { namespace clearkey { using ::android::hardware::drm::V1_0::EventType; using ::android::hardware::drm::V1_0::IDrmPluginListener; using ::android::hardware::drm::V1_0::KeyStatus; using ::android::hardware::drm::V1_0::KeyType; using ::android::hardware::drm::V1_0::KeyValue; using ::android::hardware::drm::V1_0::SecureStop; using ::android::hardware::drm::V1_0::SecureStopId; using ::android::hardware::drm::V1_0::SessionId; using ::android::hardware::drm::V1_0::Status; using ::android::hardware::drm::V1_1::DrmMetricGroup; using ::android::hardware::drm::V1_1::IDrmPlugin; using ::android::hardware::drm::V1_1::KeyRequestType; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; struct DrmPlugin : public IDrmPlugin { explicit DrmPlugin(SessionLibrary* sessionLibrary); virtual ~DrmPlugin() {} Return<void> openSession(openSession_cb _hidl_cb) override; Return<void> openSession_1_1(SecurityLevel securityLevel, openSession_cb _hidl_cb) override; Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override; Return<void> 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) override; Return<void> getKeyRequest_1_1( const hidl_vec<uint8_t>& scope, const hidl_vec<uint8_t>& initData, const hidl_string& mimeType, KeyType keyType, const hidl_vec<KeyValue>& optionalParameters, getKeyRequest_1_1_cb _hidl_cb) override; Return<void> provideKeyResponse( const hidl_vec<uint8_t>& scope, const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb) override; Return<Status> removeKeys(const hidl_vec<uint8_t>& sessionId) { if (sessionId.size() == 0) { return Status::BAD_VALUE; } return Status::ERROR_DRM_CANNOT_HANDLE; } Return<Status> restoreKeys( const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& keySetId) { if (sessionId.size() == 0 || keySetId.size() == 0) { return Status::BAD_VALUE; } return Status::ERROR_DRM_CANNOT_HANDLE; } Return<void> queryKeyStatus( const hidl_vec<uint8_t>& sessionId, queryKeyStatus_cb _hidl_cb) override; Return<void> getProvisionRequest( const hidl_string& certificateType, const hidl_string& certificateAuthority, getProvisionRequest_cb _hidl_cb) { UNUSED(certificateType); UNUSED(certificateAuthority); hidl_string defaultUrl; _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(), defaultUrl); return Void(); } Return<void> provideProvisionResponse( const hidl_vec<uint8_t>& response, provideProvisionResponse_cb _hidl_cb) { if (response.size() == 0) { _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>(), hidl_vec<uint8_t>()); return Void(); } _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(), hidl_vec<uint8_t>()); return Void(); } Return<void> getHdcpLevels(getHdcpLevels_cb _hidl_cb) { HdcpLevel connectedLevel = HdcpLevel::HDCP_NONE; HdcpLevel maxLevel = HdcpLevel::HDCP_NO_OUTPUT; _hidl_cb(Status::OK, connectedLevel, maxLevel); return Void(); } Return<void> getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) override; Return<void> getSecurityLevel(const hidl_vec<uint8_t>& sessionId, getSecurityLevel_cb _hidl_cb) override; Return<void> getMetrics(getMetrics_cb _hidl_cb) override; Return<void> getPropertyString( const hidl_string& name, getPropertyString_cb _hidl_cb) override; Return<void> getPropertyByteArray( const hidl_string& name, getPropertyByteArray_cb _hidl_cb) override; Return<Status> setPropertyString( const hidl_string& name, const hidl_string& value) override; Return<Status> setPropertyByteArray( const hidl_string& name, const hidl_vec<uint8_t>& value) override; Return<Status> setCipherAlgorithm( const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) { if (sessionId.size() == 0 || algorithm.size() == 0) { return Status::BAD_VALUE; } return Status::ERROR_DRM_CANNOT_HANDLE; } Return<Status> setMacAlgorithm( const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) { if (sessionId.size() == 0 || algorithm.size() == 0) { return Status::BAD_VALUE; } return Status::ERROR_DRM_CANNOT_HANDLE; } Return<void> 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) { if (sessionId.size() == 0 || keyId.size() == 0 || input.size() == 0 || iv.size() == 0) { _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>()); return Void(); } _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>()); return Void(); } Return<void> 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) { if (sessionId.size() == 0 || keyId.size() == 0 || input.size() == 0 || iv.size() == 0) { _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>()); return Void(); } _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>()); return Void(); } Return<void> sign( const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message, sign_cb _hidl_cb) { if (sessionId.size() == 0 || keyId.size() == 0 || message.size() == 0) { _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>()); return Void(); } _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>()); return Void(); } Return<void> 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) { if (sessionId.size() == 0 || keyId.size() == 0 || message.size() == 0 || signature.size() == 0) { _hidl_cb(Status::BAD_VALUE, false); return Void(); } _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, false); return Void(); } Return<void> 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) { if (sessionId.size() == 0 || algorithm.size() == 0 || message.size() == 0 || wrappedKey.size() == 0) { _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>()); return Void(); } _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>()); return Void(); } Return<void> setListener(const sp<IDrmPluginListener>& listener) { mListener = listener; return Void(); }; Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) { if (mListener != NULL) { mListener->sendEvent(eventType, sessionId, data); } else { ALOGE("Null event listener, event not sent"); } return Void(); } Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) { if (mListener != NULL) { mListener->sendExpirationUpdate(sessionId, expiryTimeInMS); } else { ALOGE("Null event listener, event not sent"); } return Void(); } Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId, const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) { if (mListener != NULL) { mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey); } else { ALOGE("Null event listener, event not sent"); } return Void(); } Return<void> getSecureStops(getSecureStops_cb _hidl_cb); Return<void> getSecureStop(const hidl_vec<uint8_t>& secureStopId, getSecureStop_cb _hidl_cb); Return<Status> releaseSecureStop(const hidl_vec<uint8_t>& ssRelease); Return<Status> releaseAllSecureStops(); Return<void> getSecureStopIds(getSecureStopIds_cb _hidl_cb); Return<Status> releaseSecureStops(const SecureStopRelease& ssRelease); Return<Status> removeSecureStop(const hidl_vec<uint8_t>& secureStopId); Return<Status> removeAllSecureStops(); private: void initProperties(); void installSecureStop(const hidl_vec<uint8_t>& sessionId); void setPlayPolicy(); Return<Status> setSecurityLevel(const hidl_vec<uint8_t>& sessionId, SecurityLevel level); Status getKeyRequestCommon(const hidl_vec<uint8_t>& scope, const hidl_vec<uint8_t>& initData, const hidl_string& mimeType, KeyType keyType, const hidl_vec<KeyValue>& optionalParameters, std::vector<uint8_t> *request, KeyRequestType *getKeyRequestType, std::string *defaultUrl); struct ClearkeySecureStop { std::vector<uint8_t> id; std::vector<uint8_t> data; }; std::map<std::vector<uint8_t>, ClearkeySecureStop> mSecureStops; std::vector<KeyValue> mPlayPolicy; std::map<std::string, std::string> mStringProperties; std::map<std::string, std::vector<uint8_t> > mByteArrayProperties; std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel; sp<IDrmPluginListener> mListener; SessionLibrary *mSessionLibrary; int64_t mOpenSessionOkCount; int64_t mCloseSessionOkCount; int64_t mCloseSessionNotOpenedCount; uint32_t mNextSecureStopId; CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin); }; } // namespace clearkey } // namespace V1_1 } // namespace drm } // namespace hardware } // namespace android #endif // CLEARKEY_DRM_PLUGIN_H_