MediaHTTP.cpp revision 37d8b27e5470d8243288a87e90871efd43f29606
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 } 561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber extHeaders.add(String8("User-Agent"), String8(MakeUserAgent().c_str())); 571b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 581b86fe063badb5f28c467ade39be0f4008688947Andreas Huber bool success = mHTTPConnection->connect(uri, &extHeaders); 591b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 601b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mLastHeaders = extHeaders; 611b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mLastURI = uri; 621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mCachedSizeValid = false; 641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return success ? OK : UNKNOWN_ERROR; 661b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 671b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 681b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid MediaHTTP::disconnect() { 691b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 701b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return; 711b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 721b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 731b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPConnection->disconnect(); 741b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 751b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 761b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstatus_t MediaHTTP::initCheck() const { 771b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mInitCheck; 781b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 791b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 801b86fe063badb5f28c467ade39be0f4008688947Andreas Huberssize_t MediaHTTP::readAt(off64_t offset, void *data, size_t size) { 811b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 821b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mInitCheck; 831b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 841b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 851b86fe063badb5f28c467ade39be0f4008688947Andreas Huber int64_t startTimeUs = ALooper::GetNowUs(); 861b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 871b86fe063badb5f28c467ade39be0f4008688947Andreas Huber size_t numBytesRead = 0; 881b86fe063badb5f28c467ade39be0f4008688947Andreas Huber while (numBytesRead < size) { 891b86fe063badb5f28c467ade39be0f4008688947Andreas Huber size_t copy = size - numBytesRead; 901b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 911b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (copy > 64 * 1024) { 921b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // limit the buffer sizes transferred across binder boundaries 931b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // to avoid spurious transaction failures. 941b86fe063badb5f28c467ade39be0f4008688947Andreas Huber copy = 64 * 1024; 951b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 961b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 971b86fe063badb5f28c467ade39be0f4008688947Andreas Huber ssize_t n = mHTTPConnection->readAt( 981b86fe063badb5f28c467ade39be0f4008688947Andreas Huber offset + numBytesRead, (uint8_t *)data + numBytesRead, copy); 991b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1001b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (n < 0) { 1011b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return n; 1021b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } else if (n == 0) { 1031b86fe063badb5f28c467ade39be0f4008688947Andreas Huber break; 1041b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1051b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1061b86fe063badb5f28c467ade39be0f4008688947Andreas Huber numBytesRead += n; 1071b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1081b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1091b86fe063badb5f28c467ade39be0f4008688947Andreas Huber int64_t delayUs = ALooper::GetNowUs() - startTimeUs; 1101b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1111b86fe063badb5f28c467ade39be0f4008688947Andreas Huber addBandwidthMeasurement(numBytesRead, delayUs); 1121b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1131b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return numBytesRead; 1141b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1151b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1161b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstatus_t MediaHTTP::getSize(off64_t *size) { 1171b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 1181b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mInitCheck; 1191b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1201b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1211b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // Caching the returned size so that it stays valid even after a 1221b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // disconnect. NuCachedSource2 relies on this. 1231b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1241b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (!mCachedSizeValid) { 1251b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mCachedSize = mHTTPConnection->getSize(); 1261b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mCachedSizeValid = true; 1271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1281b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1291b86fe063badb5f28c467ade39be0f4008688947Andreas Huber *size = mCachedSize; 1301b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 131b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe return *size < 0 ? *size : static_cast<status_t>(OK); 1321b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1331b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1341b86fe063badb5f28c467ade39be0f4008688947Andreas Huberuint32_t MediaHTTP::flags() { 1351b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return kWantsPrefetching | kIsHTTPBasedSource; 1361b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1371b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1381b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstatus_t MediaHTTP::reconnectAtOffset(off64_t offset) { 1391b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return connect(mLastURI.c_str(), &mLastHeaders, offset); 1401b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1411b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1421b86fe063badb5f28c467ade39be0f4008688947Andreas Huber// DRM... 1431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1441b86fe063badb5f28c467ade39be0f4008688947Andreas Hubersp<DecryptHandle> MediaHTTP::DrmInitialization(const char* mime) { 1451b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDrmManagerClient == NULL) { 1461b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDrmManagerClient = new DrmManagerClient(); 1471b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1481b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1491b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDrmManagerClient == NULL) { 1501b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return NULL; 1511b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1521b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1531b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDecryptHandle == NULL) { 1541b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDecryptHandle = mDrmManagerClient->openDecryptSession( 1551b86fe063badb5f28c467ade39be0f4008688947Andreas Huber String8(mLastURI.c_str()), mime); 1561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1571b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1581b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDecryptHandle == NULL) { 1591b86fe063badb5f28c467ade39be0f4008688947Andreas Huber delete mDrmManagerClient; 1601b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDrmManagerClient = NULL; 1611b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mDecryptHandle; 1641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1661b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid MediaHTTP::getDrmInfo( 1671b86fe063badb5f28c467ade39be0f4008688947Andreas Huber sp<DecryptHandle> &handle, DrmManagerClient **client) { 1681b86fe063badb5f28c467ade39be0f4008688947Andreas Huber handle = mDecryptHandle; 1691b86fe063badb5f28c467ade39be0f4008688947Andreas Huber *client = mDrmManagerClient; 1701b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1711b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1721b86fe063badb5f28c467ade39be0f4008688947Andreas HuberString8 MediaHTTP::getUri() { 17337d8b27e5470d8243288a87e90871efd43f29606Chong Zhang if (mInitCheck != OK) { 17437d8b27e5470d8243288a87e90871efd43f29606Chong Zhang return String8::empty(); 17537d8b27e5470d8243288a87e90871efd43f29606Chong Zhang } 17637d8b27e5470d8243288a87e90871efd43f29606Chong Zhang 177c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen String8 uri; 178c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen if (OK == mHTTPConnection->getUri(&uri)) { 179c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen return uri; 180c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen } 1811b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return String8(mLastURI.c_str()); 1821b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1831b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1841b86fe063badb5f28c467ade39be0f4008688947Andreas HuberString8 MediaHTTP::getMIMEType() const { 1851b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mInitCheck != OK) { 1861b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return String8("application/octet-stream"); 1871b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1881b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1891b86fe063badb5f28c467ade39be0f4008688947Andreas Huber String8 mimeType; 1901b86fe063badb5f28c467ade39be0f4008688947Andreas Huber status_t err = mHTTPConnection->getMIMEType(&mimeType); 1911b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1921b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (err != OK) { 1931b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return String8("application/octet-stream"); 1941b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 1951b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1961b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mimeType; 1971b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 1981b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 1991b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid MediaHTTP::clearDRMState_l() { 2001b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (mDecryptHandle != NULL) { 2011b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // To release mDecryptHandle 2021b86fe063badb5f28c467ade39be0f4008688947Andreas Huber CHECK(mDrmManagerClient); 2031b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDrmManagerClient->closeDecryptSession(mDecryptHandle); 2041b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mDecryptHandle = NULL; 2051b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 2061b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} 2071b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 2081b86fe063badb5f28c467ade39be0f4008688947Andreas Huber} // namespace android 209