11b86fe063badb5f28c467ade39be0f4008688947Andreas Huber/* 21b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * Copyright (C) 2013 The Android Open Source Project 31b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * 41b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 51b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * you may not use this file except in compliance with the License. 61b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * You may obtain a copy of the License at 71b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * 81b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 91b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * 101b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * Unless required by applicable law or agreed to in writing, software 111b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 121b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * See the License for the specific language governing permissions and 141b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * limitations under the License. 151b86fe063badb5f28c467ade39be0f4008688947Andreas Huber */ 161b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 171b86fe063badb5f28c467ade39be0f4008688947Andreas Huber//#define LOG_NDEBUG 0 181b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#define LOG_TAG "MediaHTTP" 191b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <utils/Log.h> 201b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 211b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/MediaHTTP.h> 221b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 231b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <binder/IServiceManager.h> 241b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/foundation/ADebug.h> 251b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/foundation/ALooper.h> 261b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/Utils.h> 271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 281b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPConnection.h> 291b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 301b86fe063badb5f28c467ade39be0f4008688947Andreas Hubernamespace android { 311b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 321b86fe063badb5f28c467ade39be0f4008688947Andreas HuberMediaHTTP::MediaHTTP(const sp<IMediaHTTPConnection> &conn) 3337d8b27e5470d8243288a87e90871efd43f29606Chong Zhang : mInitCheck((conn != NULL) ? OK : NO_INIT), 341b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPConnection(conn), 351b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mCachedSizeValid(false), 361b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mCachedSize(0ll), 371b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDrmManagerClient(NULL) { 381b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 391b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 401b86fe063badb5f28c467ade39be0f4008688947Andreas HuberMediaHTTP::~MediaHTTP() { 411b86fe063badb5f28c467ade39be0f4008688947Andreas Huber clearDRMState_l(); 421b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 441b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstatus_t MediaHTTP::connect( 451b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const char *uri, 461b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const KeyedVector<String8, String8> *headers, 471b86fe063badb5f28c467ade39be0f4008688947Andreas Huber off64_t /* offset */) { 481b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 491b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mInitCheck; 501b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 511b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 521b86fe063badb5f28c467ade39be0f4008688947Andreas Huber KeyedVector<String8, String8> extHeaders; 531b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (headers != NULL) { 541b86fe063badb5f28c467ade39be0f4008688947Andreas Huber extHeaders = *headers; 551b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 564136329b28f5b301cb9123009a3635a9db4a0a04Marco Nelissen 574136329b28f5b301cb9123009a3635a9db4a0a04Marco Nelissen if (extHeaders.indexOfKey(String8("User-Agent")) < 0) { 584136329b28f5b301cb9123009a3635a9db4a0a04Marco Nelissen extHeaders.add(String8("User-Agent"), String8(MakeUserAgent().c_str())); 594136329b28f5b301cb9123009a3635a9db4a0a04Marco Nelissen } 601b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 611b86fe063badb5f28c467ade39be0f4008688947Andreas Huber bool success = mHTTPConnection->connect(uri, &extHeaders); 621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mLastHeaders = extHeaders; 641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mLastURI = uri; 651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 661b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mCachedSizeValid = false; 671b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 681b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return success ? OK : UNKNOWN_ERROR; 691b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 701b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 711b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid MediaHTTP::disconnect() { 721b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 731b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return; 741b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 751b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 761b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPConnection->disconnect(); 771b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 781b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 791b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstatus_t MediaHTTP::initCheck() const { 801b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mInitCheck; 811b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 821b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 831b86fe063badb5f28c467ade39be0f4008688947Andreas Huberssize_t MediaHTTP::readAt(off64_t offset, void *data, size_t size) { 841b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 851b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mInitCheck; 861b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 871b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 881b86fe063badb5f28c467ade39be0f4008688947Andreas Huber int64_t startTimeUs = ALooper::GetNowUs(); 891b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 901b86fe063badb5f28c467ade39be0f4008688947Andreas Huber size_t numBytesRead = 0; 911b86fe063badb5f28c467ade39be0f4008688947Andreas Huber while (numBytesRead < size) { 921b86fe063badb5f28c467ade39be0f4008688947Andreas Huber size_t copy = size - numBytesRead; 931b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 941b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (copy > 64 * 1024) { 951b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // limit the buffer sizes transferred across binder boundaries 961b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // to avoid spurious transaction failures. 971b86fe063badb5f28c467ade39be0f4008688947Andreas Huber copy = 64 * 1024; 981b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 991b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1001b86fe063badb5f28c467ade39be0f4008688947Andreas Huber ssize_t n = mHTTPConnection->readAt( 1011b86fe063badb5f28c467ade39be0f4008688947Andreas Huber offset + numBytesRead, (uint8_t *)data + numBytesRead, copy); 1021b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1031b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (n < 0) { 1041b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return n; 1051b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } else if (n == 0) { 1061b86fe063badb5f28c467ade39be0f4008688947Andreas Huber break; 1071b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1081b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1091b86fe063badb5f28c467ade39be0f4008688947Andreas Huber numBytesRead += n; 1101b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1111b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1121b86fe063badb5f28c467ade39be0f4008688947Andreas Huber int64_t delayUs = ALooper::GetNowUs() - startTimeUs; 1131b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1141b86fe063badb5f28c467ade39be0f4008688947Andreas Huber addBandwidthMeasurement(numBytesRead, delayUs); 1151b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1161b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return numBytesRead; 1171b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1181b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1191b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstatus_t MediaHTTP::getSize(off64_t *size) { 1201b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 1211b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mInitCheck; 1221b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1231b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1241b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // Caching the returned size so that it stays valid even after a 1251b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // disconnect. NuCachedSource2 relies on this. 1261b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (!mCachedSizeValid) { 1281b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mCachedSize = mHTTPConnection->getSize(); 1291b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mCachedSizeValid = true; 1301b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1311b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1321b86fe063badb5f28c467ade39be0f4008688947Andreas Huber *size = mCachedSize; 1331b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 134b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe return *size < 0 ? *size : static_cast<status_t>(OK); 1351b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1361b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1371b86fe063badb5f28c467ade39be0f4008688947Andreas Huberuint32_t MediaHTTP::flags() { 1381b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return kWantsPrefetching | kIsHTTPBasedSource; 1391b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1401b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1411b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstatus_t MediaHTTP::reconnectAtOffset(off64_t offset) { 1421b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return connect(mLastURI.c_str(), &mLastHeaders, offset); 1431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1441b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1451b86fe063badb5f28c467ade39be0f4008688947Andreas Huber// DRM... 1461b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1471b86fe063badb5f28c467ade39be0f4008688947Andreas Hubersp<DecryptHandle> MediaHTTP::DrmInitialization(const char* mime) { 1481b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDrmManagerClient == NULL) { 1491b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDrmManagerClient = new DrmManagerClient(); 1501b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1511b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1521b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDrmManagerClient == NULL) { 1531b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return NULL; 1541b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1551b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDecryptHandle == NULL) { 1571b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDecryptHandle = mDrmManagerClient->openDecryptSession( 1581b86fe063badb5f28c467ade39be0f4008688947Andreas Huber String8(mLastURI.c_str()), mime); 1591b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1601b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1611b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDecryptHandle == NULL) { 1621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber delete mDrmManagerClient; 1631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDrmManagerClient = NULL; 1641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1661b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mDecryptHandle; 1671b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1681b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1691b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid MediaHTTP::getDrmInfo( 1701b86fe063badb5f28c467ade39be0f4008688947Andreas Huber sp<DecryptHandle> &handle, DrmManagerClient **client) { 1711b86fe063badb5f28c467ade39be0f4008688947Andreas Huber handle = mDecryptHandle; 1721b86fe063badb5f28c467ade39be0f4008688947Andreas Huber *client = mDrmManagerClient; 1731b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1741b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1751b86fe063badb5f28c467ade39be0f4008688947Andreas HuberString8 MediaHTTP::getUri() { 17637d8b27e5470d8243288a87e90871efd43f29606Chong Zhang if (mInitCheck != OK) { 17737d8b27e5470d8243288a87e90871efd43f29606Chong Zhang return String8::empty(); 17837d8b27e5470d8243288a87e90871efd43f29606Chong Zhang } 17937d8b27e5470d8243288a87e90871efd43f29606Chong Zhang 180c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen String8 uri; 181c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen if (OK == mHTTPConnection->getUri(&uri)) { 182c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen return uri; 183c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen } 1841b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return String8(mLastURI.c_str()); 1851b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1861b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1871b86fe063badb5f28c467ade39be0f4008688947Andreas HuberString8 MediaHTTP::getMIMEType() const { 1881b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 1891b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return String8("application/octet-stream"); 1901b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1911b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1921b86fe063badb5f28c467ade39be0f4008688947Andreas Huber String8 mimeType; 1931b86fe063badb5f28c467ade39be0f4008688947Andreas Huber status_t err = mHTTPConnection->getMIMEType(&mimeType); 1941b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1951b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (err != OK) { 1961b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return String8("application/octet-stream"); 1971b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1981b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1991b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mimeType; 2001b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 2011b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 2021b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid MediaHTTP::clearDRMState_l() { 2031b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDecryptHandle != NULL) { 2041b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // To release mDecryptHandle 2051b86fe063badb5f28c467ade39be0f4008688947Andreas Huber CHECK(mDrmManagerClient); 2061b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDrmManagerClient->closeDecryptSession(mDecryptHandle); 2071b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDecryptHandle = NULL; 2081b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 2091b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 2101b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 2111b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} // namespace android 212