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