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