11b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber/* 21b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * Copyright (C) 2012 The Android Open Source Project 31b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * 41b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 51b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * you may not use this file except in compliance with the License. 61b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * You may obtain a copy of the License at 71b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * 81b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 91b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * 101b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * Unless required by applicable law or agreed to in writing, software 111b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 121b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * See the License for the specific language governing permissions and 141b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * limitations under the License. 151b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber */ 161b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 171b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber//#define LOG_NDEBUG 0 181b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#define LOG_TAG "IHDCP" 191b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include <utils/Log.h> 201b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 211b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include <binder/Parcel.h> 221b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include <media/IHDCP.h> 231b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include <media/stagefright/MediaErrors.h> 241b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include <media/stagefright/foundation/ADebug.h> 251b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 261b19c9d120869c3182373a9b06a1ed98898df882Andreas Hubernamespace android { 271b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 281b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberenum { 291b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber OBSERVER_NOTIFY = IBinder::FIRST_CALL_TRANSACTION, 301b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber HDCP_SET_OBSERVER, 311b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber HDCP_INIT_ASYNC, 321b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber HDCP_SHUTDOWN_ASYNC, 331b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber HDCP_ENCRYPT, 341b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber}; 351b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 361b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberstruct BpHDCPObserver : public BpInterface<IHDCPObserver> { 371b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber BpHDCPObserver(const sp<IBinder> &impl) 381b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber : BpInterface<IHDCPObserver>(impl) { 391b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 401b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 411b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber virtual void notify( 421b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber int msg, int ext1, int ext2, const Parcel *obj) { 431b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber Parcel data, reply; 441b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInterfaceToken(IHDCPObserver::getInterfaceDescriptor()); 451b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInt32(msg); 461b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInt32(ext1); 471b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInt32(ext2); 481b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (obj && obj->dataSize() > 0) { 491b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize()); 501b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 511b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber remote()->transact(OBSERVER_NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); 521b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 531b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber}; 541b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 551b19c9d120869c3182373a9b06a1ed98898df882Andreas HuberIMPLEMENT_META_INTERFACE(HDCPObserver, "android.hardware.IHDCPObserver"); 561b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 571b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberstruct BpHDCP : public BpInterface<IHDCP> { 581b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber BpHDCP(const sp<IBinder> &impl) 591b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber : BpInterface<IHDCP>(impl) { 601b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 611b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 621b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber virtual status_t setObserver(const sp<IHDCPObserver> &observer) { 631b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber Parcel data, reply; 641b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); 651b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeStrongBinder(observer->asBinder()); 661b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber remote()->transact(HDCP_SET_OBSERVER, data, &reply); 671b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return reply.readInt32(); 681b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 691b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 701b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber virtual status_t initAsync(const char *host, unsigned port) { 711b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber Parcel data, reply; 721b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); 731b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeCString(host); 741b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInt32(port); 751b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber remote()->transact(HDCP_INIT_ASYNC, data, &reply); 761b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return reply.readInt32(); 771b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 781b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 791b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber virtual status_t shutdownAsync() { 801b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber Parcel data, reply; 811b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); 821b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber remote()->transact(HDCP_SHUTDOWN_ASYNC, data, &reply); 831b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return reply.readInt32(); 841b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 851b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 861b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber virtual status_t encrypt( 871b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber const void *inData, size_t size, uint32_t streamCTR, 881b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber uint64_t *outInputCTR, void *outData) { 891b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber Parcel data, reply; 901b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); 911b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInt32(size); 921b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.write(inData, size); 931b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.writeInt32(streamCTR); 941b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber remote()->transact(HDCP_ENCRYPT, data, &reply); 951b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 961b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber status_t err = reply.readInt32(); 971b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 981b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (err != OK) { 991b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber *outInputCTR = 0; 1001b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1011b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return err; 1021b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1031b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1041b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber *outInputCTR = reply.readInt64(); 1051b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber reply.read(outData, size); 1061b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1071b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return err; 1081b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1091b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber}; 1101b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1111b19c9d120869c3182373a9b06a1ed98898df882Andreas HuberIMPLEMENT_META_INTERFACE(HDCP, "android.hardware.IHDCP"); 1121b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1131b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberstatus_t BnHDCPObserver::onTransact( 1141b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1151b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber switch (code) { 1161b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber case OBSERVER_NOTIFY: 1171b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber { 1181b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber CHECK_INTERFACE(IHDCPObserver, data, reply); 1191b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1201b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber int msg = data.readInt32(); 1211b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber int ext1 = data.readInt32(); 1221b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber int ext2 = data.readInt32(); 1231b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1241b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber Parcel obj; 1251b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (data.dataAvail() > 0) { 1261b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber obj.appendFrom( 1271b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber const_cast<Parcel *>(&data), 1281b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.dataPosition(), 1291b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.dataAvail()); 1301b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1311b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1321b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber notify(msg, ext1, ext2, &obj); 1331b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1341b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return OK; 1351b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1361b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1371b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber default: 1381b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return BBinder::onTransact(code, data, reply, flags); 1391b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1401b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} 1411b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1421b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberstatus_t BnHDCP::onTransact( 1431b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1441b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber switch (code) { 1451b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber case HDCP_SET_OBSERVER: 1461b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber { 1471b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber CHECK_INTERFACE(IHDCP, data, reply); 1481b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1491b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber sp<IHDCPObserver> observer = 1501b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber interface_cast<IHDCPObserver>(data.readStrongBinder()); 1511b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1521b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber reply->writeInt32(setObserver(observer)); 1531b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return OK; 1541b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1551b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1561b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber case HDCP_INIT_ASYNC: 1571b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber { 1581b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber CHECK_INTERFACE(IHDCP, data, reply); 1591b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1601b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber const char *host = data.readCString(); 1611b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber unsigned port = data.readInt32(); 1621b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1631b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber reply->writeInt32(initAsync(host, port)); 1641b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return OK; 1651b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1661b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1671b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber case HDCP_SHUTDOWN_ASYNC: 1681b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber { 1691b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber CHECK_INTERFACE(IHDCP, data, reply); 1701b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1711b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber reply->writeInt32(shutdownAsync()); 1721b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return OK; 1731b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1741b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1751b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber case HDCP_ENCRYPT: 1761b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber { 1771b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber size_t size = data.readInt32(); 1781b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1791b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber void *inData = malloc(2 * size); 1801b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber void *outData = (uint8_t *)inData + size; 1811b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1821b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber data.read(inData, size); 1831b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1841b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber uint32_t streamCTR = data.readInt32(); 1851b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber uint64_t inputCTR; 1861b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber status_t err = encrypt(inData, size, streamCTR, &inputCTR, outData); 1871b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1881b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber reply->writeInt32(err); 1891b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1901b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (err == OK) { 1911b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber reply->writeInt64(inputCTR); 1921b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber reply->write(outData, size); 1931b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1941b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1951b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber free(inData); 1961b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber inData = outData = NULL; 1971b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1981b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return OK; 1991b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 2001b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 2011b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber default: 2021b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return BBinder::onTransact(code, data, reply, flags); 2031b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 2041b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} 2051b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 2061b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} // namespace android 207