From 1849570240443d1f75775c205fa658f7070849c6 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Fri, 10 Apr 2015 04:10:59 -0700 Subject: Add a method to associate MediaDrm session with MediaCrypto Previously, to associate a MediaDrm session with MediaCrypto, the MediaDrm sessionId was passed as initData to the MediaCrypto constructor. This is not ideal for two reasons: it's pretty obscure and you can't change the association without tearing down the MediaCodec/MediaCrypto and starting all over. Use cases like key rotation require being able to update the MediaDrm session post-construction. This CL addresses both of these issues. bug: 19570317 Change-Id: Ieb32d04d61742fc1dee2105dd904690d44c46c7b --- media/libmedia/ICrypto.cpp | 42 ++++++++++++++++++++++++++++++++++ media/libmediaplayerservice/Crypto.cpp | 10 ++++++++ media/libmediaplayerservice/Crypto.h | 2 ++ 3 files changed, 54 insertions(+) (limited to 'media') diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp index 23308c1..9246a7c 100644 --- a/media/libmedia/ICrypto.cpp +++ b/media/libmedia/ICrypto.cpp @@ -35,6 +35,7 @@ enum { REQUIRES_SECURE_COMPONENT, DECRYPT, NOTIFY_RESOLUTION, + SET_MEDIADRM_SESSION, }; struct BpCrypto : public BpInterface { @@ -161,7 +162,28 @@ struct BpCrypto : public BpInterface { remote()->transact(NOTIFY_RESOLUTION, data, &reply); } + virtual status_t setMediaDrmSession(const Vector &sessionId) { + Parcel data, reply; + data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); + + writeVector(data, sessionId); + remote()->transact(SET_MEDIADRM_SESSION, data, &reply); + + return reply.readInt32(); + } + private: + void readVector(Parcel &reply, Vector &vector) const { + uint32_t size = reply.readInt32(); + vector.insertAt((size_t)0, size); + reply.read(vector.editArray(), size); + } + + void writeVector(Parcel &data, Vector const &vector) const { + data.writeInt32(vector.size()); + data.write(vector.array(), vector.size()); + } + DISALLOW_EVIL_CONSTRUCTORS(BpCrypto); }; @@ -169,6 +191,17 @@ IMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto"); //////////////////////////////////////////////////////////////////////////////// +void BnCrypto::readVector(const Parcel &data, Vector &vector) const { + uint32_t size = data.readInt32(); + vector.insertAt((size_t)0, size); + data.read(vector.editArray(), size); +} + +void BnCrypto::writeVector(Parcel *reply, Vector const &vector) const { + reply->writeInt32(vector.size()); + reply->write(vector.array(), vector.size()); +} + status_t BnCrypto::onTransact( uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { switch (code) { @@ -317,6 +350,15 @@ status_t BnCrypto::onTransact( return OK; } + case SET_MEDIADRM_SESSION: + { + CHECK_INTERFACE(IDrm, data, reply); + Vector sessionId; + readVector(data, sessionId); + reply->writeInt32(setMediaDrmSession(sessionId)); + return OK; + } + default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp index e768772..f639193 100644 --- a/media/libmediaplayerservice/Crypto.cpp +++ b/media/libmediaplayerservice/Crypto.cpp @@ -268,4 +268,14 @@ void Crypto::notifyResolution(uint32_t width, uint32_t height) { } } +status_t Crypto::setMediaDrmSession(const Vector &sessionId) { + Mutex::Autolock autoLock(mLock); + + status_t result = NO_INIT; + if (mInitCheck == OK && mPlugin != NULL) { + result = mPlugin->setMediaDrmSession(sessionId); + } + return result; +} + } // namespace android diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h index d5f3c50..99ea95d 100644 --- a/media/libmediaplayerservice/Crypto.h +++ b/media/libmediaplayerservice/Crypto.h @@ -47,6 +47,8 @@ struct Crypto : public BnCrypto { virtual void notifyResolution(uint32_t width, uint32_t height); + virtual status_t setMediaDrmSession(const Vector &sessionId); + virtual ssize_t decrypt( bool secure, const uint8_t key[16], -- cgit v1.1