199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten/* 265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Copyright (C) 2012 The Android Open Source Project 365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * you may not use this file except in compliance with the License. 665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * You may obtain a copy of the License at 765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * 1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Unless required by applicable law or agreed to in writing, software 1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * See the License for the specific language governing permissions and 1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * limitations under the License. 1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian */ 1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0 1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "IHDCP" 1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h> 2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/Parcel.h> 2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/IHDCP.h> 2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/MediaErrors.h> 2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/foundation/ADebug.h> 254ff14bae91075eb274eb1c2975982358946e7e63John Grossman 264ff14bae91075eb274eb1c2975982358946e7e63John Grossmannamespace android { 2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianenum { 2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian OBSERVER_NOTIFY = IBinder::FIRST_CALL_TRANSACTION, 3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian HDCP_SET_OBSERVER, 31335787fe43596f38ea2fa50b24c54d0823a3fb1dGlenn Kasten HDCP_INIT_ASYNC, 324ff14bae91075eb274eb1c2975982358946e7e63John Grossman HDCP_SHUTDOWN_ASYNC, 3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian HDCP_ENCRYPT, 3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; 3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstruct BpHDCPObserver : public BpInterface<IHDCPObserver> { 3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian BpHDCPObserver(const sp<IBinder> &impl) 38799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin : BpInterface<IHDCPObserver>(impl) { 3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 415462fc9a38fa8c9dff434cd53fa5fb1782ae3042Mathias Agopian virtual void notify( 425462fc9a38fa8c9dff434cd53fa5fb1782ae3042Mathias Agopian int msg, int ext1, int ext2, const Parcel *obj) { 435462fc9a38fa8c9dff434cd53fa5fb1782ae3042Mathias Agopian Parcel data, reply; 4464760240f931714858a59c1579f07264d7182ba2Dima Zavin data.writeInterfaceToken(IHDCPObserver::getInterfaceDescriptor()); 457394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin data.writeInt32(msg); 46a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent data.writeInt32(ext1); 4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data.writeInt32(ext2); 4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (obj && obj->dataSize() > 0) { 4958912562617941964939a4182cda71eaeb153d4bGlenn Kasten data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize()); 5058912562617941964939a4182cda71eaeb153d4bGlenn Kasten } 5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian remote()->transact(OBSERVER_NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); 52feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent } 53feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}; 5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianIMPLEMENT_META_INTERFACE(HDCPObserver, "android.hardware.IHDCPObserver"); 5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstruct BpHDCP : public BpInterface<IHDCP> { 5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian BpHDCP(const sp<IBinder> &impl) 5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian : BpInterface<IHDCP>(impl) { 6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 6158912562617941964939a4182cda71eaeb153d4bGlenn Kasten 6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian virtual status_t setObserver(const sp<IHDCPObserver> &observer) { 6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Parcel data, reply; 6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); 6553d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten data.writeStrongBinder(observer->asBinder()); 6653d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten remote()->transact(HDCP_SET_OBSERVER, data, &reply); 6753d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten return reply.readInt32(); 6853d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten } 6953d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten 7053d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten virtual status_t initAsync(const char *host, unsigned port) { 7153d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten Parcel data, reply; 7253d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); 7353d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten data.writeCString(host); 744ff14bae91075eb274eb1c2975982358946e7e63John Grossman data.writeInt32(port); 7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian remote()->transact(HDCP_INIT_ASYNC, data, &reply); 765462fc9a38fa8c9dff434cd53fa5fb1782ae3042Mathias Agopian return reply.readInt32(); 775462fc9a38fa8c9dff434cd53fa5fb1782ae3042Mathias Agopian } 785462fc9a38fa8c9dff434cd53fa5fb1782ae3042Mathias Agopian 7965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian virtual status_t shutdownAsync() { 801998661fdb6b0b5ae103e047e3d653c5da1b99e3Glenn Kasten Parcel data, reply; 8165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); 8254c3b66444ebfb9f2265ee70ac3b76ccefa0506aGlenn Kasten remote()->transact(HDCP_SHUTDOWN_ASYNC, data, &reply); 8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return reply.readInt32(); 8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 862f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten virtual status_t encrypt( 8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const void *inData, size_t size, uint32_t streamCTR, 8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint64_t *outInputCTR, void *outData) { 89fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten Parcel data, reply; 9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); 9158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten data.writeInt32(size); 920d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi data.write(inData, size); 9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data.writeInt32(streamCTR); 94a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten remote()->transact(HDCP_ENCRYPT, data, &reply); 9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten status_t err = reply.readInt32(); 973acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten 9865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (err != OK) { 9965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *outInputCTR = 0; 10065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1012f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten return err; 1022f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten } 1032f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten 1042f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten *outInputCTR = reply.readInt64(); 1052f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten reply.read(outData, size); 1062f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten 1072f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten return err; 108a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten } 1092f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten}; 1102f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten 1112f732eb768004c6362fae8a02c60b69c9400b032Glenn KastenIMPLEMENT_META_INTERFACE(HDCP, "android.hardware.IHDCP"); 11272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten 11372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t BnHDCPObserver::onTransact( 11472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 11572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten switch (code) { 11672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten case OBSERVER_NOTIFY: 11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CHECK_INTERFACE(IHDCPObserver, data, reply); 11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int msg = data.readInt32(); 12165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int ext1 = data.readInt32(); 1224ff14bae91075eb274eb1c2975982358946e7e63John Grossman int ext2 = data.readInt32(); 12365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Parcel obj; 12572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten if (data.dataAvail() > 0) { 12672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten obj.appendFrom( 127fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten const_cast<Parcel *>(&data), 12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian data.dataPosition(), 12972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten data.dataAvail()); 13072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten } 131fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten 13265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian notify(msg, ext1, ext2, &obj); 133f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kasten 13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return OK; 13565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 13765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 13872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten return BBinder::onTransact(code, data, reply, flags); 13972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten } 14065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 14165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 14265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t BnHDCP::onTransact( 143f587ba5b991c7cd91e4df093d0d796bd419e5d67Glenn Kasten uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 14465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (code) { 145a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent case HDCP_SET_OBSERVER: 146a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent { 147a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent CHECK_INTERFACE(IHDCP, data, reply); 148a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent 149a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent sp<IHDCPObserver> observer = 150a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent interface_cast<IHDCPObserver>(data.readStrongBinder()); 1510ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent 15265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian reply->writeInt32(setObserver(observer)); 15372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten return OK; 15472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten } 15565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 15672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten case HDCP_INIT_ASYNC: 15765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 15872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten CHECK_INTERFACE(IHDCP, data, reply); 15965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 16072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten const char *host = data.readCString(); 16165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian unsigned port = data.readInt32(); 162a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent 163a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent reply->writeInt32(initAsync(host, port)); 164a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent return OK; 165a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent } 166a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent 16765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case HDCP_SHUTDOWN_ASYNC: 16872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten { 16965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CHECK_INTERFACE(IHDCP, data, reply); 17072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten 17165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian reply->writeInt32(shutdownAsync()); 17265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return OK; 17365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 17472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten 17572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten case HDCP_ENCRYPT: 17665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian { 1772f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten size_t size = data.readInt32(); 1782f732eb768004c6362fae8a02c60b69c9400b032Glenn Kasten 17965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian void *inData = malloc(2 * size); 18065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian void *outData = (uint8_t *)inData + size; 1813a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen 1823a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen data.read(inData, size); 1833a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen 1843a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen uint32_t streamCTR = data.readInt32(); 185f587ba5b991c7cd91e4df093d0d796bd419e5d67Glenn Kasten uint64_t inputCTR; 18665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t err = encrypt(inData, size, streamCTR, &inputCTR, outData); 187f587ba5b991c7cd91e4df093d0d796bd419e5d67Glenn Kasten 18865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian reply->writeInt32(err); 1895e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten 190f587ba5b991c7cd91e4df093d0d796bd419e5d67Glenn Kasten if (err == OK) { 19165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian reply->writeInt64(inputCTR); 19265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian reply->write(outData, size); 19365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 19465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 19565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian free(inData); 19672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten inData = outData = NULL; 19765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 19865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return OK; 19965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 20065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 20272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten return BBinder::onTransact(code, data, reply, flags); 20372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten } 20465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 205a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent 206a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent} // namespace android 20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian