diff --git a/proprietary/drmwvmplugin/include/WVMDrmPlugin.h b/proprietary/drmwvmplugin/include/WVMDrmPlugin.h index 6e09a7f5..d38841a7 100644 --- a/proprietary/drmwvmplugin/include/WVMDrmPlugin.h +++ b/proprietary/drmwvmplugin/include/WVMDrmPlugin.h @@ -80,10 +80,22 @@ protected: DrmSupportInfo* onGetSupportInfo(int uniqueId); status_t onOpenDecryptSession(int uniqueId, DecryptHandle *decryptHandle, - int fd, off64_t offset, off64_t length); + int fd, off64_t offset, off64_t length) { + return DRM_ERROR_CANNOT_HANDLE; + } status_t onOpenDecryptSession(int uniqueId, DecryptHandle *decryptHandle, - const char *uri); + int fd, off64_t offset, off64_t length, + const char* mime); + + status_t onOpenDecryptSession(int uniqueId, DecryptHandle *decryptHandle, + const char* uri) { + return DRM_ERROR_CANNOT_HANDLE; + } + + status_t onOpenDecryptSession(int uniqueId, DecryptHandle *decryptHandle, + const char* uri, + const char* mime); status_t onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle); @@ -125,6 +137,7 @@ protected: }; private: + bool isSupportedMimeType(const char* mime); static bool SendEvent(WVDRMPluginAPI::EventType code, WVDRMPluginAPI::EventDestination dest, const std::string &path); diff --git a/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp b/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp index 09c146e6..8bf938f8 100644 --- a/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp +++ b/proprietary/drmwvmplugin/src/WVMDrmPlugin.cpp @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_NDEBUG 0 + +//#define LOG_NDEBUG 0 #define LOG_TAG "WVMDrmPlugIn" #include #include @@ -704,77 +705,68 @@ status_t WVMDrmPlugin::onRemoveAllRights(int uniqueId) { * @param[in] fd File descriptor of the protected content to be decrypted * @param[in] offset Start position of the content * @param[in] length The length of the protected content + * @param[in] mime Mime type of the protected content. * @return * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success */ status_t WVMDrmPlugin::onOpenDecryptSession( - int uniqueId, DecryptHandle *decryptHandle, int fd, off64_t offset, off64_t length) + int uniqueId, DecryptHandle *decryptHandle, + int fd, off64_t offset, off64_t length, const char* mime) { - status_t result = DRM_ERROR_CANNOT_HANDLE; + ALOGV("onOpenDecryptSession: id=%d,fd=%d", uniqueId, fd); - //ALOGD("onOpenDecryptSession: fd=%d, offset=%lld, length=%lld", fd, offset, length); - - char buffer[64 * 1024]; - int dupfd = dup(fd); - if (dupfd == -1) - return result; - - FILE *f = fdopen(dupfd, "rb"); - if (f) { - fseek(f, 0, SEEK_SET); - if (fread(buffer, 1, sizeof(buffer), f) != sizeof(buffer)) { - fclose(f); - return DRM_ERROR_CANNOT_HANDLE; - } - fclose(f); - } else { - close(dupfd); - return result; + if (!isSupportedMimeType(mime)) { + return DRM_ERROR_CANNOT_HANDLE; } - if (WV_IsWidevineMedia(buffer, sizeof(buffer))) { - //ALOGD("WVMDrmPlugin::onOpenDecryptSession - WV_IsWidevineMedia: true"); - decryptHandle->mimeType = String8("video/wvm"); - decryptHandle->decryptApiType = DecryptApiType::WV_BASED; - decryptHandle->status = DRM_NO_ERROR; - decryptHandle->decryptInfo = NULL; + // For efficiency, we rely on the WVMExtractor's sniff result instead of + // setting mimeType and decryptApiType here for the DRMExtractor's sniff. + // WVMExtractor's sniff uses the cached data source for the sniff. + decryptHandle->decryptInfo = NULL; + decryptHandle->status = DRM_NO_ERROR; - mDrmPluginImpl->OpenSession(NULL); - result = DRM_NO_ERROR; - } else { - //ALOGD("WVMDrmPlugin::onOpenDecryptSession - not Widevine media"); + if (mDrmPluginImpl->OpenSession(NULL)) { + return DRM_NO_ERROR; } - - return result; + return DRM_ERROR_CANNOT_HANDLE; } +bool WVMDrmPlugin::isSupportedMimeType(const char* mime) { + ALOGV("isSupportedMimeType: mime = %s", mime? mime: "NULL"); + return strcasecmp("video/wvm", mime) == 0; +} /** * Open the decrypt session to decrypt the given protected content * * @param[in] uniqueId Unique identifier for a session * @param[in] decryptHandle Handle for the current decryption session * @param[in] uri Path of the protected content to be decrypted + * @param[in] mime Mime type of the protected content * @return * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success */ status_t WVMDrmPlugin::onOpenDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, const char* uri) + int uniqueId, DecryptHandle* decryptHandle, + const char* uri, const char* mime) { + ALOGV("onOpenDecryptSession: id=%d,uri=%s",uniqueId,uri); + if (!isSupportedMimeType(mime)) { + return DRM_ERROR_CANNOT_HANDLE; + } + + // For efficiency, we rely on the WVMExtractor's sniff result instead of + // setting mimeType and decryptApiType here for the DRMExtractor's sniff. + // WVMExtractor's sniff uses the cached data source for the sniff. status_t result = DRM_ERROR_CANNOT_HANDLE; if (!uri) return result; - if (mDrmPluginImpl->IsSupportedMediaType(uri)) { - //ALOGD("WVMDrmPlugin::onOpenDecryptSession(uri) : %d - match", uniqueId); - decryptHandle->mimeType = String8("video/wvm"); - decryptHandle->decryptApiType = DecryptApiType::WV_BASED; - decryptHandle->status = DRM_NO_ERROR; - decryptHandle->decryptInfo = NULL; + decryptHandle->decryptInfo = NULL; + decryptHandle->status = DRM_NO_ERROR; - if (mDrmPluginImpl->OpenSession(uri)) { - result = DRM_NO_ERROR; - } + if (mDrmPluginImpl->OpenSession(uri)) { + result = DRM_NO_ERROR; } else { //ALOGD("WVMDrmPlugin::onOpenDecryptSession(uri) - not Widevine media"); } diff --git a/proprietary/wvm/WVMExtractorImpl.cpp b/proprietary/wvm/WVMExtractorImpl.cpp index 1af10fa9..02b62f23 100644 --- a/proprietary/wvm/WVMExtractorImpl.cpp +++ b/proprietary/wvm/WVMExtractorImpl.cpp @@ -80,6 +80,27 @@ WVMLoadableExtractor *GetInstance(sp dataSource) { return new WVMExtractorImpl(dataSource); } +bool IsWidevineMedia(const sp& dataSource) { + char buffer[64 * 1024]; + + String8 uri = dataSource->getUri(); + if (uri.getPathExtension() == ".m3u8" || uri.find(".m3u8?") != -1) { + // can't sniff live streams - check for .m3u8 file extension + return true; + } + + ssize_t bytesRead = dataSource->readAt(0, buffer, sizeof(buffer)); + if (bytesRead < (ssize_t)sizeof(buffer)) { + ALOGW("IsWidevineMedia - insufficient data: %d", (int)bytesRead); + return false; + } + + bool result = WV_IsWidevineMedia(buffer, sizeof(buffer)); + return result; +} + + + WVMExtractorImpl::WVMExtractorImpl(sp dataSource) : mFileMetaData(new MetaData()), mDataSource(dataSource), diff --git a/proprietary/wvm/include/WVMExtractorImpl.h b/proprietary/wvm/include/WVMExtractorImpl.h index 63e016c7..f6e03603 100644 --- a/proprietary/wvm/include/WVMExtractorImpl.h +++ b/proprietary/wvm/include/WVMExtractorImpl.h @@ -31,7 +31,7 @@ namespace android { WVMLoadableExtractor *GetInstance(sp dataSource); - +bool IsWidevineMedia(const sp& dataSource); class WVMMediaSource; class WVMFileSource;