diff --git a/proprietary/drmwvmplugin/include/WVDRMPluginAPI.h b/proprietary/drmwvmplugin/include/WVDRMPluginAPI.h index 88c70493..d9cb47b4 100644 --- a/proprietary/drmwvmplugin/include/WVDRMPluginAPI.h +++ b/proprietary/drmwvmplugin/include/WVDRMPluginAPI.h @@ -1,17 +1,7 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright 2011 Widevine Technologies, Inc., All Rights Reserved * - * 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. + * Declarations for Widevine DRM Plugin API */ #ifndef __WVMDRMPLUGIN_API_H__ @@ -38,6 +28,12 @@ class WVDRMPluginAPI { PLAYBACK_INVALID }; + static const int PlaybackMode_Default = 0; + static const int PlaybackMode_Streaming = 1; + static const int PlaybackMode_Offline = 2; + static const int PlaybackMode_Any = PlaybackMode_Streaming | + PlaybackMode_Offline; + static WVDRMPluginAPI *create(); static void destroy(WVDRMPluginAPI *plugin); @@ -48,19 +44,35 @@ class WVDRMPluginAPI { virtual bool RegisterDrmInfo(std::string &portal, std::string &dsPath) = 0; virtual bool UnregisterDrmInfo(std::string &portal, std::string &dsPath) = 0; virtual bool AcquireDrmInfo(std::string &assetPath, WVCredentials &credentials, - std::string &dsPath, - const std::string &assetIdStr, const std::string &systemIdStr, + std::string &dsPath, const std::string &assetIdStr, + const std::string &systemIdStr, const std::string &keyIdStr, - uint32_t *assetId, uint32_t *systemId, uint32_t *keyId) = 0; - virtual bool ProcessDrmInfo(std::string &assetPath) = 0; + uint32_t *assetId, uint32_t *systemId, + uint32_t *keyId) = 0; + + virtual bool ProcessDrmInfo(std::string &assetPath, int playbackMode) = 0; virtual int CheckRightsStatus(std::string &path) = 0; - virtual bool GetConstraints(std::string &path, uint32_t *timeSincePlayback, uint32_t *timeRemaining, uint32_t *licenseDuration) = 0; + virtual bool GetConstraints(std::string &path, uint32_t *timeSincePlayback, + uint32_t *timeRemaining, + uint32_t *licenseDuration, std::string &lastError, + bool &allowOffline, bool &allowStreaming, + bool &denyHD) = 0; virtual bool SetPlaybackStatus(int playbackStatus, off64_t position) = 0; virtual bool RemoveRights(std::string &path) = 0; virtual bool RemoveAllRights() = 0; virtual bool Prepare(char *data, int len) = 0; virtual bool Operate(char *in, char *out, int len, char *iv) = 0; + enum EventType { + EventType_AcquireDrmInfoFailed, + EventType_ProcessDrmInfoFailed, + EventType_RightsInstalled, + EventType_RightsRemoved + }; + + typedef void (*EventHandler)(EventType type, const std::string &path); + virtual void SetEventHandler(EventHandler handler) = 0; + protected: // use create factory method, don't construct directly WVDRMPluginAPI() {} diff --git a/proprietary/drmwvmplugin/include/WVMDrmPlugin.h b/proprietary/drmwvmplugin/include/WVMDrmPlugin.h index efce025d..93c06c02 100644 --- a/proprietary/drmwvmplugin/include/WVMDrmPlugin.h +++ b/proprietary/drmwvmplugin/include/WVMDrmPlugin.h @@ -101,7 +101,10 @@ protected: void* buffer, ssize_t numBytes, off64_t offset); private: - const IDrmEngine::OnInfoListener *mOnInfoListener; + static void SendEvent(WVDRMPluginAPI::EventType code, const std::string &path); + static IDrmEngine::OnInfoListener *sOnInfoListener; + static int sUniqueId; + WVDRMPluginAPI *mDrmPluginImpl; }; diff --git a/proprietary/drmwvmplugin/lib/libwvdrm.so b/proprietary/drmwvmplugin/lib/libwvdrm.so index a0a9ef7e..33efda67 100644 Binary files a/proprietary/drmwvmplugin/lib/libwvdrm.so and b/proprietary/drmwvmplugin/lib/libwvdrm.so differ diff --git a/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp b/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp index 67bd38d2..4a5ee275 100644 --- a/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp +++ b/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -45,11 +46,15 @@ extern "C" void destroy(IDrmEngine* pPlugIn) { delete pPlugIn; } +// Needed for event callout from implementation object +IDrmEngine::OnInfoListener *WVMDrmPlugin::sOnInfoListener = NULL; +int WVMDrmPlugin::sUniqueId; + WVMDrmPlugin::WVMDrmPlugin() : DrmEngineBase(), - mOnInfoListener(NULL), mDrmPluginImpl(WVDRMPluginAPI::create()) { + mDrmPluginImpl->SetEventHandler(&SendEvent); } WVMDrmPlugin::~WVMDrmPlugin() { @@ -96,10 +101,38 @@ status_t WVMDrmPlugin::onTerminate(int uniqueId) { status_t WVMDrmPlugin::onSetOnInfoListener( int uniqueId, const IDrmEngine::OnInfoListener* infoListener) { //LOGD("WVMDrmPlugin::onSetOnInfoListener : %d", uniqueId); - mOnInfoListener = infoListener; + sOnInfoListener = const_cast(infoListener); + sUniqueId = uniqueId; return DRM_NO_ERROR; } +void WVMDrmPlugin::SendEvent(WVDRMPluginAPI::EventType type, const std::string &path) +{ + int code = -1; + + switch(type) { + EventType_AcquireFailed: + code = DrmInfoEvent::TYPE_ACQUIRE_DRM_INFO_FAILED; + break; + EventType_ProcessDrmInfoFailed: + code = DrmInfoEvent::TYPE_PROCESS_DRM_INFO_FAILED; + break; + EventType_RightsInstalled: + code = DrmInfoEvent::TYPE_RIGHTS_INSTALLED; + break; + EventType_RightsRemoved: + code = DrmInfoEvent::TYPE_RIGHTS_REMOVED; + break; + default: + break; + } + + if (sOnInfoListener) { + DrmInfoEvent event(sUniqueId, code, String8(path.c_str())); + sOnInfoListener->onInfo(event); + } +} + /** * Retrieves necessary information for registration, unregistration or rights * acquisition information. @@ -141,6 +174,7 @@ DrmInfo* WVMDrmPlugin::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmI string systemIdStr = drmInfoRequest->get(String8("WVSystemIDKey")).string(); string assetIdStr = drmInfoRequest->get(String8("WVAssetIDKey")).string(); string keyIdStr = drmInfoRequest->get(String8("WVKeyIDKey")).string(); + string licenseTypeStr = drmInfoRequest->get(String8("WVLicenseTypeKey")).string(); uint32_t systemId, assetId, keyId; @@ -166,6 +200,7 @@ DrmInfo* WVMDrmPlugin::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmI drmInfo->put(String8("WVCAUserDataKey"), String8(credentials.userData.c_str())); drmInfo->put(String8("WVDeviceIDKey"), String8(credentials.deviceID.c_str())); drmInfo->put(String8("WVStreamIDKey"), String8(credentials.streamID.c_str())); + drmInfo->put(String8("WVLicenseTypeKey"), String8(licenseTypeStr.c_str())); char buffer[16]; sprintf(buffer, "%lu", (unsigned long)systemId); @@ -239,8 +274,9 @@ DrmInfoStatus* WVMDrmPlugin::onProcessDrmInfo(int uniqueId, const DrmInfo* drmIn if (NULL != drmInfo) { if (drmInfo->getInfoType() == DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO) { std::string assetPath = drmInfo->get(String8("WVAssetURIKey")).string(); + int playbackMode = atol(drmInfo->get(String8("WVLicenseTypeKey")).string()); - if (mDrmPluginImpl->ProcessDrmInfo(assetPath)) + if (mDrmPluginImpl->ProcessDrmInfo(assetPath, playbackMode)) status = DrmInfoStatus::STATUS_OK; } else if ((drmInfo->getInfoType() == DrmInfoRequest::TYPE_REGISTRATION_INFO) || (drmInfo->getInfoType() == DrmInfoRequest::TYPE_UNREGISTRATION_INFO)) { @@ -288,9 +324,15 @@ DrmConstraints* WVMDrmPlugin::onGetConstraints(int uniqueId, const String8* path uint32_t licenseDuration = 0; uint32_t timeSincePlayback = 0; uint32_t timeRemaining = 0; + std::string lastError; + bool allowOffline; + bool allowStreaming; + bool denyHD; std::string assetPath(path->string()); - if (!mDrmPluginImpl->GetConstraints(assetPath, &timeSincePlayback, &timeRemaining, &licenseDuration)) + if (!mDrmPluginImpl->GetConstraints(assetPath, &timeSincePlayback, &timeRemaining, + &licenseDuration, lastError, allowOffline, + allowStreaming, denyHD)) return NULL; DrmConstraints* drmConstraints = new DrmConstraints(); @@ -308,6 +350,16 @@ DrmConstraints* WVMDrmPlugin::onGetConstraints(int uniqueId, const String8* path sprintf(charValue, "%lu", (unsigned long)licenseDuration); drmConstraints->put(&(DrmConstraints::LICENSE_AVAILABLE_TIME), charValue); + String8 key = String8("WVLicenseTypeKey"); + sprintf(charValue, "%u", (allowStreaming ? 1 : 0) | (allowOffline ? 2 : 0)); + drmConstraints->put(&key, charValue); + + key = String8("WVLicensedResolutionKey"); + sprintf(charValue, "%u", (denyHD ? 1 : 2)); + drmConstraints->put(&key, charValue); + + key = String8("WVLastErrorKey"); + drmConstraints->put(&key, lastError.c_str()); return drmConstraints; } @@ -755,4 +807,3 @@ DrmConvertedStatus* WVMDrmPlugin::onCloseConvertSession(int uniqueId, int conver return NULL; } - diff --git a/proprietary/drmwvmplugin/test/TestPlugin.cpp b/proprietary/drmwvmplugin/test/TestPlugin.cpp index 19422573..f991bc23 100644 --- a/proprietary/drmwvmplugin/test/TestPlugin.cpp +++ b/proprietary/drmwvmplugin/test/TestPlugin.cpp @@ -35,15 +35,22 @@ public: void TestAsset(IDrmEngine *plugin, String8 &url); - void TestRemoveAllRights(IDrmEngine *plugin); - void TestAcquireRights(IDrmEngine *plugin, String8 &url); + void TestRegister(IDrmEngine *plugin); + void TestAcquireRights(IDrmEngine *plugin, String8 &url, int playbackMode); void TestCheckRightsNotAcquired(IDrmEngine *plugin, String8 &url); void TestCheckValidRights(IDrmEngine *plugin, String8 &url); - void TestGetConstraints(IDrmEngine *plugin, String8 &url); + void TestGetConstraints(IDrmEngine *plugin, String8 &url, int playbackMode); void TestRemoveRights(IDrmEngine *plugin, String8 &url); + void TestRemoveAllRights(IDrmEngine *plugin); // Tests void Run(); + +private: + static const int PlaybackMode_Default = 0; + static const int PlaybackMode_Streaming = 1; + static const int PlaybackMode_Offline = 2; + static const int PlaybackMode_Any = PlaybackMode_Streaming | PlaybackMode_Offline; }; void WVMDrmPluginTest::Run() @@ -101,9 +108,25 @@ void WVMDrmPluginTest::Run() exit(0); } -void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url) +void WVMDrmPluginTest::TestRegister(IDrmEngine *plugin) { - cout << "WVDrmPluginTest::TestAcquireRights url=" << url << endl; + cout << "WVDrmPluginTest::TestRegister" << endl; + + String8 mimeType("video/wvm"); + DrmInfoRequest registrationInfo(DrmInfoRequest::TYPE_REGISTRATION_INFO, mimeType); + registrationInfo.put(String8("WVPortalKey"), String8("YouTube")); + + DrmInfo *info = plugin->acquireDrmInfo(0, ®istrationInfo); + if (info == NULL) { + fprintf(stderr, "acquireDrmInfo failed!\n"); + exit(-1); + } + delete info; +} + +void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url, int playbackMode) +{ + cout << "WVDrmPluginTest::TestAcquireRights url=" << url << " mode=" << playbackMode << endl; String8 mimeType("video/wvm"); DrmInfoRequest rightsAcquisitionInfo(DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO, mimeType); @@ -111,6 +134,12 @@ void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url) rightsAcquisitionInfo.put(String8("WVAssetURIKey"), url); rightsAcquisitionInfo.put(String8("WVDeviceIDKey"), String8("device1234")); rightsAcquisitionInfo.put(String8("WVPortalKey"), String8("YouTube")); + if (playbackMode) { + char num[4]; + sprintf(num, "%d", playbackMode); + rightsAcquisitionInfo.put(String8("WVLicenseTypeKey"), String8(num)); + cout << "WVLicenseTypeKey = " << num << endl; + } DrmInfo *info = plugin->acquireDrmInfo(0, &rightsAcquisitionInfo); if (info == NULL) { @@ -158,7 +187,7 @@ void WVMDrmPluginTest::TestCheckValidRights(IDrmEngine *plugin, String8 &url) } } -void WVMDrmPluginTest::TestGetConstraints(IDrmEngine *plugin, String8 &url) +void WVMDrmPluginTest::TestGetConstraints(IDrmEngine *plugin, String8 &url, int playbackMode) { cout << "WVDrmPluginTest::TestGetConstraints url=" << url << endl; @@ -169,23 +198,45 @@ void WVMDrmPluginTest::TestGetConstraints(IDrmEngine *plugin, String8 &url) exit(-1); } - if (constraints->getCount() != 3) { + if (constraints->getCount() != 6) { fprintf(stderr, "getConstraints returned unexpected count!\n"); exit(-1); } if (constraints->get(DrmConstraints::LICENSE_START_TIME) == "") { - fprintf(stderr, "getConstraints returned unexpected count!\n"); + fprintf(stderr, "getConstraints missing start time!\n"); exit(-1); } if (constraints->get(DrmConstraints::LICENSE_AVAILABLE_TIME) == "") { - fprintf(stderr, "getConstraints returned unexpected count!\n"); + fprintf(stderr, "getConstraints missing available time!\n"); exit(-1); } if (constraints->get(DrmConstraints::LICENSE_EXPIRY_TIME) == "") { - fprintf(stderr, "getConstraints returned unexpected count!\n"); + fprintf(stderr, "getConstraints missing expiry time!\n"); + exit(-1); + } + + if (constraints->get(String8("WVLicenseTypeKey")) == "") { + fprintf(stderr, "getConstraints missing license type key!\n"); + exit(-1); + } + + if (constraints->get(String8("WVLicensedResolutionKey")) == "") { + fprintf(stderr, "getConstraints missing resolution key!\n"); + exit(-1); + } + + if (constraints->get(String8("WVLastErrorKey")) == "") { + fprintf(stderr, "getConstraints missing last error key!\n"); + exit(-1); + } + + String8 licenseTypeStr = constraints->get(String8("WVLicenseTypeKey")); + int licenseType = atol(licenseTypeStr.string()); + if (licenseType != playbackMode) { + fprintf(stderr, "license type mismatch, expected %d, found %d\n", playbackMode, licenseType); exit(-1); } @@ -218,13 +269,32 @@ void WVMDrmPluginTest::TestAsset(IDrmEngine *plugin, String8 &url) { cout << "WVDrmPluginTest::TestAsset url=" << url << endl; - TestAcquireRights(plugin, url); + TestRegister(plugin); + TestRemoveAllRights(plugin); + TestCheckRightsNotAcquired(plugin, url); + + TestAcquireRights(plugin, url, PlaybackMode_Default); TestCheckValidRights(plugin, url); - TestGetConstraints(plugin, url); + TestGetConstraints(plugin, url, PlaybackMode_Any); TestRemoveRights(plugin, url); TestCheckRightsNotAcquired(plugin, url); - TestAcquireRights(plugin, url); - TestRemoveAllRights(plugin); + + TestAcquireRights(plugin, url, PlaybackMode_Offline); + TestCheckValidRights(plugin, url); + TestGetConstraints(plugin, url, PlaybackMode_Offline); + TestRemoveRights(plugin, url); + TestCheckRightsNotAcquired(plugin, url); + + TestAcquireRights(plugin, url, PlaybackMode_Streaming); + TestCheckValidRights(plugin, url); + TestGetConstraints(plugin, url, PlaybackMode_Streaming); + TestRemoveRights(plugin, url); + TestCheckRightsNotAcquired(plugin, url); + + TestAcquireRights(plugin, url, PlaybackMode_Any); + TestCheckValidRights(plugin, url); + TestGetConstraints(plugin, url, PlaybackMode_Any); + TestRemoveRights(plugin, url); TestCheckRightsNotAcquired(plugin, url); } @@ -232,6 +302,7 @@ int main(int argc, char **argv) { // turn off some noisy printing in WVStreamControl setenv("WV_SILENT", "true", 1); + WVMDrmPluginTest test; test.Run(); } diff --git a/proprietary/streamcontrol/include/WVStreamControlAPI.h b/proprietary/streamcontrol/include/WVStreamControlAPI.h index 08effa43..48323f4d 100644 --- a/proprietary/streamcontrol/include/WVStreamControlAPI.h +++ b/proprietary/streamcontrol/include/WVStreamControlAPI.h @@ -1,17 +1,7 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright 2011 Widevine Technologies, Inc., All Rights Reserved * - * 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. + * Declarations for Widevine Adaptive Streaming API */ #ifndef __WV_STREAM_CONTROL_API_H__ diff --git a/proprietary/streamcontrol/lib/libWVStreamControlAPI.so b/proprietary/streamcontrol/lib/libWVStreamControlAPI.so index a3adbbc5..ba344319 100644 Binary files a/proprietary/streamcontrol/lib/libWVStreamControlAPI.so and b/proprietary/streamcontrol/lib/libWVStreamControlAPI.so differ diff --git a/proprietary/streamcontrol/lib/libwvocs.a b/proprietary/streamcontrol/lib/libwvocs.a index 58b2370c..447ebbc1 100644 Binary files a/proprietary/streamcontrol/lib/libwvocs.a and b/proprietary/streamcontrol/lib/libwvocs.a differ diff --git a/proprietary/streamcontrol/test/TestPlayer.cpp b/proprietary/streamcontrol/test/TestPlayer.cpp index 2d998f05..83f1bc17 100644 --- a/proprietary/streamcontrol/test/TestPlayer.cpp +++ b/proprietary/streamcontrol/test/TestPlayer.cpp @@ -315,7 +315,7 @@ int main( int argc, char *argv[] ) Terminate(); } - if (!sDrmPlugin->ProcessDrmInfo(url)) { + if (!sDrmPlugin->ProcessDrmInfo(url, WVDRMPluginAPI::PlaybackMode_Any)) { fprintf(stderr, "ERROR: ProcessDrmInfo failed\n"); Terminate(); }